Permalink
Browse files

Initial commit

  • Loading branch information...
1 parent 2247f6f commit 9b8766ddd4e9d3d41ed1082ec2af959586030027 @rogeralsing committed Aug 15, 2015
View
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
View
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.22823.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wire", "Wire\Wire.csproj", "{7AF8D2B6-9F1F-4A1C-8673-48E533108385}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7AF8D2B6-9F1F-4A1C-8673-48E533108385}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7AF8D2B6-9F1F-4A1C-8673-48E533108385}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7AF8D2B6-9F1F-4A1C-8673-48E533108385}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7AF8D2B6-9F1F-4A1C-8673-48E533108385}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Wire")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Wire")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7af8d2b6-9f1f-4a1c-8673-48e533108385")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,164 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Text;
+
+namespace Wire
+{
+ public class Serializer
+ {
+ private readonly Dictionary<Type, ValueSerializer> _serializers = new Dictionary<Type, ValueSerializer>();
+
+ public ValueSerializer GetSerializerByType(Type type)
+ {
+ if (type == typeof(int))
+ return Int32Serializer.Instance;
+
+ if (type == typeof(long))
+ return Int64Serializer.Instance;
+
+ if (type == typeof(short))
+ return Int16Serializer.Instance;
+
+ if (type == typeof(byte))
+ return ByteSerializer.Instance;
+
+ if (type == typeof(bool))
+ return BoolSerializer.Instance;
+
+ if (type == typeof(DateTime))
+ return DateTimeSerializer.Instance;
+
+ if (type == typeof(string))
+ return StringSerializer.Instance;
+
+ if (type == typeof(byte[]))
+ return ByteArraySerializer.Instance;
+
+ var serializer = GetSerialzerForPoco(type);
+
+ return serializer;
+ }
+
+ private ValueSerializer GetSerialzerForPoco(Type type)
+ {
+ ValueSerializer serializer;
+ if (!_serializers.TryGetValue(type, out serializer))
+ {
+ serializer = BuildSerializer(type);
+ _serializers.Add(type, serializer);
+ }
+ return serializer;
+ }
+
+ private ValueSerializer BuildSerializer(Type type)
+ {
+ var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+ var serializer = new ObjectSerializer();
+
+ var fieldWriters = new List<Action<Stream, object, SerializerSession>>();
+ var fieldReaders = new List<Action<Stream, object, SerializerSession>>();
+ foreach (var field in fields)
+ {
+ var f = field;
+ var s = GetSerializerByType(field.FieldType);
+
+ ParameterExpression param = Expression.Parameter(typeof(object));
+ Expression castParam = Expression.Convert(param, type);
+ Expression x = Expression.Field(castParam, f);
+ Expression castRes = Expression.Convert(x, typeof(object));
+ Func<object, object> getFieldValue = Expression.Lambda<Func<object, object>>(castRes, param).Compile();
+
+ Action<Stream, object, SerializerSession> fieldWriter = (stream, o, session) =>
+ {
+ var value = getFieldValue(o);
+ s.WriteValue(stream, value, session);
+ };
+ fieldWriters.Add(fieldWriter);
+
+ Action<Stream, object, SerializerSession> fieldReader = (stream, o, session) =>
+ {
+
+ var value = s.ReadValue(stream, session);
+ f.SetValue(o, value);
+ };
+ fieldReaders.Add(fieldReader);
+ }
+
+ serializer.Writer = (stream, o, session) =>
+ {
+ for (int index = 0; index < fieldWriters.Count; index++)
+ {
+ var fieldWriter = fieldWriters[index];
+ fieldWriter(stream, o, session);
+ }
+ };
+ serializer.Reader = (stream, session) =>
+ {
+ var instance = Activator.CreateInstance(type);
+ for (int index = 0; index < fieldReaders.Count; index++)
+ {
+ var fieldReader = fieldReaders[index];
+ fieldReader(stream, instance, session);
+ }
+ return instance;
+ };
+ return serializer;
+ }
+
+ public void Serialize(object obj, Stream stream)
+ {
+ var session = new SerializerSession()
+ {
+ Buffer = new byte[100]
+ };
+ var type = obj.GetType();
+ var s = GetSerializerByType(obj.GetType());
+ s.WriteManifest(stream, type, session);
+ s.WriteValue(stream, obj, session);
+ }
+
+ public T Deserialize<T>(Stream stream)
+ {
+ var session = new SerializerSession()
+ {
+ Buffer = new byte[100]
+ };
+ var s = GetSerializerByManifest(stream, session);
+ return (T)s.ReadValue(stream, session);
+ }
+
+ private ValueSerializer GetSerializerByManifest(Stream stream, SerializerSession session)
+ {
+ var first = stream.ReadByte();
+ switch (first)
+ {
+ case 2:
+ return Int64Serializer.Instance;
+ case 3:
+ return Int16Serializer.Instance;
+ case 4:
+ return ByteSerializer.Instance;
+ case 5:
+ return DateTimeSerializer.Instance;
+ case 6:
+ return BoolSerializer.Instance;
+ case 7:
+ return StringSerializer.Instance;
+ case 8:
+ return Int32Serializer.Instance;
+ case 9:
+ return ByteArraySerializer.Instance;
+ case 255:
+ var bytes = (byte[])ByteArraySerializer.Instance.ReadValue(stream, session);
+ var typename = Encoding.UTF8.GetString(bytes);
+ var type = Type.GetType(typename);
+ return GetSerialzerForPoco(type);
+ default:
+ throw new NotSupportedException("Unknown manifest value");
+ }
+ }
+ }
+}
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Wire
+{
+ public class SerializerSession
+ {
+ public byte[] Buffer { get; set; }
+
+ public byte[] GetBuffer(int length)
+ {
+ if (length <= Buffer.Length)
+ return Buffer;
+ return new byte[length];
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 9b8766d

Please sign in to comment.