Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rogeralsing committed Aug 15, 2015
1 parent 2247f6f commit 9b8766d
Show file tree
Hide file tree
Showing 7 changed files with 607 additions and 0 deletions.
63 changes: 63 additions & 0 deletions .gitattributes
@@ -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
22 changes: 22 additions & 0 deletions Wire/Wire.sln
@@ -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
36 changes: 36 additions & 0 deletions Wire/Wire/Properties/AssemblyInfo.cs
@@ -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")]
164 changes: 164 additions & 0 deletions Wire/Wire/Serializer.cs
@@ -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");
}
}
}
}
20 changes: 20 additions & 0 deletions Wire/Wire/SerializerSession.cs
@@ -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];
}
}
}

0 comments on commit 9b8766d

Please sign in to comment.