From 423c5d07bd477adc5248fe2f2e36d8b2fc26edaf Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Wed, 13 Mar 2019 08:22:08 +0100 Subject: [PATCH] Initial Commit --- .gitignore | 41 +++++++ CIDR.cs | 207 +++++++++++++++++++++++++++++++++ Properties/AssemblyInfo.cs | 35 ++++++ ln.types.csproj | 58 ++++++++++ odb/IPersistent.cs | 17 +++ odb/ODB.cs | 50 ++++++++ odb/Persistent.cs | 27 +++++ serialize/DiskObject.cs | 68 +++++++++++ serialize/ObjectReader.cs | 197 ++++++++++++++++++++++++++++++++ serialize/ObjectWriter.cs | 226 +++++++++++++++++++++++++++++++++++++ sync/Syncable.cs | 125 ++++++++++++++++++++ 11 files changed, 1051 insertions(+) create mode 100644 .gitignore create mode 100644 CIDR.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 ln.types.csproj create mode 100644 odb/IPersistent.cs create mode 100644 odb/ODB.cs create mode 100644 odb/Persistent.cs create mode 100644 serialize/DiskObject.cs create mode 100644 serialize/ObjectReader.cs create mode 100644 serialize/ObjectWriter.cs create mode 100644 sync/Syncable.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf793ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Autosave files +*~ + +# build +[Oo]bj/ +[Bb]in/ +packages/ +TestResults/ + +# globs +Makefile.in +*.DS_Store +*.sln.cache +*.suo +*.cache +*.pidb +*.userprefs +*.usertasks +config.log +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.user +*.tar.gz +tarballs/ +test-results/ +Thumbs.db +.vs/ + +# Mac bundle stuff +*.dmg +*.app + +# resharper +*_Resharper.* +*.Resharper + +# dotCover +*.dotCover diff --git a/CIDR.cs b/CIDR.cs new file mode 100644 index 0000000..beaa81a --- /dev/null +++ b/CIDR.cs @@ -0,0 +1,207 @@ +// /** +// * File: CIDR.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.Net; +using System.Linq; +using System.Collections.Generic; +using System.Collections; + +namespace ln.types +{ + public class CIDR : IEnumerable + { + public static CIDR Parse(String source) + { + string[] toks = source.Split('/'); + IPAddress ip = IPAddress.Parse(toks[0]); + if (toks.Length == 2) + { + if (toks[1].IndexOf('.') != -1) + { + IPAddress mask = IPAddress.Parse(toks[1]); + return new CIDR(ip, mask); + } + else + { + uint w = uint.Parse(toks[1]); + return new CIDR(ip, w); + } + } + return new CIDR(ip); + } + + private readonly uint _ip; + private readonly uint _netmask; + + public int MaskWidth => (int)getNetWidth(_netmask); + public CIDR Network => new CIDR(_ip & _netmask, _netmask); + + public byte[] IPBytes + { + get => BitConverter.GetBytes(_ip).Reverse().ToArray(); + //set => _ip = BitConverter.ToUInt32(value.Reverse().ToArray(), 0); + } + + public byte[] MaskBytes + { + get => BitConverter.GetBytes(_netmask).Reverse().ToArray(); + //set => _netmask = BitConverter.ToUInt32(value.Reverse().ToArray(), 0); + } + + public CIDR() + { + } + + public CIDR(uint ip, uint netmask) + { + this._ip = ip; + this._netmask = netmask; + } + + public CIDR(CIDR ip) + { + this._ip = ip._ip; + this._netmask = 0xFFFFFFFF; + } + + public CIDR(CIDR ip, uint maskwidth) + { + this._ip = ip._ip; + this._netmask = maskFromWidth(maskwidth); + } + + public CIDR(IPAddress ip, uint maskwidth) + { + _ip = BitConverter.ToUInt32(ip.GetAddressBytes().Reverse().ToArray(), 0); + _netmask = maskFromWidth(maskwidth); + } + + public CIDR(IPAddress ip, IPAddress mask) + { + _ip = BitConverter.ToUInt32(ip.GetAddressBytes().Reverse().ToArray(), 0); + _netmask = BitConverter.ToUInt32(mask.GetAddressBytes().Reverse().ToArray(), 0); + getNetWidth(_netmask); + } + + private uint maskFromWidth(uint value) + { + uint nm = 0; + if (value == 0) + nm = 0; + else if (value == 32) + nm = 0xFFFFFFFF; + else + { + nm = 0xFFFFFFFF; + nm <<= (int)(32 - value); + } + return nm; + } + + private uint getNetWidth(uint nm) + { + uint w = 0; + + for (w = 32; w > 0; w--) + { + if ((nm & (1 << (int)(32-w))) != 0) + break; + } + for (uint n = w; n > 0; n--) + { + if ((nm & (1 << (int)(32-n))) == 0) + throw new FormatException("Netmask with holes"); + } + + return w; + } + + + public override string ToString() + { + if (_netmask == 0xFFFFFFFF) + return String.Format("{0}", String.Join(".", IPBytes.Select((x) => x.ToString()))); + else + return String.Format("{0}/{1}", String.Join(".", IPBytes.Select((x) => x.ToString())),getNetWidth(_netmask)); + } + + public static implicit operator IPAddress(CIDR cidr) + { + return new IPAddress(cidr._ip); + } + public static implicit operator CIDR(IPAddress iPAddress) + { + return new CIDR(iPAddress); + } + + public bool Contains(CIDR you) + { + return (you.MaskWidth >= MaskWidth) && ((you._ip & _netmask)==(_ip & _netmask)); + } + + public override int GetHashCode() + { + return (int)(_ip ^ _netmask); + } + public override bool Equals(object obj) + { + if (obj is IPAddress) + obj = (CIDR)(obj as IPAddress); + + if (obj is CIDR) + { + CIDR you = obj as CIDR; + return (you._ip == _ip) && (you._netmask == _netmask); + } + return false; + } + + public IEnumerator GetEnumerator() + { + return new CIDREnumerator(this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + class CIDREnumerator : IEnumerator + { + CIDR network; + CIDR curCIDR; + + public CIDR Current => curCIDR; + object IEnumerator.Current => curCIDR; + + public CIDREnumerator(CIDR network) + { + this.network = network.Network; + Reset(); + } + + public void Dispose() + { + } + + public bool MoveNext() + { + curCIDR = new CIDR(curCIDR._ip + 1, 0xFFFFFFFF); + return network.Contains(curCIDR); + } + + public void Reset() + { + curCIDR = network; + } + } + + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4f495be --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +// /** +// * File: AssemblyInfo.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.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("ln.types")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("${AuthorCopyright}")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] diff --git a/ln.types.csproj b/ln.types.csproj new file mode 100644 index 0000000..292e4b2 --- /dev/null +++ b/ln.types.csproj @@ -0,0 +1,58 @@ + + + + Debug + AnyCPU + {8D9AB9A5-E513-4BA7-A450-534F6456BF28} + Library + ln.types + ln.types + v4.7 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + {D471A566-9FB6-41B2-A777-3C32874ECD0E} + ln.logging + + + + \ No newline at end of file diff --git a/odb/IPersistent.cs b/odb/IPersistent.cs new file mode 100644 index 0000000..00605e7 --- /dev/null +++ b/odb/IPersistent.cs @@ -0,0 +1,17 @@ +// /** +// * File: IPersistent.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; +namespace ln.types.odb +{ + public interface IPersistent + { + Guid GetPersistenceID(); + } +} diff --git a/odb/ODB.cs b/odb/ODB.cs new file mode 100644 index 0000000..0494e1b --- /dev/null +++ b/odb/ODB.cs @@ -0,0 +1,50 @@ +// /** +// * File: ODB.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.IO; +using System.Collections.Generic; +namespace ln.types.odb +{ + public class ODB + { + public String BasePath { get; set; } + + + + Dictionary> persistentObjects = new Dictionary>(); + + public ODB() + { + BasePath = Path.GetFullPath("./crawler"); + if (!Directory.Exists(BasePath)) + { + Directory.CreateDirectory(BasePath); + } + } + + public IPersistent GetPersistent(Guid persistenceID) + { + if (persistentObjects.ContainsKey(persistenceID)) + { + WeakReference weakRef = persistentObjects[persistenceID]; + IPersistent o = null; + + if (weakRef.TryGetTarget(out o)) + return o; + } + return null; + } + + + + + + } +} diff --git a/odb/Persistent.cs b/odb/Persistent.cs new file mode 100644 index 0000000..ef31728 --- /dev/null +++ b/odb/Persistent.cs @@ -0,0 +1,27 @@ +// /** +// * File: Persistent.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; +namespace ln.types.odb +{ + public class Persistent : IPersistent + { + public Guid PersistenceID { get; private set; } + + public Persistent() + { + PersistenceID = Guid.NewGuid(); + } + + public Guid GetPersistenceID() + { + return PersistenceID; + } + } +} diff --git a/serialize/DiskObject.cs b/serialize/DiskObject.cs new file mode 100644 index 0000000..a90fa9c --- /dev/null +++ b/serialize/DiskObject.cs @@ -0,0 +1,68 @@ +// /** +// * File: DiskObject.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.IO; +namespace ln.types.serialize +{ + public class DiskObject + { + public String FileName { get; private set; } + + public T Instance { get; set; } + + public DiskObject(string fileName) + { + FileName = fileName; + Load(); + } + public DiskObject(string fileName,T instance) + :this(fileName) + { + Instance = instance; + } + + public void Load() + { + if (File.Exists(FileName)) + { + using (FileStream fileStream = new FileStream(FileName, FileMode.Open)) + { + ObjectReader objectReader = new ObjectReader(fileStream); + Instance = (T)objectReader.Read(); + fileStream.Close(); + } + } + else + { + Instance = Activator.CreateInstance(); + } + } + public void Save() + { + lock (this) + { + String tmpFileName = string.Format("{0}.tmp", FileName); + + using (FileStream fileStream = new FileStream(tmpFileName, FileMode.OpenOrCreate, FileAccess.Write)) + { + ObjectWriter objectWriter = new ObjectWriter(fileStream); + objectWriter.Write(Instance); + fileStream.Close(); + } + + if (!File.Exists(FileName)) + File.Move(tmpFileName, FileName); + else + File.Replace(tmpFileName, FileName, FileName + ".old"); + } + } + + } +} diff --git a/serialize/ObjectReader.cs b/serialize/ObjectReader.cs new file mode 100644 index 0000000..0a7ff21 --- /dev/null +++ b/serialize/ObjectReader.cs @@ -0,0 +1,197 @@ +// /** +// * File: ObjectReader.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.IO; +using System.Reflection; +using System.Text; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Linq; +namespace ln.types.serialize +{ + public class ObjectReader : IDisposable + { + public Stream Stream { get; } + + public object[] ReferencedObjects + { + get => referencedObjects.ToArray(); + set => referencedObjects = new List(value); + } + + List referencedObjects = new List(); + + public ObjectReader(Stream stream) + { + Stream = stream; + } + public ObjectReader(String fileName) + { + Stream = new FileStream(fileName,FileMode.Open); + } + + public virtual object QueryReferencedObject(object re) + { + return referencedObjects[(int)re]; + } + + public object Read() + { + byte[] b; + + char ch = (char)Stream.ReadByte(); + switch (ch) + { + case 'N': + return null; + case 'O': + return ReadObject(); + case 'o': + return QueryReferencedObject(Read()); + case 's': + return ReadString(); + case '8': + return (byte)Stream.ReadByte(); + case '2': + b = new byte[2]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToInt16(b, 0); + case '4': + b = new byte[4]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToInt32(b, 0); + case 'L': + b = new byte[8]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToInt64(b, 0); + case '3': + b = new byte[2]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToUInt16(b, 0); + case '5': + b = new byte[4]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToUInt32(b, 0); + case 'l': + b = new byte[8]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToUInt64(b, 0); + case 'f': + b = new byte[4]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToSingle(b, 0); + case 'd': + b = new byte[8]; + Stream.Read(b, 0, b.Length); + return BitConverter.ToDouble(b, 0); + case 'B': + return true; + case 'b': + return false; + case 'S': + return ReadStruct(); + case 'A': + return ReadArray(); + default: + throw new NotImplementedException(String.Format("Identifier {0} (0x{1:x8})",ch,(int)ch)); + } + } + + public Array ReadArray() + { + List items = new List(); + string assemblyName = Read() as string; + String typeName = Read() as string; + int length = (int)Read(); + + Type eType = Assembly.Load(assemblyName).GetType(typeName); + + Array array = Array.CreateInstance(eType, length); + + for (int n = 0; n < length; n++) + array.SetValue(Read(), n); + + return array; + } + + public object ReadObject() + { + String assemblyName = Read() as string; + String typeName = Read() as string; + + + object o = Activator.CreateInstance(assemblyName, typeName).Unwrap(); + Type type = o.GetType(); + + referencedObjects.Add(o); + + ReadFields(o); + + return o; + } + + public void ReadThis(object o) + { + Stream.ReadByte(); + String assemblyName = Read() as string; + String typeName = Read() as string; + ReadFields(o); + } + + private void ReadFields(object o) + { + Type type = o.GetType(); + int nFields = (int)Read(); + + for (int n = 0; n < nFields; n++) + { + string fieldName = Read() as string; + object value = Read(); + + FieldInfo fieldInfo = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + fieldInfo.SetValue(o, value); + } + } + + public object ReadStruct() + { + String assemblyName = Read() as string; + String typeName = Read() as string; + int nFields = (int)Read(); + + object o = Activator.CreateInstance(assemblyName, typeName).Unwrap(); + Type type = o.GetType(); + + for (int n = 0; n < nFields; n++) + { + string fieldName = Read() as string; + object value = Read(); + + FieldInfo fieldInfo = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + fieldInfo.SetValue(o, value); + } + + return o; + } + private string ReadString() + { + int length = (int)Read(); + byte[] buffer = new byte[length]; + Stream.Read(buffer, 0, length); + return Encoding.UTF8.GetString(buffer); + } + + public void Dispose() + { + Stream.Close(); + Stream.Dispose(); + } + } +} diff --git a/serialize/ObjectWriter.cs b/serialize/ObjectWriter.cs new file mode 100644 index 0000000..22e8dd2 --- /dev/null +++ b/serialize/ObjectWriter.cs @@ -0,0 +1,226 @@ +// /** +// * File: ObjectWriter.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.IO; +using System.Text; +using System.Reflection; +using System.Linq; +using System.Collections.Generic; +using ln.types.sync; +namespace ln.types.serialize +{ + /** + * Types + * + * N null + * b "false" + * B "true" + * 8 byte + * 2 short + * 4 int + * L long + * f float + * d double + * s string + * 3 ushort + * 5 uint + * l ulong + * S struct + * A Array + * + **/ + + public class ObjectWriter + { + public Stream Stream { get; } + + public object[] ReferencedObjects + { + get => referencedObjects.ToArray(); + set => referencedObjects = new List(value); + } + + List referencedObjects = new List(); + + public ObjectWriter(Stream stream) + { + Stream = stream; + } + + private void WriteByte(char ch) + { + Stream.WriteByte((byte)ch); + } + + public virtual object QueryReference(object o) + { + if (referencedObjects.Contains(o)) + return referencedObjects.IndexOf(o); + + referencedObjects.Add(o); + + return o; + } + + public void Write(object o) + { + if (o == null) + { + WriteByte('N'); + } + else + { + Type type = o.GetType(); + if (type.IsValueType || typeof(string).Equals(type)) + { + WriteValue(o); + } + else if (type.IsArray) + { + WriteArray(o as Array); + } + else + { + WriteObject(o); + } + } + } + + private void WriteArray(Array a) + { + int length = a.Length; + Type eType = a.GetType().GetElementType(); + + WriteByte('A'); + WriteValue(eType.Assembly.FullName); + Write(eType.FullName); + WriteValue(length); + + for (int n = 0; n < length; n++) + Write(a.GetValue(n)); + } + + private void WriteObject(object _o) + { + object o = QueryReference(_o); + + if (o == _o) + { + Type type = o.GetType(); + FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where((x) => !x.IsNotSerialized).ToArray(); + + WriteByte('O'); + WriteValue(type.Assembly.FullName); + WriteValue(type.FullName); + WriteValue((int)fieldInfos.Length); + + foreach (FieldInfo fieldInfo in fieldInfos) + { + if (fieldInfo.GetCustomAttribute() != null) + { + WriteValue(fieldInfo.Name); + WriteByte('N'); + } + else + { + WriteValue(fieldInfo.Name); + Write(fieldInfo.GetValue(o)); + } + } + } + else + { + WriteByte('o'); + Write(o); + } + + } + private void WriteValue(object value) + { + Type type = value.GetType(); + + if (typeof(String).Equals(type)) + { + WriteByte('s'); + byte[] buffer = Encoding.UTF8.GetBytes(value as string); + WriteValue(buffer.Length); + Stream.Write(buffer, 0, buffer.Length); + } else if (!type.IsPrimitive) + { + FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where((x)=>!x.DeclaringType.Equals(typeof(object))).ToArray(); + + WriteByte('S'); + WriteValue(type.Assembly.FullName); + WriteValue(type.FullName); + WriteValue(fieldInfos.Length); + + foreach (FieldInfo fieldInfo in fieldInfos) + { + WriteValue(fieldInfo.Name); + Write(fieldInfo.GetValue(value)); + } + } + else if (typeof(Boolean).Equals(type)) + { + WriteByte((bool)value ? 'B' : 'b'); + } + else if (typeof(byte).Equals(type)) + { + WriteByte('8'); + Stream.WriteByte((byte)value); + } + else if (typeof(short).Equals(type)) + { + WriteByte('2'); + Stream.Write(BitConverter.GetBytes((short)value),0,2); + } + else if (typeof(int).Equals(type)) + { + WriteByte('4'); + Stream.Write(BitConverter.GetBytes((int)value), 0, 4); + } + else if (typeof(long).Equals(type)) + { + WriteByte('L'); + Stream.Write(BitConverter.GetBytes((long)value), 0, 8); + } + else if (typeof(float).Equals(type)) + { + WriteByte('f'); + Stream.Write(BitConverter.GetBytes((float)value), 0, 4); + } + else if (typeof(double).Equals(type)) + { + WriteByte('d'); + Stream.Write(BitConverter.GetBytes((double)value), 0, 8); + } + else if (typeof(ushort).Equals(type)) + { + WriteByte('3'); + Stream.Write(BitConverter.GetBytes((ushort)value), 0, 2); + } + else if (typeof(uint).Equals(type)) + { + WriteByte('5'); + Stream.Write(BitConverter.GetBytes((uint)value), 0, 4); + } + else if (typeof(ulong).Equals(type)) + { + WriteByte('l'); + Stream.Write(BitConverter.GetBytes((ulong)value), 0, 8); + } + else + { + throw new NotImplementedException(); + } + } + + } +} diff --git a/sync/Syncable.cs b/sync/Syncable.cs new file mode 100644 index 0000000..7f8b10f --- /dev/null +++ b/sync/Syncable.cs @@ -0,0 +1,125 @@ +// /** +// * File: Syncable.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.IO; +using System.Collections.Generic; +using ln.logging; +using System.Runtime.Serialization; +using System.Xml.Serialization; +using System.Reflection; +using System.Text; +using ln.types.serialize; +namespace ln.types.sync +{ + public class Synced : Attribute + { + } + + public class Unsynced : Attribute + { + } + + public abstract class Syncable + { + public String FileName { get; set; } + + public Syncable() + { + } + public Syncable(string fileName) + { + FileName = fileName; + Load(); + } + + public void Load() + { + using (ObjectReader objectReader = new ObjectReader(FileName)) + { + objectReader.ReadThis(this); + } + } + + public void Sync() + { + using (FileStream fileStream = new FileStream(FileName, FileMode.OpenOrCreate)) + { + ObjectWriter objectWriter = new ObjectWriter(fileStream); + objectWriter.Write(this); + fileStream.Close(); + } + } + + public virtual void Restore(Dictionary keyValues) + { + if (keyValues.ContainsKey("sync.timestamp")) + Logging.Log(LogLevel.DEBUG, "Syncable restoring from state of {0}",keyValues["sync.timestamp"]); + + + foreach (FieldInfo fieldInfo in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) + { + if (fieldInfo.GetCustomAttribute() != null) + { + string key = String.Format("field.{0}", fieldInfo.Name); + if (keyValues.ContainsKey(key)) + { + fieldInfo.SetValue(this,keyValues[key]); + } + } + } + + } + public virtual void Collect(Dictionary keyValues) + { + keyValues["sync.timestamp"] = DateTime.Now; + Logging.Log(LogLevel.DEBUG, "Syncable: collectiong state at {0}", keyValues["sync.timestamp"]); + + foreach (FieldInfo fieldInfo in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) + { + if (fieldInfo.GetCustomAttribute() != null) + { + string key = String.Format("field.{0}", fieldInfo.Name); + object value = fieldInfo.GetValue(this); + + keyValues.Add(key, value); + } + } + + } + + private byte[] Serialize(object o) + { + if (o == null) + return new byte[0]; + + XmlSerializer xmlSerializer = new XmlSerializer(o.GetType()); + MemoryStream memoryStream = new MemoryStream(); + xmlSerializer.Serialize(memoryStream, o); + byte[] result = memoryStream.ToArray(); + + Logging.Log(LogLevel.DEBUG, "Serialized: {0}",Encoding.UTF8.GetString(result)); + + return result; + } + + private object Unserialize(byte[] buffer,Type type) + { + if ((type == null) || (buffer.Length == 0)) + return null; + + MemoryStream memoryStream = new MemoryStream(buffer); + XmlSerializer xmlSerializer = new XmlSerializer(type); + + return xmlSerializer.Deserialize(memoryStream); + } + + + } +}