public void Deserialize <TInput>(ref Reader <TInput> reader, Exception value) { uint fieldId = 0; string message = null; string stackTrace = null; Exception innerException = null; Dictionary <object, object> data = null; int hResult = 0; while (true) { var header = reader.ReadFieldHeader(); if (header.IsEndBaseOrEndObject) { break; } fieldId += header.FieldIdDelta; switch (fieldId) { case 0: message = StringCodec.ReadValue(ref reader, header); break; case 1: stackTrace = StringCodec.ReadValue(ref reader, header); break; case 2: innerException = ReadValue(ref reader, header); break; case 3: hResult = Int32Codec.ReadValue(ref reader, header); break; case 4: data = _dictionaryCodec.ReadValue(ref reader, header); break; default: reader.ConsumeUnknownField(header); break; } } SetBaseProperties(value, message, stackTrace, innerException, hResult, data); }
private void RoundTripTest(SubType expected, bool assertRef = true) { using var writerSession = GetSession(); var pipe = new Pipe(); var writer = Writer.Create(pipe.Writer, writerSession); _serializer.WriteField(ref writer, 0, typeof(SubType), expected); writer.Commit(); _log.WriteLine($"Size: {writer.Position} bytes."); _log.WriteLine($"Wrote References:\n{GetWriteReferenceTable(writerSession)}"); _ = pipe.Writer.FlushAsync().AsTask().GetAwaiter().GetResult(); pipe.Writer.Complete(); _ = pipe.Reader.TryRead(out var readResult); using var readerSesssion = GetSession(); var reader = Reader.Create(readResult.Buffer, readerSesssion); var initialHeader = reader.ReadFieldHeader(); _log.WriteLine("Header:"); _log.WriteLine(initialHeader.ToString()); var actual = _serializer.ReadValue(ref reader, initialHeader); pipe.Reader.AdvanceTo(readResult.Buffer.End); pipe.Reader.Complete(); _log.WriteLine($"Expect: {expected}\nActual: {actual}"); Assert.Equal(expected.BaseTypeString, actual.BaseTypeString); Assert.Null(actual.AddedLaterString); // The deserializer isn't 'aware' of this field which was added later - version tolerance. Assert.Equal(expected.String, actual.String); Assert.Equal(expected.Int, actual.Int); if (assertRef) { Assert.Equal(expected.Ref, actual.Ref); } Assert.Equal(writer.Position, reader.Position); Assert.Equal(writer.Session.ReferencedObjects.CurrentReferenceId, reader.Session.ReferencedObjects.CurrentReferenceId); var references = GetReadReferenceTable(reader.Session); _log.WriteLine($"Read references:\n{references}"); }
Tuple <T> IFieldCodec <Tuple <T> > .ReadValue <TInput>(ref Reader <TInput> reader, Field field) { if (field.WireType == WireType.Reference) { return(ReferenceCodec.ReadReference <Tuple <T>, TInput>(ref reader, field)); } if (field.WireType != WireType.TagDelimited) { ThrowUnsupportedWireTypeException(field); } var placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session); var item1 = default(T); uint fieldId = 0; while (true) { var header = reader.ReadFieldHeader(); if (header.IsEndBaseOrEndObject) { break; } fieldId += header.FieldIdDelta; switch (fieldId) { case 1: item1 = _valueCodec.ReadValue(ref reader, header); break; default: reader.ConsumeUnknownField(header); break; } } var result = new Tuple <T>(item1); ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId); return(result); }
public object ReadValue <TInput>(ref Reader <TInput> reader, Field field) { if (field.WireType == WireType.Reference) { return(ReferenceCodec.ReadReference <object, TInput>(ref reader, field)); } var placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session); var header = reader.ReadFieldHeader(); var type = _typeCodec.ReadValue(ref reader, header); if (type.IsValueType) { var serializer = _valueTypeSerializerFactory.GetSerializer(type); return(serializer.ReadValue(ref reader, type, placeholderReferenceId)); } return(_objectSerializer.ReadValue(ref reader, type, placeholderReferenceId)); }
public KeyValuePair <TKey, TValue> ReadValue <TInput>(ref Reader <TInput> reader, Field field) { if (field.WireType != WireType.TagDelimited) { ThrowUnsupportedWireTypeException(field); } ReferenceCodec.MarkValueField(reader.Session); var key = default(TKey); var value = default(TValue); uint fieldId = 0; while (true) { var header = reader.ReadFieldHeader(); if (header.IsEndBaseOrEndObject) { break; } fieldId += header.FieldIdDelta; switch (fieldId) { case 0: key = _keyCodec.ReadValue(ref reader, header); break; case 1: value = _valueCodec.ReadValue(ref reader, header); break; default: reader.ConsumeUnknownField(header); break; } } return(new KeyValuePair <TKey, TValue>(key, value)); }
private static void Test <T>(Func <SerializerSession> getSession, IFieldCodec <T> serializer, T expected) { using var writerSession = getSession(); var pipe = new Pipe(); var writer = Writer.Create(pipe.Writer, writerSession); serializer.WriteField(ref writer, 0, typeof(T), expected); writer.Commit(); Console.WriteLine($"Size: {writer.Position} bytes."); Console.WriteLine($"Wrote References:\n{GetWriteReferenceTable(writerSession)}"); _ = pipe.Writer.FlushAsync().AsTask().GetAwaiter().GetResult(); pipe.Writer.Complete(); _ = pipe.Reader.TryRead(out var readResult); { using var readerSesssion = getSession(); var reader = Reader.Create(readResult.Buffer, readerSesssion); var result = BitStreamFormatter.Format(ref reader); Console.WriteLine(result); } { using var readerSesssion = getSession(); var reader = Reader.Create(readResult.Buffer, readerSesssion); var initialHeader = reader.ReadFieldHeader(); Console.WriteLine("Header:"); Console.WriteLine(initialHeader.ToString()); var actual = serializer.ReadValue(ref reader, initialHeader); pipe.Reader.AdvanceTo(readResult.Buffer.End); pipe.Reader.Complete(); Console.WriteLine($"Expect: {expected}\nActual: {actual}"); var references = GetReadReferenceTable(reader.Session); Console.WriteLine($"Read references:\n{references}"); } }
static void Test <T>(Func <SerializerSession> getSession, IFieldCodec <T> serializer, T expected) { var session = getSession(); var writer = new Writer(); serializer.WriteField(writer, session, 0, typeof(T), expected); Console.WriteLine($"Size: {writer.CurrentOffset} bytes."); Console.WriteLine($"Wrote References:\n{GetWriteReferenceTable(session)}"); //Console.WriteLine("TokenStream: " + string.Join(" ", TokenStreamParser.Parse(new Reader(writer.ToBytes()), getSession()))); var reader = new Reader(writer.ToBytes()); var deserializationContext = getSession(); var initialHeader = reader.ReadFieldHeader(session); //Console.WriteLine(initialHeader); var actual = serializer.ReadValue(reader, deserializationContext, initialHeader); Console.WriteLine($"Expect: {expected}\nActual: {actual}"); var references = GetReadReferenceTable(deserializationContext); Console.WriteLine($"Read references:\n{references}"); }
/// <inheritdoc/> object IFieldCodec <object> .ReadValue <TInput>(ref Reader <TInput> reader, Field field) { if (field.WireType == WireType.Reference) { return(ReferenceCodec.ReadReference <T[], TInput>(ref reader, field)); } if (field.WireType != WireType.TagDelimited) { ThrowUnsupportedWireTypeException(field); } var placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session); Array result = null; uint fieldId = 0; int[] lengths = null; int[] indices = null; var rank = 0; while (true) { var header = reader.ReadFieldHeader(); if (header.IsEndBaseOrEndObject) { break; } fieldId += header.FieldIdDelta; switch (fieldId) { case 0: { lengths = _intArrayCodec.ReadValue(ref reader, header); rank = lengths.Length; // Multi-dimensional arrays must be indexed using indexing arrays, so create one now. indices = new int[rank]; result = Array.CreateInstance(CodecElementType, lengths); ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId); break; } case 1: { if (result is null) { return(ThrowLengthsFieldMissing()); } var element = _elementCodec.ReadValue(ref reader, header); result.SetValue(element, indices); // Increment the indices array by 1. var idx = rank - 1; while (idx >= 0 && ++indices[idx] >= lengths[idx]) { indices[idx] = 0; --idx; } break; } default: reader.ConsumeUnknownField(header); break; } } return(result); }
TField IFieldCodec <TField> .ReadValue <TInput>(ref Reader <TInput> reader, Field field) => (TField)_codec.ReadValue(ref reader, field);
/// <inheritdoc/> public List <T> ReadValue <TInput>(ref Reader <TInput> reader, Field field) { if (field.WireType == WireType.Reference) { return(ReferenceCodec.ReadReference <List <T>, TInput>(ref reader, field)); } if (field.WireType != WireType.TagDelimited) { ThrowUnsupportedWireTypeException(field); } var placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session); List <T> result = null; uint fieldId = 0; var length = 0; var index = 0; while (true) { var header = reader.ReadFieldHeader(); if (header.IsEndBaseOrEndObject) { break; } fieldId += header.FieldIdDelta; switch (fieldId) { case 0: length = Int32Codec.ReadValue(ref reader, header); if (length > 10240 && length > reader.Length) { ThrowInvalidSizeException(length); } result = _activator.Create(length); result.Capacity = length; ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId); break; case 1: if (result is null) { ThrowLengthFieldMissing(); } if (index >= length) { ThrowIndexOutOfRangeException(length); } result.Add(_fieldCodec.ReadValue(ref reader, header)); ++index; break; default: reader.ConsumeUnknownField(header); break; } } return(result); }