initial workingcollection
This commit is contained in:
Родитель
86b9977a7f
Коммит
d1b05dc36d
|
@ -3,8 +3,99 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26206.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack", "src\MessagePack\MessagePack.csproj", "{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{19FE674A-AC94-4E7E-B24C-2285D1D04CDE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagePack.Tests.NETCore", "tests\MessagePack.Tests.NETCore\MessagePack.Tests.NETCore.csproj", "{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagePack.Tests", "tests\MessagePack.Tests\MessagePack.Tests.csproj", "{9E1A55CA-711D-4F58-A332-735960E3434C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Interfaces", "src\MessagePack.Interfaces\MessagePack.Interfaces.csproj", "{7BEB73DC-9106-4507-A5CC-8CD850A24109}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "T4Templates", "src\T4Templates\T4Templates.csproj", "{74108F4E-91FA-4D00-9246-2B627F271458}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Debug|x64.Build.0 = Debug|x64
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Debug|x86.Build.0 = Debug|x86
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Release|x64.ActiveCfg = Release|x64
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Release|x64.Build.0 = Release|x64
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Release|x86.ActiveCfg = Release|x86
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}.Release|x86.Build.0 = Release|x86
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Debug|x64.Build.0 = Debug|x64
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Debug|x86.Build.0 = Debug|x86
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Release|x64.ActiveCfg = Release|x64
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Release|x64.Build.0 = Release|x64
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Release|x86.ActiveCfg = Release|x86
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE}.Release|x86.Build.0 = Release|x86
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Debug|x64.Build.0 = Debug|x64
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Debug|x86.Build.0 = Debug|x86
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Release|x64.ActiveCfg = Release|x64
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Release|x64.Build.0 = Release|x64
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Release|x86.ActiveCfg = Release|x86
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109}.Release|x86.Build.0 = Release|x86
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Release|x64.Build.0 = Release|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
|
||||
{4F231E1B-2BE9-404D-ACCB-482709CE0ADE} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
|
||||
{9E1A55CA-711D-4F58-A332-735960E3434C} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
|
||||
{7BEB73DC-9106-4507-A5CC-8CD850A24109} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
|
||||
{74108F4E-91FA-4D00-9246-2B627F271458} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
libz inject-dll --assembly src\ZeroFormatter.CodeGenerator\bin\Release\zfc.exe --include src\ZeroFormatter.CodeGenerator\bin\Release\*.dll --move
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
public class MessagePackKeyAttribute : Attribute
|
||||
{
|
||||
public int? IntKey { get; private set; }
|
||||
public string StringKey { get; private set; }
|
||||
|
||||
public MessagePackKeyAttribute(int x)
|
||||
{
|
||||
this.IntKey = x;
|
||||
}
|
||||
|
||||
public MessagePackKeyAttribute(string x)
|
||||
{
|
||||
this.StringKey = x;
|
||||
}
|
||||
}
|
||||
|
||||
public class MessagePackContract : Attribute
|
||||
{
|
||||
public bool KeyAsPropertyName { get; private set; }
|
||||
|
||||
public MessagePackContract(bool keyAsPropertyName = false)
|
||||
{
|
||||
this.KeyAsPropertyName = keyAsPropertyName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.4</TargetFramework>
|
||||
<AssemblyName>MessagePack.Interfaces</AssemblyName>
|
||||
<RootNamespace>MessagePack</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
public interface IMessagePackFormatter<T>
|
||||
{
|
||||
int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver typeResolver);
|
||||
T Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
// TODO:not yet implemented
|
||||
class ObjectFormatter
|
||||
{
|
||||
// getMap
|
||||
// getLength
|
||||
// for(...){
|
||||
|
||||
// var type = TryReadType();
|
||||
// if(type.IsInteger() -> ReadInt -> switch() case... field = getValue...;
|
||||
// else if(type == string) -> ReadString -> switch() case... field = getValue...;
|
||||
|
||||
// constructor matching
|
||||
// new()... set...
|
||||
// return...
|
||||
}
|
||||
|
||||
// [SerializationConstructor]
|
||||
|
||||
//public class MetaObject
|
||||
//{
|
||||
// public bool IsIntKey { get; set; }
|
||||
// public bool IsStringKey { get { return !IsIntKey; } }
|
||||
// public bool IsClass { get; set; }
|
||||
// public bool IsStruct { get { return !IsClass; } }
|
||||
// public ConstructorInfo BestmatchConstructor { get; set; }
|
||||
|
||||
// public class Member
|
||||
// {
|
||||
// public bool IsProperty { get; set; }
|
||||
// public bool IsField { get; set; }
|
||||
// }
|
||||
//}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MessagePack.Formatters.Specialized
|
||||
{
|
||||
//public class CachedSerializeFormatter<T> : IMessagePackFormatter<T>
|
||||
// where T : class
|
||||
//{
|
||||
// object gate = new object();
|
||||
// byte[] cacheBuffer = null;
|
||||
|
||||
// public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver typeResolver)
|
||||
// {
|
||||
|
||||
// lock (gate)
|
||||
// {
|
||||
// if (cacheBuffer != null)
|
||||
// {
|
||||
// Buffer.BlockCopy(cacheBuffer, 0, bytes, offset, cacheBuffer.Length);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
|
||||
// }
|
||||
// }
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public T Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int byteSize)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
|
||||
|
||||
// //var formatter = typeResolver.GetFormatter<T>();
|
||||
// //if (formatter == this)
|
||||
// //{
|
||||
// // // use DefaultResolver to avoid circular reference.
|
||||
// // throw new NotImplementedException();
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // var huga = formatter.Deserialize(bytes, offset, typeResolver, out byteSize);
|
||||
// //}
|
||||
// }
|
||||
//}
|
||||
|
||||
public class BooleanFormatter : IMessagePackFormatter<bool>
|
||||
{
|
||||
public int Serialize(ref byte[] bytes, int offset, bool value, IFormatterResolver typeResolver)
|
||||
{
|
||||
return MessagePackBinary.WriteBoolean(ref bytes, offset, value);
|
||||
}
|
||||
|
||||
public bool Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
|
||||
{
|
||||
return MessagePackBinary.ReadBoolean(bytes, offset, out readSize);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
using MessagePack.Formatters;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
public interface IFormatterResolver
|
||||
{
|
||||
IMessagePackFormatter<T> GetFormatter<T>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
public interface IMessagePackSerializationCallbackReceiver
|
||||
{
|
||||
void OnBeforeSerialize();
|
||||
void OnAfterDeserialize();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.4</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\T4Templates\PrimitiveFormatter.cs" Link="Formatters\PrimitiveFormatter.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,975 @@
|
|||
using MessagePack.Decoders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
/// <summary>
|
||||
/// Encode/Decode Utility of MessagePack Spec.
|
||||
/// https://github.com/msgpack/msgpack/blob/master/spec.md
|
||||
/// </summary>
|
||||
public static class MessagePackBinary
|
||||
{
|
||||
const int MaxSize = byte.MaxValue;
|
||||
|
||||
static readonly IBooleanDecoder[] booleanDecoders = new IBooleanDecoder[MaxSize];
|
||||
static readonly IByteDecoder[] byteDecoders = new IByteDecoder[MaxSize];
|
||||
static readonly IBytesDecoder[] bytesDecoders = new IBytesDecoder[MaxSize];
|
||||
|
||||
// static readonly Func<byte[], int, int>[] IntegerDecoder = new Func<byte[], int, int>[255];
|
||||
|
||||
static MessagePackBinary()
|
||||
{
|
||||
// Init LookupTable.
|
||||
for (int i = 0; i < MaxSize; i++)
|
||||
{
|
||||
booleanDecoders[i] = Decoders.InvalidBoolean.Instance;
|
||||
byteDecoders[i] = Decoders.InvalidByte.Instance;
|
||||
bytesDecoders[i] = Decoders.InvalidBytes.Instance;
|
||||
}
|
||||
|
||||
// Emit Codes.
|
||||
for (int i = MessagePackCode.MinFixInt; i <= MessagePackCode.MaxFixInt; i++)
|
||||
{
|
||||
// IntegerDecoder[i] = DecodeFixInteger;
|
||||
byteDecoders[i] = Decoders.FixByte.Instance;
|
||||
}
|
||||
for (int i = MessagePackCode.MinFixMap; i <= MessagePackCode.MaxFixMap; i++)
|
||||
{
|
||||
// typeLookupTable[i] = MessagePackType.Map;
|
||||
}
|
||||
for (int i = MessagePackCode.MinFixArray; i <= MessagePackCode.MaxFixArray; i++)
|
||||
{
|
||||
//typeLookupTable[i] = MessagePackType.Array;
|
||||
}
|
||||
for (int i = MessagePackCode.MinFixStr; i <= MessagePackCode.MaxFixStr; i++)
|
||||
{
|
||||
//typeLookupTable[i] = MessagePackType.String;
|
||||
}
|
||||
|
||||
bytesDecoders[MessagePackCode.Nil] = Decoders.NilBytes.Instance;
|
||||
|
||||
//typeLookupTable[MessagePackCode.NeverUsed] = MessagePackType.Unknown;
|
||||
booleanDecoders[MessagePackCode.False] = Decoders.False.Instance;
|
||||
booleanDecoders[MessagePackCode.True] = Decoders.True.Instance;
|
||||
bytesDecoders[MessagePackCode.Bin8] = Decoders.Bin8Bytes.Instance;
|
||||
bytesDecoders[MessagePackCode.Bin16] = Decoders.Bin16Bytes.Instance;
|
||||
bytesDecoders[MessagePackCode.Bin32] = Decoders.Bin32Bytes.Instance;
|
||||
//typeLookupTable[MessagePackCode.Ext8] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.Ext16] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.Ext32] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.Float32] = MessagePackType.Float;
|
||||
//typeLookupTable[MessagePackCode.Float64] = MessagePackType.Float;
|
||||
|
||||
byteDecoders[MessagePackCode.UInt8] = Decoders.UInt8Byte.Instance;
|
||||
|
||||
//typeLookupTable[MessagePackCode.UInt16] = MessagePackType.Integer;
|
||||
//typeLookupTable[MessagePackCode.UInt32] = MessagePackType.Integer;
|
||||
//typeLookupTable[MessagePackCode.UInt64] = MessagePackType.Integer;
|
||||
|
||||
// byteDecoders[MessagePackCode.Int8] = Decoders.UInt8Byte;
|
||||
|
||||
|
||||
//typeLookupTable[MessagePackCode.Int16] = MessagePackType.Integer;
|
||||
//typeLookupTable[MessagePackCode.Int32] = MessagePackType.Integer;
|
||||
//typeLookupTable[MessagePackCode.Int64] = MessagePackType.Integer;
|
||||
//typeLookupTable[MessagePackCode.FixExt1] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.FixExt2] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.FixExt4] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.FixExt8] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.FixExt16] = MessagePackType.Extension;
|
||||
//typeLookupTable[MessagePackCode.Str8] = MessagePackType.String;
|
||||
//typeLookupTable[MessagePackCode.Str16] = MessagePackType.String;
|
||||
//typeLookupTable[MessagePackCode.Str32] = MessagePackType.String;
|
||||
//typeLookupTable[MessagePackCode.Array16] = MessagePackType.Array;
|
||||
//typeLookupTable[MessagePackCode.Array32] = MessagePackType.Array;
|
||||
//typeLookupTable[MessagePackCode.Map16] = MessagePackType.Map;
|
||||
//typeLookupTable[MessagePackCode.Map32] = MessagePackType.Map;
|
||||
|
||||
for (int i = MessagePackCode.MinNegativeFixInt; i <= MessagePackCode.MaxNegativeFixInt; i++)
|
||||
{
|
||||
//typeLookupTable[i] = MessagePackType.Integer;
|
||||
}
|
||||
}
|
||||
|
||||
public static MessagePackType GetMessagePackType(byte[] bytes, int offset)
|
||||
{
|
||||
return MessagePackCode.ToMessagePackType(bytes[offset]);
|
||||
}
|
||||
|
||||
public static void EnsureCapacity(ref byte[] bytes, int offset, int appendLength)
|
||||
{
|
||||
var newLength = offset + appendLength;
|
||||
|
||||
// If null(most case fisrt time) fill byte.
|
||||
if (bytes == null)
|
||||
{
|
||||
bytes = new byte[newLength];
|
||||
return;
|
||||
}
|
||||
|
||||
// like MemoryStream.EnsureCapacity
|
||||
var current = bytes.Length;
|
||||
if (newLength > current)
|
||||
{
|
||||
int num = newLength;
|
||||
if (num < 256)
|
||||
{
|
||||
num = 256;
|
||||
FastResize(ref bytes, num);
|
||||
return;
|
||||
}
|
||||
if (num < current * 2)
|
||||
{
|
||||
num = current * 2;
|
||||
}
|
||||
|
||||
FastResize(ref bytes, num);
|
||||
}
|
||||
}
|
||||
|
||||
// Buffer.BlockCopy version of Array.Resize
|
||||
public static void FastResize(ref byte[] array, int newSize)
|
||||
{
|
||||
if (newSize < 0) throw new ArgumentOutOfRangeException("newSize");
|
||||
|
||||
byte[] array2 = array;
|
||||
if (array2 == null)
|
||||
{
|
||||
array = new byte[newSize];
|
||||
return;
|
||||
}
|
||||
|
||||
if (array2.Length != newSize)
|
||||
{
|
||||
byte[] array3 = new byte[newSize];
|
||||
Buffer.BlockCopy(array2, 0, array3, 0, (array2.Length > newSize) ? newSize : array2.Length);
|
||||
array = array3;
|
||||
}
|
||||
}
|
||||
|
||||
public static int WriteNil(ref byte[] bytes, int offset)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 1);
|
||||
|
||||
bytes[offset] = MessagePackCode.Nil;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe! don't ensure capacity and don't return size.
|
||||
/// </summary>
|
||||
public static void WriteNilUnsafe(ref byte[] bytes, int offset, bool value)
|
||||
{
|
||||
bytes[offset] = MessagePackCode.Nil;
|
||||
}
|
||||
|
||||
public static Nil ReadNil(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
if (bytes[offset] == MessagePackCode.Nil)
|
||||
{
|
||||
readSize = 1;
|
||||
return Nil.Default;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("code is invalid. code:{0} type:{1}", bytes[offset], MessagePackCode.ToMessagePackType(bytes[offset])));
|
||||
}
|
||||
}
|
||||
|
||||
public static int WriteBoolean(ref byte[] bytes, int offset, bool value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 1);
|
||||
|
||||
bytes[offset] = (value ? MessagePackCode.True : MessagePackCode.False);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe! don't ensure capacity and don't return size.
|
||||
/// </summary>
|
||||
public static void WriteBooleanUnsafe(ref byte[] bytes, int offset, bool value)
|
||||
{
|
||||
bytes[offset] = (value ? MessagePackCode.True : MessagePackCode.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe! don't ensure capacity and don't return size.
|
||||
/// </summary>
|
||||
public static void WriteBooleanTrueUnsafe(ref byte[] bytes, int offset)
|
||||
{
|
||||
bytes[offset] = MessagePackCode.True;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe! don't ensure capacity and don't return size.
|
||||
/// </summary>
|
||||
public static void WriteBooleanFalseUnsafe(ref byte[] bytes, int offset)
|
||||
{
|
||||
bytes[offset] = MessagePackCode.False;
|
||||
}
|
||||
|
||||
public static bool ReadBoolean(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
readSize = 1;
|
||||
return booleanDecoders[bytes[offset]].Read();
|
||||
}
|
||||
|
||||
public static int WriteByte(ref byte[] bytes, int offset, byte value)
|
||||
{
|
||||
if (value <= MessagePackCode.MaxFixInt)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 1);
|
||||
bytes[offset] = value;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 2);
|
||||
bytes[offset] = MessagePackCode.UInt8;
|
||||
bytes[offset + 1] = value;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte ReadByte(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
return byteDecoders[bytes[offset]].Read(bytes, offset, out readSize);
|
||||
}
|
||||
|
||||
public static int WriteBytes(ref byte[] bytes, int offset, byte[] value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return WriteNil(ref bytes, offset);
|
||||
}
|
||||
|
||||
var len = value.Length;
|
||||
if (len <= byte.MaxValue)
|
||||
{
|
||||
var size = value.Length + 2;
|
||||
EnsureCapacity(ref bytes, offset, size);
|
||||
|
||||
bytes[offset] = MessagePackCode.Bin8;
|
||||
bytes[offset + 1] = (byte)len;
|
||||
|
||||
Buffer.BlockCopy(value, 0, bytes, offset + 2, value.Length);
|
||||
return size;
|
||||
}
|
||||
else if (len <= UInt16.MaxValue)
|
||||
{
|
||||
var size = value.Length + 3;
|
||||
EnsureCapacity(ref bytes, offset, size);
|
||||
|
||||
bytes[offset] = MessagePackCode.Bin16;
|
||||
bytes[offset + 1] = (byte)(len >> 8);
|
||||
bytes[offset + 2] = (byte)(len);
|
||||
|
||||
Buffer.BlockCopy(value, 0, bytes, offset + 3, value.Length);
|
||||
return size;
|
||||
}
|
||||
else
|
||||
{
|
||||
var size = value.Length + 5;
|
||||
EnsureCapacity(ref bytes, offset, size);
|
||||
|
||||
bytes[offset] = MessagePackCode.Bin32;
|
||||
bytes[offset + 1] = (byte)(len >> 24);
|
||||
bytes[offset + 2] = (byte)(len >> 16);
|
||||
bytes[offset + 3] = (byte)(len >> 8);
|
||||
bytes[offset + 4] = (byte)(len);
|
||||
|
||||
Buffer.BlockCopy(value, 0, bytes, offset + 5, value.Length);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ReadBytes(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
return bytesDecoders[bytes[offset]].Read(bytes, offset, out readSize);
|
||||
}
|
||||
|
||||
// TODO:..................
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static int WriteSByte(ref byte[] bytes, int offset, sbyte value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 1);
|
||||
|
||||
bytes[offset] = (byte)value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static sbyte ReadSByte(ref byte[] bytes, int offset)
|
||||
{
|
||||
return (sbyte)bytes[offset];
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteSingle(ref byte[] bytes, int offset, float value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 4);
|
||||
|
||||
if (offset % 4 == 0)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(float*)(ptr + offset) = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint num = *(uint*)(&value);
|
||||
bytes[offset] = (byte)num;
|
||||
bytes[offset + 1] = (byte)(num >> 8);
|
||||
bytes[offset + 2] = (byte)(num >> 16);
|
||||
bytes[offset + 3] = (byte)(num >> 24);
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe float ReadSingle(ref byte[] bytes, int offset)
|
||||
{
|
||||
if (offset % 4 == 0)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(float*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint num = (uint)((int)bytes[offset] | (int)bytes[offset + 1] << 8 | (int)bytes[offset + 2] << 16 | (int)bytes[offset + 3] << 24);
|
||||
return *(float*)(&num);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteDouble(ref byte[] bytes, int offset, double value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 8);
|
||||
|
||||
if (offset % 8 == 0)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(double*)(ptr + offset) = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong num = (ulong)(*(long*)(&value));
|
||||
bytes[offset] = (byte)num;
|
||||
bytes[offset + 1] = (byte)(num >> 8);
|
||||
bytes[offset + 2] = (byte)(num >> 16);
|
||||
bytes[offset + 3] = (byte)(num >> 24);
|
||||
bytes[offset + 4] = (byte)(num >> 32);
|
||||
bytes[offset + 5] = (byte)(num >> 40);
|
||||
bytes[offset + 6] = (byte)(num >> 48);
|
||||
bytes[offset + 7] = (byte)(num >> 56);
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe double ReadDouble(ref byte[] bytes, int offset)
|
||||
{
|
||||
if (offset % 8 == 0)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(double*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint num = (uint)((int)bytes[offset] | (int)bytes[offset + 1] << 8 | (int)bytes[offset + 2] << 16 | (int)bytes[offset + 3] << 24);
|
||||
ulong num2 = (ulong)((int)bytes[offset + 4] | (int)bytes[offset + 5] << 8 | (int)bytes[offset + 6] << 16 | (int)bytes[offset + 7] << 24) << 32 | (ulong)num;
|
||||
return *(double*)(&num2);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteInt16(ref byte[] bytes, int offset, short value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 2);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(short*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe short ReadInt16(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(short*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteInt32(ref byte[] bytes, int offset, int value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 4);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(int*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe! don't ensure capacity and don't return size.
|
||||
/// </summary>
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe void WriteInt32Unsafe(ref byte[] bytes, int offset, int value)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(int*)(ptr + offset) = value;
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int ReadInt32(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(int*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteInt64(ref byte[] bytes, int offset, long value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 8);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(long*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe long ReadInt64(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(long*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteUInt16(ref byte[] bytes, int offset, ushort value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 2);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(ushort*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe ushort ReadUInt16(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(ushort*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteUInt32(ref byte[] bytes, int offset, uint value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 4);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(uint*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe uint ReadUInt32(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(uint*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteUInt64(ref byte[] bytes, int offset, ulong value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 8);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(ulong*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe ulong ReadUInt64(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(ulong*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static int WriteChar(ref byte[] bytes, int offset, char value)
|
||||
{
|
||||
return WriteUInt16(ref bytes, offset, (ushort)value);
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static char ReadChar(ref byte[] bytes, int offset)
|
||||
{
|
||||
return (char)ReadUInt16(ref bytes, offset);
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static int WriteString(ref byte[] bytes, int offset, string value)
|
||||
{
|
||||
var ensureSize = StringEncoding.UTF8.GetMaxByteCount(value.Length);
|
||||
EnsureCapacity(ref bytes, offset, ensureSize);
|
||||
|
||||
return StringEncoding.UTF8.GetBytes(value, 0, value.Length, bytes, offset);
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static string ReadString(ref byte[] bytes, int offset, int count)
|
||||
{
|
||||
return StringEncoding.UTF8.GetString(bytes, offset, count);
|
||||
}
|
||||
|
||||
// decimal underlying "flags, hi, lo, mid" fields are sequential and same layuout with .NET Framework and Mono(Unity)
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteDecimal(ref byte[] bytes, int offset, decimal value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 16);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(Decimal*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 16;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe decimal ReadDecimal(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(Decimal*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
// Guid's underlying _a,...,_k field is sequential and same layuout as .NET Framework and Mono(Unity)
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe int WriteGuid(ref byte[] bytes, int offset, Guid value)
|
||||
{
|
||||
EnsureCapacity(ref bytes, offset, 16);
|
||||
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(Guid*)(ptr + offset) = value;
|
||||
}
|
||||
|
||||
return 16;
|
||||
}
|
||||
|
||||
#if !UNITY
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static unsafe Guid ReadGuid(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
return *(Guid*)(ptr + offset);
|
||||
}
|
||||
}
|
||||
|
||||
#region Timestamp/Duration
|
||||
|
||||
public static unsafe int WriteTimeSpan(ref byte[] bytes, int offset, TimeSpan timeSpan)
|
||||
{
|
||||
checked
|
||||
{
|
||||
long ticks = timeSpan.Ticks;
|
||||
long seconds = ticks / TimeSpan.TicksPerSecond;
|
||||
int nanos = (int)(ticks % TimeSpan.TicksPerSecond) * Duration.NanosecondsPerTick;
|
||||
|
||||
EnsureCapacity(ref bytes, offset, 12);
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(long*)(ptr + offset) = seconds;
|
||||
*(int*)(ptr + offset + 8) = nanos;
|
||||
}
|
||||
|
||||
return 12;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe TimeSpan ReadTimeSpan(ref byte[] bytes, int offset)
|
||||
{
|
||||
checked
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
var seconds = *(long*)(ptr + offset);
|
||||
var nanos = *(int*)(ptr + offset + 8);
|
||||
|
||||
if (!Duration.IsNormalized(seconds, nanos))
|
||||
{
|
||||
throw new InvalidOperationException("Duration was not a valid normalized duration");
|
||||
}
|
||||
long ticks = seconds * TimeSpan.TicksPerSecond + nanos / Duration.NanosecondsPerTick;
|
||||
return TimeSpan.FromTicks(ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe int WriteDateTime(ref byte[] bytes, int offset, DateTime dateTime)
|
||||
{
|
||||
dateTime = dateTime.ToUniversalTime();
|
||||
|
||||
// Do the arithmetic using DateTime.Ticks, which is always non-negative, making things simpler.
|
||||
long secondsSinceBclEpoch = dateTime.Ticks / TimeSpan.TicksPerSecond;
|
||||
int nanoseconds = (int)(dateTime.Ticks % TimeSpan.TicksPerSecond) * Duration.NanosecondsPerTick;
|
||||
|
||||
EnsureCapacity(ref bytes, offset, 12);
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
*(long*)(ptr + offset) = (secondsSinceBclEpoch - Timestamp.BclSecondsAtUnixEpoch);
|
||||
*(int*)(ptr + offset + 8) = nanoseconds;
|
||||
}
|
||||
|
||||
return 12;
|
||||
}
|
||||
|
||||
public static unsafe DateTime ReadDateTime(ref byte[] bytes, int offset)
|
||||
{
|
||||
fixed (byte* ptr = bytes)
|
||||
{
|
||||
var seconds = *(long*)(ptr + offset);
|
||||
var nanos = *(int*)(ptr + offset + 8);
|
||||
|
||||
if (!Timestamp.IsNormalized(seconds, nanos))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(@"Timestamp contains invalid values: Seconds={0}; Nanos={1}", seconds, nanos));
|
||||
}
|
||||
return Timestamp.UnixEpoch.AddSeconds(seconds).AddTicks(nanos / Duration.NanosecondsPerTick);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Timestamp
|
||||
{
|
||||
internal static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
internal const long BclSecondsAtUnixEpoch = 62135596800;
|
||||
internal const long UnixSecondsAtBclMaxValue = 253402300799;
|
||||
internal const long UnixSecondsAtBclMinValue = -BclSecondsAtUnixEpoch;
|
||||
internal const int MaxNanos = Duration.NanosecondsPerSecond - 1;
|
||||
|
||||
internal static bool IsNormalized(long seconds, int nanoseconds)
|
||||
{
|
||||
return nanoseconds >= 0 &&
|
||||
nanoseconds <= MaxNanos &&
|
||||
seconds >= UnixSecondsAtBclMinValue &&
|
||||
seconds <= UnixSecondsAtBclMaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Duration
|
||||
{
|
||||
public const int NanosecondsPerSecond = 1000000000;
|
||||
public const int NanosecondsPerTick = 100;
|
||||
public const long MaxSeconds = 315576000000L;
|
||||
public const long MinSeconds = -315576000000L;
|
||||
internal const int MaxNanoseconds = NanosecondsPerSecond - 1;
|
||||
internal const int MinNanoseconds = -NanosecondsPerSecond + 1;
|
||||
|
||||
internal static bool IsNormalized(long seconds, int nanoseconds)
|
||||
{
|
||||
// Simple boundaries
|
||||
if (seconds < MinSeconds || seconds > MaxSeconds ||
|
||||
nanoseconds < MinNanoseconds || nanoseconds > MaxNanoseconds)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// We only have a problem is one is strictly negative and the other is
|
||||
// strictly positive.
|
||||
return Math.Sign(seconds) * Math.Sign(nanoseconds) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
namespace MessagePack.Decoders
|
||||
{
|
||||
internal interface IBooleanDecoder
|
||||
{
|
||||
bool Read();
|
||||
}
|
||||
|
||||
internal class True : IBooleanDecoder
|
||||
{
|
||||
internal static IBooleanDecoder Instance = new True();
|
||||
|
||||
True() { }
|
||||
|
||||
public bool Read()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal class False : IBooleanDecoder
|
||||
{
|
||||
internal static IBooleanDecoder Instance = new False();
|
||||
|
||||
False() { }
|
||||
|
||||
public bool Read()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal class InvalidBoolean : IBooleanDecoder
|
||||
{
|
||||
internal static IBooleanDecoder Instance = new InvalidBoolean();
|
||||
|
||||
InvalidBoolean() { }
|
||||
|
||||
public bool Read()
|
||||
{
|
||||
throw new InvalidOperationException("code is invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IByteDecoder
|
||||
{
|
||||
byte Read(byte[] bytes, int offset, out int readSize);
|
||||
}
|
||||
|
||||
internal class FixByte : IByteDecoder
|
||||
{
|
||||
internal static readonly IByteDecoder Instance = new FixByte();
|
||||
|
||||
FixByte()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
readSize = 1;
|
||||
return bytes[offset];
|
||||
}
|
||||
}
|
||||
|
||||
internal class UInt8Byte : IByteDecoder
|
||||
{
|
||||
internal static readonly IByteDecoder Instance = new UInt8Byte();
|
||||
|
||||
UInt8Byte()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
readSize = 2;
|
||||
return bytes[offset + 1];
|
||||
}
|
||||
}
|
||||
|
||||
internal class InvalidByte : IByteDecoder
|
||||
{
|
||||
internal static readonly IByteDecoder Instance = new InvalidByte();
|
||||
|
||||
InvalidByte()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("code is invalid. code:{0} type:{1}", bytes[offset], MessagePackCode.ToMessagePackType(bytes[offset])));
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IBytesDecoder
|
||||
{
|
||||
byte[] Read(byte[] bytes, int offset, out int readSize);
|
||||
}
|
||||
|
||||
internal class NilBytes : IBytesDecoder
|
||||
{
|
||||
internal static readonly IBytesDecoder Instance = new NilBytes();
|
||||
|
||||
NilBytes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte[] Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
readSize = 1;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Bin8Bytes : IBytesDecoder
|
||||
{
|
||||
internal static readonly IBytesDecoder Instance = new Bin8Bytes();
|
||||
|
||||
Bin8Bytes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte[] Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
var length = bytes[offset + 1];
|
||||
var newBytes = new byte[length];
|
||||
Buffer.BlockCopy(bytes, offset + 2, newBytes, 0, length);
|
||||
|
||||
readSize = length + 2;
|
||||
return newBytes;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Bin16Bytes : IBytesDecoder
|
||||
{
|
||||
internal static readonly IBytesDecoder Instance = new Bin16Bytes();
|
||||
|
||||
Bin16Bytes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte[] Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
var length = ((int)bytes[offset + 1] << 8 | (int)bytes[offset + 2]);
|
||||
var newBytes = new byte[length];
|
||||
Buffer.BlockCopy(bytes, offset + 3, newBytes, 0, length);
|
||||
|
||||
readSize = length + 3;
|
||||
return newBytes;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Bin32Bytes : IBytesDecoder
|
||||
{
|
||||
internal static readonly IBytesDecoder Instance = new Bin32Bytes();
|
||||
|
||||
Bin32Bytes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte[] Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
var length = ((int)bytes[offset + 1] << 24 | (int)bytes[offset + 2] << 16 | (int)bytes[offset + 3] << 8 | (int)bytes[offset + 4]);
|
||||
var newBytes = new byte[length];
|
||||
Buffer.BlockCopy(bytes, offset + 5, newBytes, 0, length);
|
||||
|
||||
readSize = length + 5;
|
||||
return newBytes;
|
||||
}
|
||||
}
|
||||
|
||||
internal class InvalidBytes : IBytesDecoder
|
||||
{
|
||||
internal static readonly IBytesDecoder Instance = new InvalidBytes();
|
||||
|
||||
InvalidBytes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte[] Read(byte[] bytes, int offset, out int readSize)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("code is invalid. code:{0} type:{1}", bytes[offset], MessagePackCode.ToMessagePackType(bytes[offset])));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
/// <summary>
|
||||
/// https://github.com/msgpack/msgpack/blob/master/spec.md#serialization-type-to-format-conversion
|
||||
/// </summary>
|
||||
public enum MessagePackType : byte
|
||||
{
|
||||
Integer = 0,
|
||||
Nil = 1,
|
||||
Boolean = 2,
|
||||
Float = 3,
|
||||
String = 4,
|
||||
Binary = 5,
|
||||
Array = 6,
|
||||
Map = 7,
|
||||
Extension = 8,
|
||||
|
||||
Unknown = 255
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://github.com/msgpack/msgpack/blob/master/spec.md#overview
|
||||
/// </summary>
|
||||
public static class MessagePackCode
|
||||
{
|
||||
public const byte MinFixInt = 0x00;
|
||||
public const byte MaxFixInt = 0x7f;
|
||||
public const byte MinFixMap = 0x80;
|
||||
public const byte MaxFixMap = 0x8f;
|
||||
public const byte MinFixArray = 0x90;
|
||||
public const byte MaxFixArray = 0x9f;
|
||||
public const byte MinFixStr = 0xa0;
|
||||
public const byte MaxFixStr = 0xbf;
|
||||
public const byte Nil = 0xc0;
|
||||
public const byte NeverUsed = 0xc1;
|
||||
public const byte False = 0xc2;
|
||||
public const byte True = 0xc3;
|
||||
public const byte Bin8 = 0xc4;
|
||||
public const byte Bin16 = 0xc5;
|
||||
public const byte Bin32 = 0xc6;
|
||||
public const byte Ext8 = 0xc7;
|
||||
public const byte Ext16 = 0xc8;
|
||||
public const byte Ext32 = 0xc9;
|
||||
public const byte Float32 = 0xca;
|
||||
public const byte Float64 = 0xcb;
|
||||
public const byte UInt8 = 0xcc;
|
||||
public const byte UInt16 = 0xcd;
|
||||
public const byte UInt32 = 0xce;
|
||||
public const byte UInt64 = 0xcf;
|
||||
public const byte Int8 = 0xd0;
|
||||
public const byte Int16 = 0xd1;
|
||||
public const byte Int32 = 0xd2;
|
||||
public const byte Int64 = 0xd3;
|
||||
public const byte FixExt1 = 0xd4;
|
||||
public const byte FixExt2 = 0xd5;
|
||||
public const byte FixExt4 = 0xd6;
|
||||
public const byte FixExt8 = 0xd7;
|
||||
public const byte FixExt16 = 0xd8;
|
||||
public const byte Str8 = 0xd9;
|
||||
public const byte Str16 = 0xda;
|
||||
public const byte Str32 = 0xdb;
|
||||
public const byte Array16 = 0xdc;
|
||||
public const byte Array32 = 0xdd;
|
||||
public const byte Map16 = 0xde;
|
||||
public const byte Map32 = 0xdf;
|
||||
public const byte MinNegativeFixInt = 0xe0;
|
||||
public const byte MaxNegativeFixInt = 0xff;
|
||||
|
||||
static readonly MessagePackType[] typeLookupTable = new MessagePackType[255];
|
||||
|
||||
static MessagePackCode()
|
||||
{
|
||||
// Init Lookup Table
|
||||
for (int i = MinFixInt; i <= MaxFixInt; i++)
|
||||
{
|
||||
typeLookupTable[i] = MessagePackType.Integer;
|
||||
}
|
||||
for (int i = MinFixMap; i <= MaxFixMap; i++)
|
||||
{
|
||||
typeLookupTable[i] = MessagePackType.Map;
|
||||
}
|
||||
for (int i = MinFixArray; i <= MaxFixArray; i++)
|
||||
{
|
||||
typeLookupTable[i] = MessagePackType.Array;
|
||||
}
|
||||
for (int i = MinFixStr; i <= MaxFixStr; i++)
|
||||
{
|
||||
typeLookupTable[i] = MessagePackType.String;
|
||||
}
|
||||
typeLookupTable[Nil] = MessagePackType.Nil;
|
||||
typeLookupTable[NeverUsed] = MessagePackType.Unknown;
|
||||
typeLookupTable[False] = MessagePackType.Boolean;
|
||||
typeLookupTable[True] = MessagePackType.Boolean;
|
||||
typeLookupTable[Bin8] = MessagePackType.Binary;
|
||||
typeLookupTable[Bin16] = MessagePackType.Binary;
|
||||
typeLookupTable[Bin32] = MessagePackType.Binary;
|
||||
typeLookupTable[Ext8] = MessagePackType.Extension;
|
||||
typeLookupTable[Ext16] = MessagePackType.Extension;
|
||||
typeLookupTable[Ext32] = MessagePackType.Extension;
|
||||
typeLookupTable[Float32] = MessagePackType.Float;
|
||||
typeLookupTable[Float64] = MessagePackType.Float;
|
||||
typeLookupTable[UInt8] = MessagePackType.Integer;
|
||||
typeLookupTable[UInt16] = MessagePackType.Integer;
|
||||
typeLookupTable[UInt32] = MessagePackType.Integer;
|
||||
typeLookupTable[UInt64] = MessagePackType.Integer;
|
||||
typeLookupTable[Int8] = MessagePackType.Integer;
|
||||
typeLookupTable[Int16] = MessagePackType.Integer;
|
||||
typeLookupTable[Int32] = MessagePackType.Integer;
|
||||
typeLookupTable[Int64] = MessagePackType.Integer;
|
||||
typeLookupTable[FixExt1] = MessagePackType.Extension;
|
||||
typeLookupTable[FixExt2] = MessagePackType.Extension;
|
||||
typeLookupTable[FixExt4] = MessagePackType.Extension;
|
||||
typeLookupTable[FixExt8] = MessagePackType.Extension;
|
||||
typeLookupTable[FixExt16] = MessagePackType.Extension;
|
||||
typeLookupTable[Str8] = MessagePackType.String;
|
||||
typeLookupTable[Str16] = MessagePackType.String;
|
||||
typeLookupTable[Str32] = MessagePackType.String;
|
||||
typeLookupTable[Array16] = MessagePackType.Array;
|
||||
typeLookupTable[Array32] = MessagePackType.Array;
|
||||
typeLookupTable[Map16] = MessagePackType.Map;
|
||||
typeLookupTable[Map32] = MessagePackType.Map;
|
||||
for (int i = MinNegativeFixInt; i <= MaxNegativeFixInt; i++)
|
||||
{
|
||||
typeLookupTable[i] = MessagePackType.Integer;
|
||||
}
|
||||
}
|
||||
|
||||
public static MessagePackType ToMessagePackType(byte code)
|
||||
{
|
||||
return typeLookupTable[code];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
public static class MessagePackSerializer
|
||||
{
|
||||
}
|
||||
|
||||
internal static class InternalMemoryPool
|
||||
{
|
||||
[ThreadStatic]
|
||||
public static readonly byte[] Buffer = new byte[4096];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
public struct Nil : IEquatable<Nil>
|
||||
{
|
||||
public static readonly Nil Default = new Nil();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Nil;
|
||||
}
|
||||
|
||||
public bool Equals(Nil other)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "()";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MessagePack.Formatters;
|
||||
|
||||
namespace MessagePack.Resolvers
|
||||
{
|
||||
public class BuiltinResolver : IFormatterResolver
|
||||
{
|
||||
public IMessagePackFormatter<T> GetFormatter<T>()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using MessagePack.Formatters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MessagePack.Resolvers
|
||||
{
|
||||
public class DefaultResolver : IFormatterResolver
|
||||
{
|
||||
public static IFormatterResolver Instance = new DefaultResolver();
|
||||
|
||||
DefaultResolver()
|
||||
{
|
||||
}
|
||||
|
||||
public IMessagePackFormatter<T> GetFormatter<T>()
|
||||
{
|
||||
return FormatterCache<T>.formatter;
|
||||
}
|
||||
|
||||
static class FormatterCache<T>
|
||||
{
|
||||
public static readonly IMessagePackFormatter<T> formatter;
|
||||
|
||||
static FormatterCache()
|
||||
{
|
||||
//if (typeof(T) == typeof(NotMsgPackMarkedClass))
|
||||
//{
|
||||
// formatter = (IMessagePackFormatter<T>)(object)new NotMsgPackMarkedClassFormatter();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // fallback, use default formatter.
|
||||
// // formatter =
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MessagePack.Formatters;
|
||||
|
||||
namespace MessagePack.Resolvers
|
||||
{
|
||||
public class DynamicResolver : IFormatterResolver
|
||||
{
|
||||
IMessagePackFormatter<T> IFormatterResolver.GetFormatter<T>()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MessagePack.Formatters;
|
||||
|
||||
namespace MessagePack.Resolvers
|
||||
{
|
||||
public class EnumResolver : IFormatterResolver
|
||||
{
|
||||
IMessagePackFormatter<T> IFormatterResolver.GetFormatter<T>()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using System.Text;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
internal static class StringEncoding
|
||||
{
|
||||
public static readonly Encoding UTF8 = new UTF8Encoding(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
</configuration>
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
public class BooleanFormatter : IMessagePackFormatter<Boolean>
|
||||
{
|
||||
public int Serialize(ref byte[] bytes, int offset, Boolean value, IFormatterResolver typeResolver)
|
||||
{
|
||||
return MessagePackBinary.WriteBoolean(ref bytes, offset, value);
|
||||
}
|
||||
|
||||
public Boolean Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
|
||||
{
|
||||
return MessagePackBinary.ReadBoolean(bytes, offset, out readSize);
|
||||
}
|
||||
}
|
||||
|
||||
public class NullableBooleanFormatter : IMessagePackFormatter<Boolean?>
|
||||
{
|
||||
public int Serialize(ref byte[] bytes, int offset, Boolean? value, IFormatterResolver typeResolver)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return MessagePackBinary.WriteNil(ref bytes, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessagePackBinary.WriteBoolean(ref bytes, offset, value.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean? Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
|
||||
{
|
||||
if (bytes[offset] == MessagePackCode.Nil)
|
||||
{
|
||||
readSize = 1;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessagePackBinary.ReadBoolean(bytes, offset, out readSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ByteFormatter : IMessagePackFormatter<Byte>
|
||||
{
|
||||
public int Serialize(ref byte[] bytes, int offset, Byte value, IFormatterResolver typeResolver)
|
||||
{
|
||||
return MessagePackBinary.WriteByte(ref bytes, offset, value);
|
||||
}
|
||||
|
||||
public Byte Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
|
||||
{
|
||||
return MessagePackBinary.ReadByte(bytes, offset, out readSize);
|
||||
}
|
||||
}
|
||||
|
||||
public class NullableByteFormatter : IMessagePackFormatter<Byte?>
|
||||
{
|
||||
public int Serialize(ref byte[] bytes, int offset, Byte? value, IFormatterResolver typeResolver)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return MessagePackBinary.WriteNil(ref bytes, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessagePackBinary.WriteByte(ref bytes, offset, value.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public Byte? Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
|
||||
{
|
||||
if (bytes[offset] == MessagePackCode.Nil)
|
||||
{
|
||||
readSize = 1;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessagePackBinary.ReadByte(bytes, offset, out readSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var types = new[]
|
||||
{
|
||||
/*
|
||||
Tuple.Create(typeof(Int16), 2),
|
||||
Tuple.Create(typeof(Int32), 4),
|
||||
Tuple.Create(typeof(Int64), 8),
|
||||
Tuple.Create(typeof(UInt16), 2),
|
||||
Tuple.Create(typeof(UInt32), 4),
|
||||
Tuple.Create(typeof(UInt64), 8),
|
||||
Tuple.Create(typeof(Single), 4),
|
||||
Tuple.Create(typeof(Double), 8),
|
||||
*/
|
||||
Tuple.Create(typeof(bool), 1),
|
||||
Tuple.Create(typeof(byte), 1),
|
||||
/*
|
||||
Tuple.Create(typeof(sbyte), 1),
|
||||
Tuple.Create(typeof(char), 2),
|
||||
Tuple.Create(typeof(decimal), 16),
|
||||
Tuple.Create(typeof(Guid), 16),
|
||||
Tuple.Create(typeof(TimeSpan), 12),
|
||||
Tuple.Create(typeof(DateTime), 12),
|
||||
*/
|
||||
};
|
||||
#>
|
||||
using System;
|
||||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
<# foreach(var tuple in types) { var t = tuple.Item1; #>
|
||||
public class <#= t.Name #>Formatter : IMessagePackFormatter<<#= t.Name #>>
|
||||
{
|
||||
public int Serialize(ref byte[] bytes, int offset, <#= t.Name #> value, IFormatterResolver typeResolver)
|
||||
{
|
||||
return MessagePackBinary.Write<#= t.Name #>(ref bytes, offset, value);
|
||||
}
|
||||
|
||||
public <#= t.Name #> Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
|
||||
{
|
||||
return MessagePackBinary.Read<#= t.Name #>(bytes, offset, out readSize);
|
||||
}
|
||||
}
|
||||
|
||||
public class Nullable<#= t.Name #>Formatter : IMessagePackFormatter<<#= t.Name #>?>
|
||||
{
|
||||
public int Serialize(ref byte[] bytes, int offset, <#= t.Name #>? value, IFormatterResolver typeResolver)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return MessagePackBinary.WriteNil(ref bytes, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessagePackBinary.Write<#= t.Name #>(ref bytes, offset, value.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public <#= t.Name #>? Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
|
||||
{
|
||||
if (bytes[offset] == MessagePackCode.Nil)
|
||||
{
|
||||
readSize = 1;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessagePackBinary.Read<#= t.Name #>(bytes, offset, out readSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace T4Templates
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
|
||||
// アセンブリに関連付けられている情報を変更するには、
|
||||
// これらの属性値を変更してください。
|
||||
[assembly: AssemblyTitle("T4Templates")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("T4Templates")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから
|
||||
// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、
|
||||
// その型の ComVisible 属性を true に設定してください。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります
|
||||
[assembly: Guid("74108f4e-91fa-4d00-9246-2b627f271458")]
|
||||
|
||||
// アセンブリのバージョン情報は次の 4 つの値で構成されています:
|
||||
//
|
||||
// メジャー バージョン
|
||||
// マイナー バージョン
|
||||
// ビルド番号
|
||||
// Revision
|
||||
//
|
||||
// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます
|
||||
// 既定値にすることができます:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{74108F4E-91FA-4D00-9246-2B627F271458}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>T4Templates</RootNamespace>
|
||||
<AssemblyName>T4Templates</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PrimitiveFormatter.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>PrimitiveFormatter.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="PrimitiveFormatter.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>PrimitiveFormatter.cs</LastGenOutput>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.6.1</TargetFramework>
|
||||
<RootNamespace>MessagePack.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
|
||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170210-02" />
|
||||
<PackageReference Include="Microsoft.TestPlatform.TestHost" Version="15.0.0-preview-20170210-02" />
|
||||
<PackageReference Include="MsgPack.Cli" Version="0.9.0-beta2" />
|
||||
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
|
||||
<PackageReference Include="xunit" Version="2.2.0-rc1-build3507" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-rc1-build1247" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MessagePack\MessagePack.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace MessagePack.Tests
|
||||
{
|
||||
public class MessagePackBinaryTest
|
||||
{
|
||||
(MsgPack.Packer, MsgPack.Unpacker) CreateReference()
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
var packer = MsgPack.Packer.Create(ms, MsgPack.PackerCompatibilityOptions.None);
|
||||
var unpacker = MsgPack.Unpacker.Create(ms);
|
||||
return (packer, unpacker);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Binary()
|
||||
{
|
||||
(var packer, var unpacker) = CreateReference();
|
||||
|
||||
byte[] bytes = null;
|
||||
MessagePackBinary.WriteNil(ref bytes, 0).Is(1);
|
||||
|
||||
packer.PackNull().Position.Is(bytes.Length);
|
||||
unpacker.ReadItemData().AsBinary().SequenceEqual(bytes);
|
||||
|
||||
|
||||
|
||||
//const int offset = 33;
|
||||
//var bytes = new byte[100];
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteBoolean(ref bytes, offset, true).Is(1);
|
||||
//BinaryUtil.ReadBoolean(ref bytes, offset).IsTrue();
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteByte(ref bytes, offset, (byte)234).Is(1);
|
||||
//BinaryUtil.ReadByte(ref bytes, offset).Is((byte)234);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteChar(ref bytes, offset, 'z').Is(2);
|
||||
//BinaryUtil.ReadChar(ref bytes, offset).Is('z');
|
||||
|
||||
//bytes = new byte[100];
|
||||
//var now = DateTime.Now.ToUniversalTime();
|
||||
//BinaryUtil.WriteDateTime(ref bytes, offset, now).Is(12);
|
||||
//BinaryUtil.ReadDateTime(ref bytes, offset).Is(now);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteDecimal(ref bytes, offset, decimal.MaxValue).Is(16);
|
||||
//BinaryUtil.ReadDecimal(ref bytes, offset).Is(decimal.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteDouble(ref bytes, offset, double.MaxValue).Is(8);
|
||||
//BinaryUtil.ReadDouble(ref bytes, offset).Is(double.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteInt16(ref bytes, offset, short.MaxValue).Is(2);
|
||||
//BinaryUtil.ReadInt16(ref bytes, offset).Is(short.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteInt32(ref bytes, offset, int.MaxValue).Is(4);
|
||||
//BinaryUtil.ReadInt32(ref bytes, offset).Is(int.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteInt32Unsafe(ref bytes, offset, int.MaxValue);
|
||||
//BinaryUtil.ReadInt32(ref bytes, offset).Is(int.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteInt64(ref bytes, offset, long.MaxValue).Is(8);
|
||||
//BinaryUtil.ReadInt64(ref bytes, offset).Is(long.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteSByte(ref bytes, offset, sbyte.MaxValue).Is(1);
|
||||
//BinaryUtil.ReadSByte(ref bytes, offset).Is(sbyte.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteSingle(ref bytes, offset, Single.MaxValue).Is(4);
|
||||
//BinaryUtil.ReadSingle(ref bytes, offset).Is(Single.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//var c = BinaryUtil.WriteString(ref bytes, offset, "あいうえおかきくけこ");
|
||||
//BinaryUtil.ReadString(ref bytes, offset, c).Is("あいうえおかきくけこ");
|
||||
|
||||
//var ts = new TimeSpan(14, 213, 41241);
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteTimeSpan(ref bytes, offset, ts).Is(12);
|
||||
//BinaryUtil.ReadTimeSpan(ref bytes, offset).Is(ts);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteUInt16(ref bytes, offset, UInt16.MaxValue).Is(2);
|
||||
//BinaryUtil.ReadUInt16(ref bytes, offset).Is(UInt16.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteUInt32(ref bytes, offset, UInt32.MaxValue).Is(4);
|
||||
//BinaryUtil.ReadUInt32(ref bytes, offset).Is(UInt32.MaxValue);
|
||||
|
||||
//bytes = new byte[100];
|
||||
//BinaryUtil.WriteUInt64(ref bytes, offset, UInt64.MaxValue).Is(8);
|
||||
//BinaryUtil.ReadUInt64(ref bytes, offset).Is(UInt64.MaxValue);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Xunit;
|
||||
|
||||
namespace ZeroFormatter.DotNetCore.Tests
|
||||
{
|
||||
public static partial class AssertEx
|
||||
{
|
||||
public static void IsZero<T>(this IEnumerable<T> source)
|
||||
{
|
||||
source.Any().IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>Alternative of ExpectedExceptionAttribute(allow derived type)</summary>
|
||||
public static T Catch<T>(Action testCode, string message = "") where T : Exception
|
||||
{
|
||||
var exception = ExecuteCode(testCode);
|
||||
var headerMsg = "Failed Throws<" + typeof(T).Name + ">.";
|
||||
var additionalMsg = string.IsNullOrEmpty(message) ? "" : ", " + message;
|
||||
|
||||
if (exception == null)
|
||||
{
|
||||
var formatted = headerMsg + " No exception was thrown" + additionalMsg;
|
||||
throw new AssertFailedException(formatted);
|
||||
}
|
||||
else if (!typeof(T).GetTypeInfo().IsInstanceOfType(exception))
|
||||
{
|
||||
var formatted = string.Format("{0} Catched:{1}{2}", headerMsg, exception.GetType().Name, additionalMsg);
|
||||
throw new AssertFailedException(formatted);
|
||||
}
|
||||
|
||||
return (T)exception;
|
||||
}
|
||||
|
||||
public static T Throws<T>(Action testCode, string message = "") where T : Exception
|
||||
{
|
||||
var exception = Catch<T>(testCode, message);
|
||||
|
||||
if (!typeof(T).Equals(exception.GetType()))
|
||||
{
|
||||
var headerMsg = "Failed Throws<" + typeof(T).Name + ">.";
|
||||
var additionalMsg = string.IsNullOrEmpty(message) ? "" : ", " + message;
|
||||
var formatted = string.Format("{0} Catched:{1}{2}", headerMsg, exception.GetType().Name, additionalMsg);
|
||||
throw new AssertFailedException(formatted);
|
||||
}
|
||||
|
||||
return (T)exception;
|
||||
}
|
||||
|
||||
/// <summary>execute action and return exception when catched otherwise return null</summary>
|
||||
private static Exception ExecuteCode(Action testCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
testCode();
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,539 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
* Chaining Assertion
|
||||
* ver 1.7.1.0 (Apr. 29th, 2013)
|
||||
*
|
||||
* created and maintained by neuecc <ils@neue.cc - @neuecc on Twitter>
|
||||
* licensed under Microsoft Public License(Ms-PL)
|
||||
* http://chainingassertion.codeplex.com/
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
/* -- Tutorial --
|
||||
* | at first, include this file on xUnit.net Project.
|
||||
*
|
||||
* | three example, "Is" overloads.
|
||||
*
|
||||
* // This same as Assert.Equal(25, Math.Pow(5, 2))
|
||||
* Math.Pow(5, 2).Is(25);
|
||||
*
|
||||
* // This same as Assert.True("foobar".StartsWith("foo") && "foobar".EndWith("bar"))
|
||||
* "foobar".Is(s => s.StartsWith("foo") && s.EndsWith("bar"));
|
||||
*
|
||||
* // This same as Assert.Equal(Enumerable.Range(1,5).ToArray(), new[]{1, 2, 3, 4, 5}.ToArray())
|
||||
* // it is sequence value compare
|
||||
* Enumerable.Range(1, 5).Is(1, 2, 3, 4, 5);
|
||||
*
|
||||
* | CollectionAssert
|
||||
* | if you want to use CollectionAssert Methods then use Linq to Objects and Is
|
||||
*
|
||||
* var array = new[] { 1, 3, 7, 8 };
|
||||
* array.Count().Is(4);
|
||||
* array.Contains(8).IsTrue(); // IsTrue() == Is(true)
|
||||
* array.All(i => i < 5).IsFalse(); // IsFalse() == Is(false)
|
||||
* array.Any().Is(true);
|
||||
* new int[] { }.Any().Is(false); // IsEmpty
|
||||
* array.OrderBy(x => x).Is(array); // IsOrdered
|
||||
*
|
||||
* | Other Assertions
|
||||
*
|
||||
* // Null Assertions
|
||||
* Object obj = null;
|
||||
* obj.IsNull(); // Assert.Null(obj)
|
||||
* new Object().IsNotNull(); // Assert.NotNull(obj)
|
||||
*
|
||||
* // Not Assertion
|
||||
* "foobar".IsNot("fooooooo"); // Assert.NotEqual
|
||||
* new[] { "a", "z", "x" }.IsNot("a", "x", "z"); /// Assert.NotEqual
|
||||
*
|
||||
* // ReferenceEqual Assertion
|
||||
* var tuple = Tuple.Create("foo");
|
||||
* tuple.IsSameReferenceAs(tuple); // Assert.Same
|
||||
* tuple.IsNotSameReferenceAs(Tuple.Create("foo")); // Assert.NotSame
|
||||
*
|
||||
* // Type Assertion
|
||||
* "foobar".IsInstanceOf<string>(); // Assert.IsType
|
||||
* (999).IsNotInstanceOf<double>(); // Assert.IsNotType
|
||||
*
|
||||
* | Advanced Collection Assertion
|
||||
*
|
||||
* var lower = new[] { "a", "b", "c" };
|
||||
* var upper = new[] { "A", "B", "C" };
|
||||
*
|
||||
* // Comparer CollectionAssert, use IEqualityComparer<T> or Func<T,T,bool> delegate
|
||||
* lower.Is(upper, StringComparer.InvariantCultureIgnoreCase);
|
||||
* lower.Is(upper, (x, y) => x.ToUpper() == y.ToUpper());
|
||||
*
|
||||
* // or you can use Linq to Objects - SequenceEqual
|
||||
* lower.SequenceEqual(upper, StringComparer.InvariantCultureIgnoreCase).Is(true);
|
||||
*
|
||||
* | StructuralEqual
|
||||
*
|
||||
* class MyClass
|
||||
* {
|
||||
* public int IntProp { get; set; }
|
||||
* public string StrField;
|
||||
* }
|
||||
*
|
||||
* var mc1 = new MyClass() { IntProp = 10, StrField = "foo" };
|
||||
* var mc2 = new MyClass() { IntProp = 10, StrField = "foo" };
|
||||
*
|
||||
* mc1.IsStructuralEqual(mc2); // deep recursive value equality compare
|
||||
*
|
||||
* mc1.IntProp = 20;
|
||||
* mc1.IsNotStructuralEqual(mc2);
|
||||
*
|
||||
* | DynamicAccessor
|
||||
*
|
||||
* // AsDynamic convert to "dynamic" that can call private method/property/field/indexer.
|
||||
*
|
||||
* // a class and private field/property/method.
|
||||
* public class PrivateMock
|
||||
* {
|
||||
* private string privateField = "homu";
|
||||
*
|
||||
* private string PrivateProperty
|
||||
* {
|
||||
* get { return privateField + privateField; }
|
||||
* set { privateField = value; }
|
||||
* }
|
||||
*
|
||||
* private string PrivateMethod(int count)
|
||||
* {
|
||||
* return string.Join("", Enumerable.Repeat(privateField, count));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // call private property.
|
||||
* var actual = new PrivateMock().AsDynamic().PrivateProperty;
|
||||
* Assert.AreEqual("homuhomu", actual);
|
||||
*
|
||||
* // dynamic can't invoke extension methods.
|
||||
* // if you want to invoke "Is" then cast type.
|
||||
* (new PrivateMock().AsDynamic().PrivateMethod(3) as string).Is("homuhomuhomu");
|
||||
*
|
||||
* // set value
|
||||
* var mock = new PrivateMock().AsDynamic();
|
||||
* mock.PrivateProperty = "mogumogu";
|
||||
* (mock.privateField as string).Is("mogumogu");
|
||||
*
|
||||
* -- more details see project home --*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Xunit
|
||||
{
|
||||
#region Extensions
|
||||
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute]
|
||||
public static partial class AssertEx
|
||||
{
|
||||
/// <summary>Assert.Equal, if T is IEnumerable then compare value equality</summary>
|
||||
public static void Is<T>(this T actual, T expected)
|
||||
{
|
||||
if (typeof(T) != typeof(string) && typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
Assert.Equal(
|
||||
((IEnumerable)actual).Cast<object>().ToArray(),
|
||||
((IEnumerable)expected).Cast<object>().ToArray());
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.True(predicate(value))</summary>
|
||||
public static void Is<T>(this T value, Expression<Func<T, bool>> predicate, string message = "")
|
||||
{
|
||||
var condition = predicate.Compile().Invoke(value);
|
||||
|
||||
var paramName = predicate.Parameters.First().Name;
|
||||
string msg = "";
|
||||
try
|
||||
{
|
||||
var dumper = new ExpressionDumper<T>(value, predicate.Parameters.Single());
|
||||
dumper.Visit(predicate);
|
||||
var dump = string.Join(", ", dumper.Members.Select(kvp => kvp.Key + " = " + kvp.Value));
|
||||
msg = string.Format("\r\n{0} = {1}\r\n{2}\r\n{3}{4}",
|
||||
paramName, value, dump, predicate,
|
||||
string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
}
|
||||
catch
|
||||
{
|
||||
msg = string.Format("{0} = {1}, {2}{3}",
|
||||
paramName, value, predicate,
|
||||
string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
}
|
||||
|
||||
Assert.True(condition, msg);
|
||||
}
|
||||
|
||||
/// <summary>Assert.Equal</summary>
|
||||
public static void Is<T>(this T actual, T expected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.Equal(expected, actual, comparer);
|
||||
}
|
||||
|
||||
/// <summary>Assert.Equal(sequence value compare)</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, params T[] expected)
|
||||
{
|
||||
Is(actual, expected.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>Assert.Equal(sequence value compare)</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, IEnumerable<T> expected)
|
||||
{
|
||||
Assert.Equal(expected.ToArray(), actual.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>Assert.True(actual.SequenceEqual(expected, comparer))</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, IEnumerable<T> expected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.True(actual.SequenceEqual(expected, comparer));
|
||||
}
|
||||
|
||||
/// <summary>Assert.True(actual.SequenceEqual(expected, comparison))</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, IEnumerable<T> expected, Func<T, T, bool> equalityComparison)
|
||||
{
|
||||
Assert.True(actual.SequenceEqual(expected, new EqualityComparer<T>(equalityComparison)));
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual, if T is IEnumerable then check value equality</summary>
|
||||
public static void IsNot<T>(this T actual, T notExpected)
|
||||
{
|
||||
if (typeof(T) != typeof(string) && typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
Assert.NotEqual(
|
||||
((IEnumerable)actual).Cast<object>().ToArray(),
|
||||
((IEnumerable)notExpected).Cast<object>().ToArray());
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.NotEqual(notExpected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual</summary>
|
||||
public static void IsNot<T>(this T actual, T notExpected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.NotEqual(notExpected, actual, comparer);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual(sequence value compare)</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, params T[] notExpected)
|
||||
{
|
||||
IsNot(actual, notExpected.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual(sequence value compare)</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, IEnumerable<T> notExpected)
|
||||
{
|
||||
Assert.NotEqual(notExpected.ToArray(), actual.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>Assert.False(actual.SequenceEqual(notExpected, comparer))</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, IEnumerable<T> notExpected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.False(actual.SequenceEqual(notExpected, comparer));
|
||||
}
|
||||
|
||||
/// <summary>Assert.False(actual.SequenceEqual(notExpected, comparison))</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, IEnumerable<T> notExpected, Func<T, T, bool> equalityComparison)
|
||||
{
|
||||
Assert.False(actual.SequenceEqual(notExpected, new EqualityComparer<T>(equalityComparison)));
|
||||
}
|
||||
|
||||
/// <summary>Assert.Null</summary>
|
||||
public static void IsNull<T>(this T value)
|
||||
{
|
||||
Assert.Null(value);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotNull</summary>
|
||||
public static void IsNotNull<T>(this T value)
|
||||
{
|
||||
Assert.NotNull(value);
|
||||
}
|
||||
|
||||
/// <summary>Is(true)</summary>
|
||||
public static void IsTrue(this bool value)
|
||||
{
|
||||
value.Is(true);
|
||||
}
|
||||
|
||||
/// <summary>Is(false)</summary>
|
||||
public static void IsFalse(this bool value)
|
||||
{
|
||||
value.Is(false);
|
||||
}
|
||||
|
||||
/// <summary>Assert.Same</summary>
|
||||
public static void IsSameReferenceAs<T>(this T actual, T expected)
|
||||
{
|
||||
Assert.Same(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotSame</summary>
|
||||
public static void IsNotSameReferenceAs<T>(this T actual, T notExpected)
|
||||
{
|
||||
Assert.NotSame(notExpected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.IsType</summary>
|
||||
public static TExpected IsInstanceOf<TExpected>(this object value)
|
||||
{
|
||||
Assert.IsType<TExpected>(value);
|
||||
return (TExpected)value;
|
||||
}
|
||||
|
||||
/// <summary>Assert.IsNotType</summary>
|
||||
public static void IsNotInstanceOf<TWrong>(this object value)
|
||||
{
|
||||
Assert.IsNotType<TWrong>(value);
|
||||
}
|
||||
|
||||
/// <summary>EqualityComparison to IEqualityComparer Converter for CollectionAssert</summary>
|
||||
private class EqualityComparer<T> : IEqualityComparer<T>
|
||||
{
|
||||
readonly Func<T, T, bool> comparison;
|
||||
|
||||
public EqualityComparer(Func<T, T, bool> comparison)
|
||||
{
|
||||
this.comparison = comparison;
|
||||
}
|
||||
|
||||
|
||||
public bool Equals(T x, T y)
|
||||
{
|
||||
return (comparison != null)
|
||||
? comparison(x, y)
|
||||
: object.Equals(x, y);
|
||||
}
|
||||
|
||||
public int GetHashCode(T obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private class ReflectAccessor<T>
|
||||
{
|
||||
public Func<object> GetValue { get; private set; }
|
||||
public Action<object> SetValue { get; private set; }
|
||||
|
||||
public ReflectAccessor(T target, string name)
|
||||
{
|
||||
var field = typeof(T).GetTypeInfo().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (field != null)
|
||||
{
|
||||
GetValue = () => field.GetValue(target);
|
||||
SetValue = value => field.SetValue(target, value);
|
||||
return;
|
||||
}
|
||||
|
||||
var prop = typeof(T).GetTypeInfo().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (prop != null)
|
||||
{
|
||||
GetValue = () => prop.GetValue(target, null);
|
||||
SetValue = value => prop.SetValue(target, value, null);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ArgumentException(string.Format("\"{0}\" not found : Type <{1}>", name, typeof(T).Name));
|
||||
}
|
||||
}
|
||||
|
||||
#region StructuralEqual
|
||||
|
||||
/// <summary>Assert by deep recursive value equality compare</summary>
|
||||
public static void IsStructuralEqual(this object actual, object expected, string message = "")
|
||||
{
|
||||
message = (string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
if (object.ReferenceEquals(actual, expected)) return;
|
||||
|
||||
if (actual == null) throw new AssertException("actual is null" + message);
|
||||
if (expected == null) throw new AssertException("actual is not null" + message);
|
||||
if (actual.GetType() != expected.GetType())
|
||||
{
|
||||
var msg = string.Format("expected type is {0} but actual type is {1}{2}",
|
||||
expected.GetType().Name, actual.GetType().Name, message);
|
||||
throw new AssertException(msg);
|
||||
}
|
||||
|
||||
var r = StructuralEqual(actual, expected, new[] { actual.GetType().Name }); // root type
|
||||
if (!r.IsEquals)
|
||||
{
|
||||
var msg = string.Format("is not structural equal, failed at {0}, actual = {1} expected = {2}{3}",
|
||||
string.Join(".", r.Names), r.Left, r.Right, message);
|
||||
throw new AssertException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Assert by deep recursive value equality compare</summary>
|
||||
public static void IsNotStructuralEqual(this object actual, object expected, string message = "")
|
||||
{
|
||||
message = (string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
if (object.ReferenceEquals(actual, expected)) throw new AssertException("actual is same reference" + message); ;
|
||||
|
||||
if (actual == null) return;
|
||||
if (expected == null) return;
|
||||
if (actual.GetType() != expected.GetType())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var r = StructuralEqual(actual, expected, new[] { actual.GetType().Name }); // root type
|
||||
if (r.IsEquals)
|
||||
{
|
||||
throw new AssertException("is structural equal" + message);
|
||||
}
|
||||
}
|
||||
|
||||
static EqualInfo SequenceEqual(IEnumerable leftEnumerable, IEnumerable rightEnumarable, IEnumerable<string> names)
|
||||
{
|
||||
var le = leftEnumerable.GetEnumerator();
|
||||
using (le as IDisposable)
|
||||
{
|
||||
var re = rightEnumarable.GetEnumerator();
|
||||
|
||||
using (re as IDisposable)
|
||||
{
|
||||
var index = 0;
|
||||
while (true)
|
||||
{
|
||||
object lValue = null;
|
||||
object rValue = null;
|
||||
var lMove = le.MoveNext();
|
||||
var rMove = re.MoveNext();
|
||||
if (lMove) lValue = le.Current;
|
||||
if (rMove) rValue = re.Current;
|
||||
|
||||
if (lMove && rMove)
|
||||
{
|
||||
var result = StructuralEqual(lValue, rValue, names.Concat(new[] { "[" + index + "]" }));
|
||||
if (!result.IsEquals)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if ((lMove == true && rMove == false) || (lMove == false && rMove == true))
|
||||
{
|
||||
return new EqualInfo { IsEquals = false, Left = lValue, Right = rValue, Names = names.Concat(new[] { "[" + index + "]" }) };
|
||||
}
|
||||
if (lMove == false && rMove == false) break;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new EqualInfo { IsEquals = true, Left = leftEnumerable, Right = rightEnumarable, Names = names };
|
||||
}
|
||||
|
||||
static EqualInfo StructuralEqual(object left, object right, IEnumerable<string> names)
|
||||
{
|
||||
// type and basic checks
|
||||
if (object.ReferenceEquals(left, right)) return new EqualInfo { IsEquals = true, Left = left, Right = right, Names = names };
|
||||
if (left == null || right == null) return new EqualInfo { IsEquals = false, Left = left, Right = right, Names = names };
|
||||
var lType = left.GetType();
|
||||
var rType = right.GetType();
|
||||
if (lType != rType) return new EqualInfo { IsEquals = false, Left = left, Right = right, Names = names };
|
||||
|
||||
var type = left.GetType();
|
||||
|
||||
// not object(int, string, etc...)
|
||||
if (Type.GetTypeCode(type) != TypeCode.Object)
|
||||
{
|
||||
return new EqualInfo { IsEquals = left.Equals(right), Left = left, Right = right, Names = names };
|
||||
}
|
||||
|
||||
// is sequence
|
||||
if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(type))
|
||||
{
|
||||
return SequenceEqual((IEnumerable)left, (IEnumerable)right, names);
|
||||
}
|
||||
|
||||
// IEquatable<T>
|
||||
var equatable = typeof(IEquatable<>).MakeGenericType(type);
|
||||
if (equatable.GetTypeInfo().IsAssignableFrom(type))
|
||||
{
|
||||
var result = (bool)equatable.GetTypeInfo().GetMethod("Equals").Invoke(left, new[] { right });
|
||||
return new EqualInfo { IsEquals = result, Left = left, Right = right, Names = names };
|
||||
}
|
||||
|
||||
// is object
|
||||
var fields = left.GetType().GetTypeInfo().GetFields(BindingFlags.Instance | BindingFlags.Public);
|
||||
var properties = left.GetType().GetTypeInfo().GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => x.GetGetMethod(false) != null);
|
||||
var members = fields.Cast<MemberInfo>().Concat(properties);
|
||||
|
||||
foreach (dynamic mi in fields.Cast<MemberInfo>().Concat(properties))
|
||||
{
|
||||
var concatNames = names.Concat(new[] { (string)mi.Name });
|
||||
|
||||
object lv = mi.GetValue(left);
|
||||
object rv = mi.GetValue(right);
|
||||
var result = StructuralEqual(lv, rv, concatNames);
|
||||
if (!result.IsEquals)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return new EqualInfo { IsEquals = true, Left = left, Right = right, Names = names };
|
||||
}
|
||||
|
||||
private class EqualInfo
|
||||
{
|
||||
public object Left;
|
||||
public object Right;
|
||||
public bool IsEquals;
|
||||
public IEnumerable<string> Names;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ExpressionDumper
|
||||
|
||||
private class ExpressionDumper<T> : ExpressionVisitor
|
||||
{
|
||||
ParameterExpression param;
|
||||
T target;
|
||||
|
||||
public Dictionary<string, object> Members { get; private set; }
|
||||
|
||||
public ExpressionDumper(T target, ParameterExpression param)
|
||||
{
|
||||
this.target = target;
|
||||
this.param = param;
|
||||
this.Members = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
protected override System.Linq.Expressions.Expression VisitMember(MemberExpression node)
|
||||
{
|
||||
if (node.Expression == param && !Members.ContainsKey(node.Member.Name))
|
||||
{
|
||||
var accessor = new ReflectAccessor<T>(target, node.Member.Name);
|
||||
Members.Add(node.Member.Name, accessor.GetValue());
|
||||
}
|
||||
|
||||
return base.VisitMember(node);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public class AssertException : Exception
|
||||
{
|
||||
public AssertException(string message) : base(message) { }
|
||||
}
|
||||
|
||||
public class AssertFailedException : Exception
|
||||
{
|
||||
public AssertFailedException(string message) : base(message) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\xunit.runner.visualstudio.2.2.0-rc1-build1247\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.2.2.0-rc1-build1247\build\net20\xunit.runner.visualstudio.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{9E1A55CA-711D-4F58-A332-735960E3434C}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MessagePack.Tests</RootNamespace>
|
||||
<AssemblyName>MessagePack.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="MsgPack, Version=0.9.0.0, Culture=neutral, PublicKeyToken=a2625990d5dc0167, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\MsgPack.Cli.0.9.0-beta2\lib\net46\MsgPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.assert, Version=2.2.0.3507, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\xunit.assert.2.2.0-rc1-build3507\lib\netstandard1.1\xunit.assert.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.core, Version=2.2.0.3507, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\xunit.extensibility.core.2.2.0-rc1-build3507\lib\netstandard1.1\xunit.core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.execution.desktop, Version=2.2.0.3507, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\xunit.extensibility.execution.2.2.0-rc1-build3507\lib\net452\xunit.execution.desktop.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MessagePackBinaryTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utils\ChainingAssertion.Ext.cs" />
|
||||
<Compile Include="Utils\ChainingAssertion.Xunit.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MessagePack\MessagePack.csproj">
|
||||
<Project>{7abb33ee-a2f1-492b-8daf-5df89f0f0b79}</Project>
|
||||
<Name>MessagePack</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>このプロジェクトは、このコンピューター上にない NuGet パッケージを参照しています。それらのパッケージをダウンロードするには、[NuGet パッケージの復元] を使用します。詳細については、http://go.microsoft.com/fwlink/?LinkID=322105 を参照してください。見つからないファイルは {0} です。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.2.0-rc1-build1247\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.2.0-rc1-build1247\build\net20\xunit.runner.visualstudio.props'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace MessagePack.Tests
|
||||
{
|
||||
public class MessagePackBinaryTest
|
||||
{
|
||||
(MemoryStream, MsgPack.Packer) CreateReferencePacker()
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
var packer = MsgPack.Packer.Create(ms, MsgPack.PackerCompatibilityOptions.None);
|
||||
return (ms, packer);
|
||||
}
|
||||
|
||||
MsgPack.MessagePackObject CreateUnpackedReference(byte[] bytes)
|
||||
{
|
||||
var ms = new MemoryStream(bytes);
|
||||
var unpacker = MsgPack.Unpacker.Create(ms);
|
||||
unpacker.Read();
|
||||
return unpacker.LastReadData;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NilTest()
|
||||
{
|
||||
(var stream, var packer) = CreateReferencePacker();
|
||||
|
||||
byte[] bytes = null;
|
||||
MessagePackBinary.WriteNil(ref bytes, 0).Is(1);
|
||||
|
||||
packer.PackNull().Position.Is(bytes.Length);
|
||||
stream.ToArray().SequenceEqual(bytes);
|
||||
|
||||
int readSize;
|
||||
MessagePackBinary.ReadNil(bytes, 0, out readSize).Is(Nil.Default);
|
||||
readSize.Is(1);
|
||||
|
||||
CreateUnpackedReference(bytes).IsNil.IsTrue();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, 1)]
|
||||
[InlineData(false, 1)]
|
||||
public void BoolTest(bool target, int length)
|
||||
{
|
||||
(var stream, var packer) = CreateReferencePacker();
|
||||
|
||||
byte[] bytes = null;
|
||||
MessagePackBinary.WriteBoolean(ref bytes, 0, target).Is(length);
|
||||
|
||||
packer.Pack(target).Position.Is(bytes.Length);
|
||||
stream.ToArray().SequenceEqual(bytes);
|
||||
|
||||
int readSize;
|
||||
MessagePackBinary.ReadBoolean(bytes, 0, out readSize).Is(target);
|
||||
readSize.Is(length);
|
||||
|
||||
CreateUnpackedReference(bytes).AsBoolean().Is(target);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(byte.MinValue, 1)]
|
||||
[InlineData(111, 1)]
|
||||
[InlineData(136, 2)]
|
||||
[InlineData(byte.MaxValue, 2)]
|
||||
public void ByteTest(byte target, int length)
|
||||
{
|
||||
(var stream, var packer) = CreateReferencePacker();
|
||||
|
||||
byte[] bytes = null;
|
||||
MessagePackBinary.WriteByte(ref bytes, 0, target).Is(length);
|
||||
|
||||
packer.Pack(target).Position.Is(bytes.Length);
|
||||
stream.ToArray().SequenceEqual(bytes);
|
||||
|
||||
int readSize;
|
||||
MessagePackBinary.ReadByte(bytes, 0, out readSize).Is(target);
|
||||
readSize.Is(length);
|
||||
|
||||
CreateUnpackedReference(bytes).AsByte().Is(target);
|
||||
}
|
||||
|
||||
public static object[] bytesTestData = new object[]
|
||||
{
|
||||
new object[]{ (byte[])null, 1 },
|
||||
new object[]{ new byte[] { }, 2 },
|
||||
new object[]{ new byte[] { 1, 2, 3 }, 5 },
|
||||
new object[]{ Enumerable.Repeat((byte)100, byte.MaxValue).ToArray(), 255 + 2 },
|
||||
new object[]{ Enumerable.Repeat((byte)100, UInt16.MaxValue).ToArray(), 65535 + 3 },
|
||||
new object[]{ Enumerable.Repeat((byte)100, 99999).ToArray(), 99999 + 5 },
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(bytesTestData))]
|
||||
public void BytesTest(byte[] target, int length)
|
||||
{
|
||||
(var stream, var packer) = CreateReferencePacker();
|
||||
|
||||
byte[] bytes = null;
|
||||
MessagePackBinary.WriteBytes(ref bytes, 0, target).Is(length);
|
||||
|
||||
packer.PackBinary(target).Position.Is(bytes.Length);
|
||||
stream.ToArray().SequenceEqual(bytes);
|
||||
|
||||
int readSize;
|
||||
MessagePackBinary.ReadBytes(bytes, 0, out readSize).Is(target);
|
||||
readSize.Is(length);
|
||||
|
||||
CreateUnpackedReference(bytes).AsBinary().Is(target);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("MessagePack.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MessagePack.Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: Guid("9e1a55ca-711d-4f58-a332-735960e3434c")]
|
||||
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Xunit;
|
||||
|
||||
namespace ZeroFormatter.DotNetCore.Tests
|
||||
{
|
||||
public static partial class AssertEx
|
||||
{
|
||||
public static void IsZero<T>(this IEnumerable<T> source)
|
||||
{
|
||||
source.Any().IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>Alternative of ExpectedExceptionAttribute(allow derived type)</summary>
|
||||
public static T Catch<T>(Action testCode, string message = "") where T : Exception
|
||||
{
|
||||
var exception = ExecuteCode(testCode);
|
||||
var headerMsg = "Failed Throws<" + typeof(T).Name + ">.";
|
||||
var additionalMsg = string.IsNullOrEmpty(message) ? "" : ", " + message;
|
||||
|
||||
if (exception == null)
|
||||
{
|
||||
var formatted = headerMsg + " No exception was thrown" + additionalMsg;
|
||||
throw new AssertFailedException(formatted);
|
||||
}
|
||||
else if (!typeof(T).GetTypeInfo().IsInstanceOfType(exception))
|
||||
{
|
||||
var formatted = string.Format("{0} Catched:{1}{2}", headerMsg, exception.GetType().Name, additionalMsg);
|
||||
throw new AssertFailedException(formatted);
|
||||
}
|
||||
|
||||
return (T)exception;
|
||||
}
|
||||
|
||||
public static T Throws<T>(Action testCode, string message = "") where T : Exception
|
||||
{
|
||||
var exception = Catch<T>(testCode, message);
|
||||
|
||||
if (!typeof(T).Equals(exception.GetType()))
|
||||
{
|
||||
var headerMsg = "Failed Throws<" + typeof(T).Name + ">.";
|
||||
var additionalMsg = string.IsNullOrEmpty(message) ? "" : ", " + message;
|
||||
var formatted = string.Format("{0} Catched:{1}{2}", headerMsg, exception.GetType().Name, additionalMsg);
|
||||
throw new AssertFailedException(formatted);
|
||||
}
|
||||
|
||||
return (T)exception;
|
||||
}
|
||||
|
||||
/// <summary>execute action and return exception when catched otherwise return null</summary>
|
||||
private static Exception ExecuteCode(Action testCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
testCode();
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,545 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
* Chaining Assertion
|
||||
* ver 1.7.1.0 (Apr. 29th, 2013)
|
||||
*
|
||||
* created and maintained by neuecc <ils@neue.cc - @neuecc on Twitter>
|
||||
* licensed under Microsoft Public License(Ms-PL)
|
||||
* http://chainingassertion.codeplex.com/
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
/* -- Tutorial --
|
||||
* | at first, include this file on xUnit.net Project.
|
||||
*
|
||||
* | three example, "Is" overloads.
|
||||
*
|
||||
* // This same as Assert.Equal(25, Math.Pow(5, 2))
|
||||
* Math.Pow(5, 2).Is(25);
|
||||
*
|
||||
* // This same as Assert.True("foobar".StartsWith("foo") && "foobar".EndWith("bar"))
|
||||
* "foobar".Is(s => s.StartsWith("foo") && s.EndsWith("bar"));
|
||||
*
|
||||
* // This same as Assert.Equal(Enumerable.Range(1,5).ToArray(), new[]{1, 2, 3, 4, 5}.ToArray())
|
||||
* // it is sequence value compare
|
||||
* Enumerable.Range(1, 5).Is(1, 2, 3, 4, 5);
|
||||
*
|
||||
* | CollectionAssert
|
||||
* | if you want to use CollectionAssert Methods then use Linq to Objects and Is
|
||||
*
|
||||
* var array = new[] { 1, 3, 7, 8 };
|
||||
* array.Count().Is(4);
|
||||
* array.Contains(8).IsTrue(); // IsTrue() == Is(true)
|
||||
* array.All(i => i < 5).IsFalse(); // IsFalse() == Is(false)
|
||||
* array.Any().Is(true);
|
||||
* new int[] { }.Any().Is(false); // IsEmpty
|
||||
* array.OrderBy(x => x).Is(array); // IsOrdered
|
||||
*
|
||||
* | Other Assertions
|
||||
*
|
||||
* // Null Assertions
|
||||
* Object obj = null;
|
||||
* obj.IsNull(); // Assert.Null(obj)
|
||||
* new Object().IsNotNull(); // Assert.NotNull(obj)
|
||||
*
|
||||
* // Not Assertion
|
||||
* "foobar".IsNot("fooooooo"); // Assert.NotEqual
|
||||
* new[] { "a", "z", "x" }.IsNot("a", "x", "z"); /// Assert.NotEqual
|
||||
*
|
||||
* // ReferenceEqual Assertion
|
||||
* var tuple = Tuple.Create("foo");
|
||||
* tuple.IsSameReferenceAs(tuple); // Assert.Same
|
||||
* tuple.IsNotSameReferenceAs(Tuple.Create("foo")); // Assert.NotSame
|
||||
*
|
||||
* // Type Assertion
|
||||
* "foobar".IsInstanceOf<string>(); // Assert.IsType
|
||||
* (999).IsNotInstanceOf<double>(); // Assert.IsNotType
|
||||
*
|
||||
* | Advanced Collection Assertion
|
||||
*
|
||||
* var lower = new[] { "a", "b", "c" };
|
||||
* var upper = new[] { "A", "B", "C" };
|
||||
*
|
||||
* // Comparer CollectionAssert, use IEqualityComparer<T> or Func<T,T,bool> delegate
|
||||
* lower.Is(upper, StringComparer.InvariantCultureIgnoreCase);
|
||||
* lower.Is(upper, (x, y) => x.ToUpper() == y.ToUpper());
|
||||
*
|
||||
* // or you can use Linq to Objects - SequenceEqual
|
||||
* lower.SequenceEqual(upper, StringComparer.InvariantCultureIgnoreCase).Is(true);
|
||||
*
|
||||
* | StructuralEqual
|
||||
*
|
||||
* class MyClass
|
||||
* {
|
||||
* public int IntProp { get; set; }
|
||||
* public string StrField;
|
||||
* }
|
||||
*
|
||||
* var mc1 = new MyClass() { IntProp = 10, StrField = "foo" };
|
||||
* var mc2 = new MyClass() { IntProp = 10, StrField = "foo" };
|
||||
*
|
||||
* mc1.IsStructuralEqual(mc2); // deep recursive value equality compare
|
||||
*
|
||||
* mc1.IntProp = 20;
|
||||
* mc1.IsNotStructuralEqual(mc2);
|
||||
*
|
||||
* | DynamicAccessor
|
||||
*
|
||||
* // AsDynamic convert to "dynamic" that can call private method/property/field/indexer.
|
||||
*
|
||||
* // a class and private field/property/method.
|
||||
* public class PrivateMock
|
||||
* {
|
||||
* private string privateField = "homu";
|
||||
*
|
||||
* private string PrivateProperty
|
||||
* {
|
||||
* get { return privateField + privateField; }
|
||||
* set { privateField = value; }
|
||||
* }
|
||||
*
|
||||
* private string PrivateMethod(int count)
|
||||
* {
|
||||
* return string.Join("", Enumerable.Repeat(privateField, count));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // call private property.
|
||||
* var actual = new PrivateMock().AsDynamic().PrivateProperty;
|
||||
* Assert.AreEqual("homuhomu", actual);
|
||||
*
|
||||
* // dynamic can't invoke extension methods.
|
||||
* // if you want to invoke "Is" then cast type.
|
||||
* (new PrivateMock().AsDynamic().PrivateMethod(3) as string).Is("homuhomuhomu");
|
||||
*
|
||||
* // set value
|
||||
* var mock = new PrivateMock().AsDynamic();
|
||||
* mock.PrivateProperty = "mogumogu";
|
||||
* (mock.privateField as string).Is("mogumogu");
|
||||
*
|
||||
* -- more details see project home --*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Xunit
|
||||
{
|
||||
#region Extensions
|
||||
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute]
|
||||
public static partial class AssertEx
|
||||
{
|
||||
/// <summary>Assert.Equal, if T is IEnumerable then compare value equality</summary>
|
||||
public static void Is<T>(this T actual, T expected)
|
||||
{
|
||||
if (expected == null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof(T) != typeof(string) && typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
Assert.Equal(
|
||||
((IEnumerable)actual).Cast<object>().ToArray(),
|
||||
((IEnumerable)expected).Cast<object>().ToArray());
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.True(predicate(value))</summary>
|
||||
public static void Is<T>(this T value, Expression<Func<T, bool>> predicate, string message = "")
|
||||
{
|
||||
var condition = predicate.Compile().Invoke(value);
|
||||
|
||||
var paramName = predicate.Parameters.First().Name;
|
||||
string msg = "";
|
||||
try
|
||||
{
|
||||
var dumper = new ExpressionDumper<T>(value, predicate.Parameters.Single());
|
||||
dumper.Visit(predicate);
|
||||
var dump = string.Join(", ", dumper.Members.Select(kvp => kvp.Key + " = " + kvp.Value));
|
||||
msg = string.Format("\r\n{0} = {1}\r\n{2}\r\n{3}{4}",
|
||||
paramName, value, dump, predicate,
|
||||
string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
}
|
||||
catch
|
||||
{
|
||||
msg = string.Format("{0} = {1}, {2}{3}",
|
||||
paramName, value, predicate,
|
||||
string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
}
|
||||
|
||||
Assert.True(condition, msg);
|
||||
}
|
||||
|
||||
/// <summary>Assert.Equal</summary>
|
||||
public static void Is<T>(this T actual, T expected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.Equal(expected, actual, comparer);
|
||||
}
|
||||
|
||||
/// <summary>Assert.Equal(sequence value compare)</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, params T[] expected)
|
||||
{
|
||||
Is(actual, expected.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>Assert.Equal(sequence value compare)</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, IEnumerable<T> expected)
|
||||
{
|
||||
Assert.Equal(expected.ToArray(), actual.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>Assert.True(actual.SequenceEqual(expected, comparer))</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, IEnumerable<T> expected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.True(actual.SequenceEqual(expected, comparer));
|
||||
}
|
||||
|
||||
/// <summary>Assert.True(actual.SequenceEqual(expected, comparison))</summary>
|
||||
public static void Is<T>(this IEnumerable<T> actual, IEnumerable<T> expected, Func<T, T, bool> equalityComparison)
|
||||
{
|
||||
Assert.True(actual.SequenceEqual(expected, new EqualityComparer<T>(equalityComparison)));
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual, if T is IEnumerable then check value equality</summary>
|
||||
public static void IsNot<T>(this T actual, T notExpected)
|
||||
{
|
||||
if (typeof(T) != typeof(string) && typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
Assert.NotEqual(
|
||||
((IEnumerable)actual).Cast<object>().ToArray(),
|
||||
((IEnumerable)notExpected).Cast<object>().ToArray());
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.NotEqual(notExpected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual</summary>
|
||||
public static void IsNot<T>(this T actual, T notExpected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.NotEqual(notExpected, actual, comparer);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual(sequence value compare)</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, params T[] notExpected)
|
||||
{
|
||||
IsNot(actual, notExpected.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotEqual(sequence value compare)</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, IEnumerable<T> notExpected)
|
||||
{
|
||||
Assert.NotEqual(notExpected.ToArray(), actual.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>Assert.False(actual.SequenceEqual(notExpected, comparer))</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, IEnumerable<T> notExpected, IEqualityComparer<T> comparer)
|
||||
{
|
||||
Assert.False(actual.SequenceEqual(notExpected, comparer));
|
||||
}
|
||||
|
||||
/// <summary>Assert.False(actual.SequenceEqual(notExpected, comparison))</summary>
|
||||
public static void IsNot<T>(this IEnumerable<T> actual, IEnumerable<T> notExpected, Func<T, T, bool> equalityComparison)
|
||||
{
|
||||
Assert.False(actual.SequenceEqual(notExpected, new EqualityComparer<T>(equalityComparison)));
|
||||
}
|
||||
|
||||
/// <summary>Assert.Null</summary>
|
||||
public static void IsNull<T>(this T value)
|
||||
{
|
||||
Assert.Null(value);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotNull</summary>
|
||||
public static void IsNotNull<T>(this T value)
|
||||
{
|
||||
Assert.NotNull(value);
|
||||
}
|
||||
|
||||
/// <summary>Is(true)</summary>
|
||||
public static void IsTrue(this bool value)
|
||||
{
|
||||
value.Is(true);
|
||||
}
|
||||
|
||||
/// <summary>Is(false)</summary>
|
||||
public static void IsFalse(this bool value)
|
||||
{
|
||||
value.Is(false);
|
||||
}
|
||||
|
||||
/// <summary>Assert.Same</summary>
|
||||
public static void IsSameReferenceAs<T>(this T actual, T expected)
|
||||
{
|
||||
Assert.Same(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.NotSame</summary>
|
||||
public static void IsNotSameReferenceAs<T>(this T actual, T notExpected)
|
||||
{
|
||||
Assert.NotSame(notExpected, actual);
|
||||
}
|
||||
|
||||
/// <summary>Assert.IsType</summary>
|
||||
public static TExpected IsInstanceOf<TExpected>(this object value)
|
||||
{
|
||||
Assert.IsType<TExpected>(value);
|
||||
return (TExpected)value;
|
||||
}
|
||||
|
||||
/// <summary>Assert.IsNotType</summary>
|
||||
public static void IsNotInstanceOf<TWrong>(this object value)
|
||||
{
|
||||
Assert.IsNotType<TWrong>(value);
|
||||
}
|
||||
|
||||
/// <summary>EqualityComparison to IEqualityComparer Converter for CollectionAssert</summary>
|
||||
private class EqualityComparer<T> : IEqualityComparer<T>
|
||||
{
|
||||
readonly Func<T, T, bool> comparison;
|
||||
|
||||
public EqualityComparer(Func<T, T, bool> comparison)
|
||||
{
|
||||
this.comparison = comparison;
|
||||
}
|
||||
|
||||
|
||||
public bool Equals(T x, T y)
|
||||
{
|
||||
return (comparison != null)
|
||||
? comparison(x, y)
|
||||
: object.Equals(x, y);
|
||||
}
|
||||
|
||||
public int GetHashCode(T obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private class ReflectAccessor<T>
|
||||
{
|
||||
public Func<object> GetValue { get; private set; }
|
||||
public Action<object> SetValue { get; private set; }
|
||||
|
||||
public ReflectAccessor(T target, string name)
|
||||
{
|
||||
var field = typeof(T).GetTypeInfo().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (field != null)
|
||||
{
|
||||
GetValue = () => field.GetValue(target);
|
||||
SetValue = value => field.SetValue(target, value);
|
||||
return;
|
||||
}
|
||||
|
||||
var prop = typeof(T).GetTypeInfo().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (prop != null)
|
||||
{
|
||||
GetValue = () => prop.GetValue(target, null);
|
||||
SetValue = value => prop.SetValue(target, value, null);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ArgumentException(string.Format("\"{0}\" not found : Type <{1}>", name, typeof(T).Name));
|
||||
}
|
||||
}
|
||||
|
||||
#region StructuralEqual
|
||||
|
||||
/// <summary>Assert by deep recursive value equality compare</summary>
|
||||
public static void IsStructuralEqual(this object actual, object expected, string message = "")
|
||||
{
|
||||
message = (string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
if (object.ReferenceEquals(actual, expected)) return;
|
||||
|
||||
if (actual == null) throw new AssertException("actual is null" + message);
|
||||
if (expected == null) throw new AssertException("actual is not null" + message);
|
||||
if (actual.GetType() != expected.GetType())
|
||||
{
|
||||
var msg = string.Format("expected type is {0} but actual type is {1}{2}",
|
||||
expected.GetType().Name, actual.GetType().Name, message);
|
||||
throw new AssertException(msg);
|
||||
}
|
||||
|
||||
var r = StructuralEqual(actual, expected, new[] { actual.GetType().Name }); // root type
|
||||
if (!r.IsEquals)
|
||||
{
|
||||
var msg = string.Format("is not structural equal, failed at {0}, actual = {1} expected = {2}{3}",
|
||||
string.Join(".", r.Names), r.Left, r.Right, message);
|
||||
throw new AssertException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Assert by deep recursive value equality compare</summary>
|
||||
public static void IsNotStructuralEqual(this object actual, object expected, string message = "")
|
||||
{
|
||||
message = (string.IsNullOrEmpty(message) ? "" : ", " + message);
|
||||
if (object.ReferenceEquals(actual, expected)) throw new AssertException("actual is same reference" + message); ;
|
||||
|
||||
if (actual == null) return;
|
||||
if (expected == null) return;
|
||||
if (actual.GetType() != expected.GetType())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var r = StructuralEqual(actual, expected, new[] { actual.GetType().Name }); // root type
|
||||
if (r.IsEquals)
|
||||
{
|
||||
throw new AssertException("is structural equal" + message);
|
||||
}
|
||||
}
|
||||
|
||||
static EqualInfo SequenceEqual(IEnumerable leftEnumerable, IEnumerable rightEnumarable, IEnumerable<string> names)
|
||||
{
|
||||
var le = leftEnumerable.GetEnumerator();
|
||||
using (le as IDisposable)
|
||||
{
|
||||
var re = rightEnumarable.GetEnumerator();
|
||||
|
||||
using (re as IDisposable)
|
||||
{
|
||||
var index = 0;
|
||||
while (true)
|
||||
{
|
||||
object lValue = null;
|
||||
object rValue = null;
|
||||
var lMove = le.MoveNext();
|
||||
var rMove = re.MoveNext();
|
||||
if (lMove) lValue = le.Current;
|
||||
if (rMove) rValue = re.Current;
|
||||
|
||||
if (lMove && rMove)
|
||||
{
|
||||
var result = StructuralEqual(lValue, rValue, names.Concat(new[] { "[" + index + "]" }));
|
||||
if (!result.IsEquals)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if ((lMove == true && rMove == false) || (lMove == false && rMove == true))
|
||||
{
|
||||
return new EqualInfo { IsEquals = false, Left = lValue, Right = rValue, Names = names.Concat(new[] { "[" + index + "]" }) };
|
||||
}
|
||||
if (lMove == false && rMove == false) break;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new EqualInfo { IsEquals = true, Left = leftEnumerable, Right = rightEnumarable, Names = names };
|
||||
}
|
||||
|
||||
static EqualInfo StructuralEqual(object left, object right, IEnumerable<string> names)
|
||||
{
|
||||
// type and basic checks
|
||||
if (object.ReferenceEquals(left, right)) return new EqualInfo { IsEquals = true, Left = left, Right = right, Names = names };
|
||||
if (left == null || right == null) return new EqualInfo { IsEquals = false, Left = left, Right = right, Names = names };
|
||||
var lType = left.GetType();
|
||||
var rType = right.GetType();
|
||||
if (lType != rType) return new EqualInfo { IsEquals = false, Left = left, Right = right, Names = names };
|
||||
|
||||
var type = left.GetType();
|
||||
|
||||
// not object(int, string, etc...)
|
||||
if (Type.GetTypeCode(type) != TypeCode.Object)
|
||||
{
|
||||
return new EqualInfo { IsEquals = left.Equals(right), Left = left, Right = right, Names = names };
|
||||
}
|
||||
|
||||
// is sequence
|
||||
if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(type))
|
||||
{
|
||||
return SequenceEqual((IEnumerable)left, (IEnumerable)right, names);
|
||||
}
|
||||
|
||||
// IEquatable<T>
|
||||
var equatable = typeof(IEquatable<>).MakeGenericType(type);
|
||||
if (equatable.GetTypeInfo().IsAssignableFrom(type))
|
||||
{
|
||||
var result = (bool)equatable.GetTypeInfo().GetMethod("Equals").Invoke(left, new[] { right });
|
||||
return new EqualInfo { IsEquals = result, Left = left, Right = right, Names = names };
|
||||
}
|
||||
|
||||
// is object
|
||||
var fields = left.GetType().GetTypeInfo().GetFields(BindingFlags.Instance | BindingFlags.Public);
|
||||
var properties = left.GetType().GetTypeInfo().GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => x.GetGetMethod(false) != null);
|
||||
var members = fields.Cast<MemberInfo>().Concat(properties);
|
||||
|
||||
foreach (dynamic mi in fields.Cast<MemberInfo>().Concat(properties))
|
||||
{
|
||||
var concatNames = names.Concat(new[] { (string)mi.Name });
|
||||
|
||||
object lv = mi.GetValue(left);
|
||||
object rv = mi.GetValue(right);
|
||||
var result = StructuralEqual(lv, rv, concatNames);
|
||||
if (!result.IsEquals)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return new EqualInfo { IsEquals = true, Left = left, Right = right, Names = names };
|
||||
}
|
||||
|
||||
private class EqualInfo
|
||||
{
|
||||
public object Left;
|
||||
public object Right;
|
||||
public bool IsEquals;
|
||||
public IEnumerable<string> Names;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ExpressionDumper
|
||||
|
||||
private class ExpressionDumper<T> : ExpressionVisitor
|
||||
{
|
||||
ParameterExpression param;
|
||||
T target;
|
||||
|
||||
public Dictionary<string, object> Members { get; private set; }
|
||||
|
||||
public ExpressionDumper(T target, ParameterExpression param)
|
||||
{
|
||||
this.target = target;
|
||||
this.param = param;
|
||||
this.Members = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
protected override System.Linq.Expressions.Expression VisitMember(MemberExpression node)
|
||||
{
|
||||
if (node.Expression == param && !Members.ContainsKey(node.Member.Name))
|
||||
{
|
||||
var accessor = new ReflectAccessor<T>(target, node.Member.Name);
|
||||
Members.Add(node.Member.Name, accessor.GetValue());
|
||||
}
|
||||
|
||||
return base.VisitMember(node);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public class AssertException : Exception
|
||||
{
|
||||
public AssertException(string message) : base(message) { }
|
||||
}
|
||||
|
||||
public class AssertFailedException : Exception
|
||||
{
|
||||
public AssertFailedException(string message) : base(message) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MsgPack.Cli" version="0.9.0-beta2" targetFramework="net462" />
|
||||
<package id="System.ValueTuple" version="4.3.0" targetFramework="net462" />
|
||||
<package id="xunit" version="2.2.0-rc1-build3507" targetFramework="net462" />
|
||||
<package id="xunit.abstractions" version="2.0.1" targetFramework="net462" />
|
||||
<package id="xunit.assert" version="2.2.0-rc1-build3507" targetFramework="net462" />
|
||||
<package id="xunit.core" version="2.2.0-rc1-build3507" targetFramework="net462" />
|
||||
<package id="xunit.extensibility.core" version="2.2.0-rc1-build3507" targetFramework="net462" />
|
||||
<package id="xunit.extensibility.execution" version="2.2.0-rc1-build3507" targetFramework="net462" />
|
||||
<package id="xunit.runner.visualstudio" version="2.2.0-rc1-build1247" targetFramework="net462" developmentDependency="true" />
|
||||
</packages>
|
Загрузка…
Ссылка в новой задаче