public static void AllSerializeDeserialize <From, To>(From from, bool noTranscoding = false) where From : class where To : class { RoundtripMemory <From, To> memoryRoundtrip = (serialize, deserialize) => { var data = serialize(from); var to = deserialize(data); Assert.IsTrue(from.IsEqual(to)); }; RoundtripPointer <From, To> pointerRoundtrip = (serialize, deserialize) => { var ptr = RMarshal.AllocHGlobal(UnsafeBufferSize); var data = serialize(from, ptr, UnsafeBufferSize); var to = deserialize(data, UnsafeBufferSize); Assert.IsTrue(from.IsEqual(to)); RMarshal.FreeHGlobal(data); }; RoundtripMemoryPointer <From, To> memoryPointerRoundtrip = (serialize, deserialize) => { var data = serialize(from); var pinned = GCHandle.Alloc(data.Array, GCHandleType.Pinned); var to = deserialize(RMarshal.UnsafeAddrOfPinnedArrayElement(data.Array, data.Offset), data.Count); Assert.IsTrue(from.IsEqual(to)); pinned.Free(); }; RoundtripStream <From, To> streamRoundtrip = (serialize, deserialize) => { var stream = new MemoryStream(); serialize(from, stream); stream.Position = 0; var to = deserialize(stream); Assert.IsTrue(from.IsEqual(to)); }; MarshalStream <From> streamMarshal = serialize => streamRoundtrip(serialize, stream => { stream.Position = 0; return(Unmarshal <To> .From(new InputStream(stream))); }); MarshalStream <From> streamMarshalSchema = serialize => streamRoundtrip(serialize, stream => { stream.Position = 0; return(Unmarshal.From(new InputStream(stream), Schema <From> .RuntimeSchema).Deserialize <To>()); }); MarshalStream <From> streamMarshalNoSchema = serialize => streamRoundtrip(serialize, stream => { stream.Position = 0; return(Unmarshal.From(new InputStream(stream)).Deserialize <To>()); }); MarshalMemory <From> memoryMarshal = serialize => memoryRoundtrip(serialize, Unmarshal <To> .From); TranscodeStream <From, To> streamTranscode = (serialize, transcode, deserialize) => streamRoundtrip((obj, stream) => { using (var tmp = new MemoryStream()) { serialize(obj, tmp); tmp.Position = 0; transcode(tmp, stream); } }, deserialize); if (noTranscoding) { streamTranscode = (serialize, transcode, deserialize) => { } } ; // Compact Binary streamRoundtrip(SerializeCB, DeserializeCB <To>); memoryRoundtrip(SerializeUnsafeCB, DeserializeSafeCB <To>); memoryRoundtrip(SerializeUnsafeCB, DeserializeUnsafeCB <To>); memoryPointerRoundtrip(SerializeUnsafeCB, DeserializePointerCB <To>); pointerRoundtrip(SerializePointerCB, DeserializePointerCB <To>); memoryRoundtrip(SerializeSafeCB, DeserializeSafeCB <To>); memoryRoundtrip(SerializeSafeCB, DeserializeUnsafeCB <To>); memoryPointerRoundtrip(SerializeSafeCB, DeserializePointerCB <To>); memoryRoundtrip(SerializeSafeCBNoInlining, DeserializeSafeCB <To>); streamMarshal(MarshalCB); streamMarshal(SerializerMarshalCB); streamMarshalSchema(MarshalCB); streamMarshalNoSchema(MarshalCB); memoryMarshal(MarshalCB); streamTranscode(SerializeCB, TranscodeCBCB, DeserializeCB <To>); streamTranscode(SerializeCB, TranscodeCBFB, DeserializeFB <To>); streamRoundtrip(SerializeCB, stream => { var input = new InputStream(stream); var reader = new CompactBinaryReader <InputStream>(input); return(DeserializeTagged <To>(reader)); }); // Fast Binary streamRoundtrip(SerializeFB, DeserializeFB <To>); memoryRoundtrip(SerializeFB, DeserializeSafeFB <To>); memoryRoundtrip(SerializeFB, DeserializeUnsafeFB <To>); memoryPointerRoundtrip(SerializeFB, DeserializePointerFB <To>); streamMarshal(MarshalFB); streamMarshal(SerializerMarshalFB); streamMarshalSchema(MarshalFB); streamMarshalNoSchema(MarshalFB); memoryMarshal(MarshalFB); streamTranscode(SerializeFB, TranscodeFBFB, DeserializeFB <To>); streamTranscode(SerializeFB, TranscodeFBCB, DeserializeCB <To>); streamRoundtrip(SerializeFB, stream => { var input = new InputStream(stream); var reader = new FastBinaryReader <InputStream>(input); return(DeserializeTagged <To>(reader)); }); // Simple doesn't support omitting fields if (typeof(From) != typeof(Nothing) && typeof(From) != typeof(GenericsWithNothing)) { streamRoundtrip(SerializeSP, DeserializeSP <From, To>); memoryRoundtrip(SerializeSP, DeserializeSafeSP <From, To>); memoryRoundtrip(SerializeSP, DeserializeUnsafeSP <From, To>); memoryPointerRoundtrip(SerializeSP, DeserializePointerSP <From, To>); streamRoundtrip(SerializeSP2, DeserializeSP2 <From, To>); memoryRoundtrip(SerializeSP2, DeserializeSafeSP2 <From, To>); memoryRoundtrip(SerializeSP2, DeserializeUnsafeSP2 <From, To>); streamTranscode(SerializeCB, TranscodeCBSP <From>, DeserializeSP <From, To>); streamTranscode(SerializeFB, TranscodeFBSP <From>, DeserializeSP <From, To>); streamTranscode(SerializeSP, TranscodeSPSP <From>, DeserializeSP <From, To>); streamTranscode(SerializeSP, TranscodeSPCB <From>, DeserializeCB <To>); streamTranscode(SerializeSP, TranscodeSPFB <From>, DeserializeFB <To>); // Pull parser doesn't supprot bonded<T> if (AnyField <From>(Reflection.IsBonded)) { streamTranscode(SerializeSP, TranscodeSPXml <From>, DeserializeXml <To>); // NewtonSoft JSON doesn't support uint64 if (typeof(From) != typeof(MaxUInt64)) { streamTranscode(SerializeSP, TranscodeSPJson <From>, DeserializeJson <To>); } } streamRoundtrip(SerializeSP, stream => { var input = new InputStream(stream); var reader = new SimpleBinaryReader <InputStream>(input); return(DeserializeUntagged <From, To>(reader)); }); streamMarshalSchema(MarshalSP); } // Pull parser doesn't supprot bonded<T> if (AnyField <From>(Reflection.IsBonded)) { streamRoundtrip(SerializeXml, DeserializeXml <To>); streamTranscode(SerializeCB, TranscodeCBXml <From>, DeserializeXml <To>); streamTranscode(SerializeFB, TranscodeFBXml <From>, DeserializeXml <To>); // NewtonSoft JSON doesn't support uint64 if (typeof(From) != typeof(MaxUInt64)) { streamRoundtrip(SerializeJson, DeserializeJson <To>); streamTranscode(SerializeCB, TranscodeCBJson <From>, DeserializeJson <To>); streamTranscode(SerializeFB, TranscodeFBJson <From>, DeserializeJson <To>); } } } delegate bool TypePredicate(Type field);
public static void AllSerializeDeserialize <From, To>(From from, bool noTranscoding = false) where From : class where To : class { RoundtripMemory <From, To> memoryRoundtrip = (serialize, deserialize) => { var data = serialize(from); var to = deserialize(data); Assert.IsTrue(from.IsEqual(to)); }; RoundtripStream <From, To> streamRoundtrip = (serialize, deserialize) => { var stream = new MemoryStream(); serialize(from, stream); stream.Position = 0; var to = deserialize(stream); Assert.IsTrue(from.IsEqual(to)); }; MarshalStream <From> streamMarshal = serialize => streamRoundtrip(serialize, stream => { stream.Position = 0; return(Unmarshal <To> .From(new InputStream(stream))); }); MarshalStream <From> streamMarshalSchema = serialize => streamRoundtrip(serialize, stream => { stream.Position = 0; return(Unmarshal.From(new InputStream(stream), Schema <From> .RuntimeSchema).Deserialize <To>()); }); MarshalStream <From> streamMarshalNoSchema = serialize => streamRoundtrip(serialize, stream => { stream.Position = 0; return(Unmarshal.From(new InputStream(stream)).Deserialize <To>()); }); MarshalMemory <From> memoryMarshal = serialize => memoryRoundtrip(serialize, Unmarshal <To> .From); TranscodeStream <From, To> streamTranscode = (serialize, transcode, deserialize) => streamRoundtrip((obj, stream) => { using (var tmp = new MemoryStream()) { serialize(obj, tmp); tmp.Position = 0; transcode(tmp, stream); } }, deserialize); if (noTranscoding) { streamTranscode = (serialize, transcode, deserialize) => { } } ; // Compact Binary streamRoundtrip(SerializeCB, DeserializeCB <To>); memoryRoundtrip(SerializeUnsafeCB, DeserializeSafeCB <To>); memoryRoundtrip(SerializeUnsafeCB, DeserializeUnsafeCB <To>); memoryRoundtrip(SerializeSafeCB, DeserializeSafeCB <To>); memoryRoundtrip(SerializeSafeCB, DeserializeUnsafeCB <To>); streamMarshal(MarshalCB); streamMarshal(SerializerMarshalCB); streamMarshalSchema(MarshalCB); streamMarshalNoSchema(MarshalCB); memoryMarshal(MarshalCB); streamTranscode(SerializeCB, TranscodeCBCB, DeserializeCB <To>); streamTranscode(SerializeCB, TranscodeCBFB, DeserializeFB <To>); streamRoundtrip(SerializeCB, stream => { var input = new InputStream(stream); var reader = new CompactBinaryReader <InputStream>(input); return(DeserializeTagged <To>(reader)); }); // Fast Binary streamRoundtrip(SerializeFB, DeserializeFB <To>); memoryRoundtrip(SerializeFB, DeserializeSafeFB <To>); memoryRoundtrip(SerializeFB, DeserializeUnsafeFB <To>); streamMarshal(MarshalFB); streamMarshal(SerializerMarshalFB); streamMarshalSchema(MarshalFB); streamMarshalNoSchema(MarshalFB); memoryMarshal(MarshalFB); streamTranscode(SerializeFB, TranscodeFBFB, DeserializeFB <To>); streamTranscode(SerializeFB, TranscodeFBCB, DeserializeCB <To>); streamRoundtrip(SerializeFB, stream => { var input = new InputStream(stream); var reader = new FastBinaryReader <InputStream>(input); return(DeserializeTagged <To>(reader)); }); // Simple doesn't support omitting fields if (typeof(From) != typeof(Nothing) && typeof(From) != typeof(GenericsWithNothing)) { streamRoundtrip(SerializeSP, DeserializeSP <From, To>); memoryRoundtrip(SerializeSP, DeserializeSafeSP <From, To>); memoryRoundtrip(SerializeSP, DeserializeUnsafeSP <From, To>); streamTranscode(SerializeCB, TranscodeCBSP <From>, DeserializeSP <From, To>); streamTranscode(SerializeFB, TranscodeFBSP <From>, DeserializeSP <From, To>); streamTranscode(SerializeSP, TranscodeSPSP <From>, DeserializeSP <From, To>); streamTranscode(SerializeSP, TranscodeSPCB <From>, DeserializeCB <To>); streamTranscode(SerializeSP, TranscodeSPFB <From>, DeserializeFB <To>); streamTranscode(SerializeSP, TranscodeSPXml <From>, DeserializeXml <To>); streamTranscode(SerializeSP, TranscodeSPJson <From>, DeserializeJson <To>); streamRoundtrip(SerializeSP, stream => { var input = new InputStream(stream); var reader = new SimpleBinaryReader <InputStream>(input); return(DeserializeUntagged <From, To>(reader)); }); streamMarshalSchema(MarshalSP); } streamRoundtrip(SerializeXml, DeserializeXml <To>); streamRoundtrip(SerializeJson, DeserializeJson <To>); streamTranscode(SerializeCB, TranscodeCBXml <From>, DeserializeXml <To>); streamTranscode(SerializeCB, TranscodeCBJson <From>, DeserializeJson <To>); streamTranscode(SerializeFB, TranscodeFBXml <From>, DeserializeXml <To>); streamTranscode(SerializeFB, TranscodeFBJson <From>, DeserializeJson <To>); } }