public void UniqueKeySerializationShouldReproduceAnIdenticalObject() { { var expected = UniqueKey.NewKey(Guid.NewGuid()); BinaryTokenStreamWriter writer = new BinaryTokenStreamWriter(); writer.Write(expected); BinaryTokenStreamReader reader = new BinaryTokenStreamReader(writer.ToBytes()); var actual = reader.ReadUniqueKey(); Assert.AreEqual(expected, actual, "UniqueKey.Serialize() and UniqueKey.Deserialize() failed to reproduce an identical object (case #1)."); } { var kx = random.Next().ToString(CultureInfo.InvariantCulture); var expected = UniqueKey.NewKey(Guid.NewGuid(), category: UniqueKey.Category.KeyExtGrain, keyExt: kx); BinaryTokenStreamWriter writer = new BinaryTokenStreamWriter(); writer.Write(expected); BinaryTokenStreamReader reader = new BinaryTokenStreamReader(writer.ToBytes()); var actual = reader.ReadUniqueKey(); Assert.AreEqual(expected, actual, "UniqueKey.Serialize() and UniqueKey.Deserialize() failed to reproduce an identical object (case #2)."); } { var kx = random.Next().ToString(CultureInfo.InvariantCulture) + new String('*', 400); var expected = UniqueKey.NewKey(Guid.NewGuid(), category: UniqueKey.Category.KeyExtGrain, keyExt: kx); BinaryTokenStreamWriter writer = new BinaryTokenStreamWriter(); writer.Write(expected); BinaryTokenStreamReader reader = new BinaryTokenStreamReader(writer.ToBytes()); var actual = reader.ReadUniqueKey(); Assert.AreEqual(expected, actual, "UniqueKey.Serialize() and UniqueKey.Deserialize() failed to reproduce an identical object (case #3)."); } }
public void Serialize(object item, ISerializationContext outerContext, Type expectedType) { var outerWriter = outerContext.StreamWriter; var actualType = item.GetType(); // To support loss-free serialization where possible, instances of the fallback exception type are serialized in a // semi-manual fashion. var fallbackException = item as RemoteNonDeserializableException; if (fallbackException != null) { this.ReserializeFallback(fallbackException, outerContext); return; } // Write the concrete type directly. this.typeSerializer.WriteNamedType(actualType, outerWriter); // Create a nested context which will be written to the outer context at an int-length offset from the current position. // This is because the inner context will be copied with a length prefix to the outer context. var innerWriter = new BinaryTokenStreamWriter(); var innerContext = outerContext.CreateNestedContext(position: outerContext.CurrentOffset + sizeof(int), writer: innerWriter); // Serialize the exception itself. var methods = this.GetSerializerMethods(actualType); methods.Serialize(item, innerContext, null); // Write the serialized exception to the output stream. outerContext.StreamWriter.Write(innerWriter.CurrentOffset); outerContext.StreamWriter.Write(innerWriter.ToBytes()); }
private void ReserializeFallback(RemoteNonDeserializableException fallbackException, ISerializationContext outerContext) { var outerWriter = outerContext.StreamWriter; // Write the type name directly. var key = new TypeSerializer.TypeKey(fallbackException.OriginalTypeName); TypeSerializer.WriteTypeKey(key, outerWriter); // Create a nested context which will be written to the outer context at an int-length offset from the current position. // This is because the inner context will be copied with a length prefix to the outer context. var innerWriter = new BinaryTokenStreamWriter(); var innerContext = outerContext.CreateNestedContext(sizeof(int), innerWriter); // Serialize the only accepted fields from the base Exception class. this.fallbackBaseExceptionSerializer.Serialize(fallbackException, innerContext, null); // Write the length of the serialized exception, then write the serialized bytes. var additionalDataLength = fallbackException.AdditionalData?.Length ?? 0; outerWriter.Write(innerWriter.CurrentOffset + additionalDataLength); outerWriter.Write(innerWriter.ToBytes()); if (additionalDataLength > 0) { outerWriter.Write(fallbackException.AdditionalData); } }
/// <inheritdoc /> public object DeepCopy(object source, ICopyContext context) { if (source == null) { return null; } var outputWriter = new BinaryTokenStreamWriter(); var serializationContext = new SerializationContext(context.GetSerializationManager()) { StreamWriter = outputWriter }; Serialize(source, serializationContext, source.GetType()); var deserializationContext = new DeserializationContext(context.GetSerializationManager()) { StreamReader = new BinaryTokenStreamReader(outputWriter.ToBytes()) }; var retVal = Deserialize(source.GetType(), deserializationContext); outputWriter.ReleaseBuffers(); return retVal; }
public void Serialize_CustomSerializer() { var original = new ClassWithCustomSerializer() { IntProperty = -3, StringProperty = "Goodbye" }; var writeStream = new BinaryTokenStreamWriter(); SerializationManager.Serialize(original, writeStream); Assert.AreEqual(1, ClassWithCustomSerializer.SerializeCounter, "Custom serializer was not called"); var readStream = new BinaryTokenStreamReader(writeStream.ToBytes()); var obj = SerializationManager.Deserialize(readStream); Assert.AreEqual(1, ClassWithCustomSerializer.DeserializeCounter, "Custom deserializer was not called"); }
private List<ArraySegment<byte>> Serialize_Impl(out int headerLengthOut, out int bodyLengthOut) { var headerStream = new BinaryTokenStreamWriter(); SerializationManager.SerializeMessageHeaders(Headers, headerStream); if (bodyBytes == null) { var bodyStream = new BinaryTokenStreamWriter(); SerializationManager.Serialize(bodyObject, bodyStream); // We don't bother to turn this into a byte array and save it in bodyBytes because Serialize only gets called on a message // being sent off-box. In this case, the likelihood of needed to re-serialize is very low, and the cost of capturing the // serialized bytes from the steam -- where they're a list of ArraySegment objects -- into an array of bytes is actually // pretty high (an array allocation plus a bunch of copying). bodyBytes = bodyStream.ToBytes() as List<ArraySegment<byte>>; } if (headerBytes != null) { BufferPool.GlobalPool.Release(headerBytes); } headerBytes = headerStream.ToBytes() as List<ArraySegment<byte>>; int headerLength = headerBytes.Sum(ab => ab.Count); int bodyLength = bodyBytes.Sum(ab => ab.Count); var bytes = new List<ArraySegment<byte>>(); bytes.Add(new ArraySegment<byte>(BitConverter.GetBytes(headerLength))); bytes.Add(new ArraySegment<byte>(BitConverter.GetBytes(bodyLength))); bytes.AddRange(headerBytes); bytes.AddRange(bodyBytes); if (headerLength + bodyLength > LargeMessageSizeThreshold) { logger.Info(ErrorCode.Messaging_LargeMsg_Outgoing, "Preparing to send large message Size={0} HeaderLength={1} BodyLength={2} #ArraySegments={3}. Msg={4}", headerLength + bodyLength + LENGTH_HEADER_SIZE, headerLength, bodyLength, bytes.Count, this.ToString()); if (logger.IsVerbose3) logger.Verbose3("Sending large message {0}", this.ToLongString()); } headerLengthOut = headerLength; bodyLengthOut = bodyLength; return bytes; }
private GrainReference RoundTripGrainReferenceOrleansSerializer(GrainReference input) { BinaryTokenStreamWriter writer = new BinaryTokenStreamWriter(); GrainReference.SerializeGrainReference(input, writer, typeof(GrainReference)); BinaryTokenStreamReader reader = new BinaryTokenStreamReader(writer.ToBytes()); GrainReference output = (GrainReference)GrainReference.DeserializeGrainReference(typeof(GrainReference), reader); return output; }