184 lines
5.8 KiB
C#
184 lines
5.8 KiB
C#
// /**
|
|
// * File: PreparedObject.cs
|
|
// * Author: haraldwolff
|
|
// *
|
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
|
// *
|
|
// *
|
|
// **/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.CodeDom;
|
|
using System.Reflection;
|
|
using System.IO;
|
|
using System.Linq;
|
|
namespace ln.types.odb
|
|
{
|
|
public class PreparedObject
|
|
{
|
|
public ODB ODB { get; private set; }
|
|
|
|
public DateTime Timestamp { get; private set; }
|
|
public Type PreparedType { get; private set; }
|
|
|
|
public IPersistent Instance { get; set; }
|
|
public Guid PersistenceID { get; private set; }
|
|
|
|
public string[] StoredFieldNames => fieldStore.Keys.ToArray();
|
|
|
|
public IEnumerable<Guid> ReferencedPersistentIDs => referencedPersistentIDs;
|
|
public IEnumerable<IPersistent> ReferencedPersistents => referencedPersistents;
|
|
|
|
List<Guid> referencedPersistentIDs = new List<Guid>();
|
|
HashSet<IPersistent> referencedPersistents = new HashSet<IPersistent>();
|
|
Dictionary<string, byte[]> fieldStore = new Dictionary<string, byte[]>();
|
|
|
|
public PreparedObject(ODB odb,Type preparedType,Guid persistenceID)
|
|
{
|
|
ODB = odb;
|
|
Timestamp = DateTime.Now;
|
|
PreparedType = preparedType;
|
|
PersistenceID = persistenceID;
|
|
Instance = null;
|
|
}
|
|
public PreparedObject(ODB odb, IPersistent o)
|
|
{
|
|
ODB = odb;
|
|
Timestamp = DateTime.Now;
|
|
PreparedType = o.GetType();
|
|
PersistenceID = o.GetPersistenceID();
|
|
Instance = o;
|
|
|
|
SyncFromInstance();
|
|
}
|
|
|
|
private IEnumerable<FieldInfo> GetAllFields(Type type)
|
|
{
|
|
if (type == typeof(object))
|
|
{
|
|
return new FieldInfo[0];
|
|
}
|
|
else
|
|
{
|
|
return GetAllFields(type.BaseType).Concat(type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly));
|
|
}
|
|
}
|
|
|
|
private void SyncFromInstance()
|
|
{
|
|
referencedPersistentIDs.Clear();
|
|
FieldInfo[] fields = GetAllFields(PreparedType).ToArray();
|
|
|
|
foreach (FieldInfo fieldInfo in fields)
|
|
{
|
|
if (!fieldInfo.IsStatic)
|
|
{
|
|
object value = fieldInfo.GetValue(Instance);
|
|
if (value == null)
|
|
{
|
|
fieldStore[fieldInfo.Name] = new byte[0];
|
|
}
|
|
else
|
|
{
|
|
MemoryStream objectStream = new MemoryStream();
|
|
ODBObjectWriter objectWriter = new ODBObjectWriter(objectStream);
|
|
|
|
objectWriter.Write(value);
|
|
|
|
fieldStore[fieldInfo.Name] = objectStream.ToArray();
|
|
referencedPersistentIDs.AddRange(objectWriter.ReferencedPersistentIDs);
|
|
foreach (IPersistent persistent in objectWriter.ReferencedPersistents)
|
|
referencedPersistents.Add(persistent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private void SyncToInstance()
|
|
{
|
|
foreach (FieldInfo fieldInfo in GetAllFields(PreparedType))
|
|
{
|
|
if (!fieldInfo.IsStatic)
|
|
{
|
|
byte[] bytes = fieldStore[fieldInfo.Name];
|
|
if (bytes.Length == 0)
|
|
{
|
|
fieldInfo.SetValue(Instance, null);
|
|
}
|
|
else
|
|
{
|
|
MemoryStream objectStream = new MemoryStream(fieldStore[fieldInfo.Name]);
|
|
ODBObjectReader objectReader = new ODBObjectReader(ODB, objectStream);
|
|
|
|
object value = objectReader.Read();
|
|
fieldInfo.SetValue(Instance, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ReConfigure(Type targetType,DateTime timestamp)
|
|
{
|
|
Timestamp = timestamp;
|
|
PreparedType = targetType;
|
|
fieldStore.Clear();
|
|
Instance = null;
|
|
}
|
|
|
|
public byte[] GetFieldBytes(string fieldName)
|
|
{
|
|
return fieldStore[fieldName];
|
|
}
|
|
public void SetFieldBytes(string fieldName,byte[] bytes)
|
|
{
|
|
fieldStore[fieldName] = bytes;
|
|
}
|
|
|
|
public IPersistent CreateInstance()
|
|
{
|
|
Instance = (IPersistent)Activator.CreateInstance(PreparedType,true);
|
|
SyncToInstance();
|
|
return Instance;
|
|
}
|
|
|
|
public bool InstanceEquals(PreparedObject other)
|
|
{
|
|
if (other == null)
|
|
return false;
|
|
|
|
if (Equals(other))
|
|
{
|
|
foreach (String fieldName in fieldStore.Keys)
|
|
{
|
|
byte[] me = fieldStore[fieldName];
|
|
byte[] you = other.fieldStore[fieldName];
|
|
|
|
File.WriteAllBytes("me.bin", me);
|
|
File.WriteAllBytes("you.bin", you);
|
|
|
|
if (!me.AreEqual(you))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return PersistenceID.GetHashCode() ^ PreparedType.GetHashCode();
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is PreparedObject)
|
|
{
|
|
PreparedObject you = obj as PreparedObject;
|
|
return PreparedType.Equals(you.PreparedType) && PersistenceID.Equals(you.PersistenceID);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|
|
}
|