public ActionRequest <TReqParams, TRespData> Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (!reader.TryReadMapHeader(out var elementCount)) { throw new MessagePackSerializationException(); } var actionSeq = ReadOnlySequence <byte> .Empty; var paramsSeq = ReadOnlySequence <byte> .Empty; var echo = string.Empty; // `elementCount` shall be 2 or 3. for (var i = 0; i < elementCount; i++) { if (reader.TryReadStringSpan(out var propertyName)) { if (propertyName.SequenceEqual(ConstantsOfAction.sActionPropertyName)) { actionSeq = reader.ReadRaw(); } else if (propertyName.SequenceEqual(ConstantsOfAction.sParamsPropertyName)) { paramsSeq = reader.ReadRaw(); } else if (propertyName.SequenceEqual(ConstantsOfAction.sEchoPropertyName)) { echo = reader.ReadString(); } } } var action = MessagePackSerializer.Deserialize <ActionType>(actionSeq, options) ?? ActionType.Unknown with { Key = MessagePackSerializer.Deserialize <string>(actionSeq, options) }; var param = MessagePackSerializer.Deserialize(typeof(TReqParams), paramsSeq, options); // Full-trust `ActionType`, so `GetUninitializedObject` is safe, but it is f**king SLOW. // var zeroObj = FormatterServices.GetUninitializedObject(action.ClassType); // `Activator` is much (4x-6x) faster, but it depends on the constructor. var zeroObj = Activator.CreateInstance(action.ClassType, param, echo); if (zeroObj is ActionRequest <TReqParams, TRespData> req && param is TReqParams reqParam) { return(req with { Action = action, Params = reqParam, Echo = echo }); } // Failed in deserialize. throw new NotSupportedException( $"{nameof(ActionType)} {Encoding.UTF8.GetString(actionSeq)} is not supported by {nameof(MsgPackActionRequestFormatter<TReqParams, TRespData>)}."); } }
public ReadOnlySequence <T> Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (reader.TryReadNil()) { return(ReadOnlySequence <T> .Empty); } var header = reader.ReadExtensionFormatHeader(); if (header.TypeCode != TypeCode) { throw new MessagePackSerializationException("Extension TypeCode is invalid. typeCode: " + header.TypeCode); } if (header.Length == 0) { return(ReadOnlySequence <T> .Empty); } var elementCount = header.Length / sizeof(T); if (elementCount * sizeof(T) != header.Length) { throw new MessagePackSerializationException("Extension Length is invalid. actual: " + header.Length + ", element size: " + sizeof(T)); } var answer = new T[elementCount]; reader.ReadRaw(header.Length).CopyTo(MemoryMarshal.AsBytes(answer.AsSpan())); return(new ReadOnlySequence <T>(answer)); }
public T Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { var header = reader.ReadExtensionFormatHeader(); if (header.TypeCode != TypeCode) { throw new MessagePackSerializationException("Extension TypeCode is invalid. typeCode: " + header.TypeCode); } if (header.Length != sizeof(T)) { throw new MessagePackSerializationException("Extension Length is invalid. actual: " + header.Length + ", expected: " + sizeof(T)); } var sequence = reader.ReadRaw(sizeof(T)); if (sequence.IsSingleSegment) { return(Unsafe.As <byte, T>(ref Unsafe.AsRef(sequence.FirstSpan[0]))); } T answer; sequence.CopyTo(new Span <byte>(&answer, sizeof(T))); return(answer); }
public Segment Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (!reader.TryReadMapHeader(out var elementCount)) { throw new MessagePackSerializationException(); } var typeSeq = ReadOnlySequence <byte> .Empty; var dataSeq = ReadOnlySequence <byte> .Empty; // `elementCount` shall be 2. for (var i = 0; i < elementCount; i++) { if (reader.TryReadStringSpan(out var propertyName)) { if (propertyName.SequenceEqual(sTypePropertyName)) { typeSeq = reader.ReadRaw(); } else if (propertyName.SequenceEqual(sDataPropertyName)) { dataSeq = reader.ReadRaw(); } } } var type = MessagePackSerializer.Deserialize <SegmentType>(typeSeq, options) ?? SegmentType.Unknown with { Key = MessagePackSerializer.Deserialize <string>(typeSeq, options) }; var data = MessagePackSerializer.Deserialize(type.ClassType, dataSeq, options); if (data is SegmentData d) { // BUG: `SegmentData` ignores `ExtensionData`. return(new Segment(type, d)); } // Failed in deserialize `data`, not supported `Segment` yet. throw new NotSupportedException( $"{nameof(SegmentType)} {Encoding.UTF8.GetString(typeSeq)} is not supported by {nameof(MsgPackSegmentFormatter)}."); } }
private object ReadItem(ref MessagePackReader reader, string invocationId) { long longId = 0; if (long.TryParse(invocationId, out longId)) { Type itemType = this.Connection.GetItemType(longId); return(MessagePackSerializer.Deserialize(itemType, reader.ReadRaw())); //return MessagePackSerializer.Deserialize(itemType, ref reader); } else { reader.Skip(); return(null); } }
public UInt160 Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { // post RC3 serialization format of UInt160 if (reader.NextMessagePackType == MessagePackType.Binary) { var value = options.Resolver.GetFormatter <byte[]>().Deserialize(ref reader, options); return(new UInt160(value)); } // pre RC3 serialization format of UInt160 if (reader.NextMessagePackType == MessagePackType.Integer) { var seq = reader.ReadRaw(UInt160.Length); return(new UInt160(seq.IsSingleSegment ? seq.FirstSpan : seq.ToArray())); } throw new MessagePackSerializationException($"Unexpected UInt160 MessagePack type {reader.NextMessagePackType}"); }
private CompletionMessage CreateCompletionMessage(ref MessagePackReader reader, IInvocationBinder binder) { var headers = ReadHeaders(ref reader); var invocationId = ReadInvocationId(ref reader); var resultKind = ReadInt32(ref reader, "resultKind"); string?error = null; object?result = null; var hasResult = false; switch (resultKind) { case ErrorResult: error = ReadString(ref reader, "error"); break; case NonVoidResult: var itemType = binder.GetReturnType(invocationId); if (itemType == typeof(RawResult)) { result = new RawResult(reader.ReadRaw()); } else { result = DeserializeObject(ref reader, itemType, "argument"); } hasResult = true; break; case VoidResult: hasResult = false; break; default: throw new InvalidDataException("Invalid invocation result kind."); } return(ApplyHeaders(headers, new CompletionMessage(invocationId, error, result, hasResult))); }
public T[] Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (reader.TryReadNil()) { return(null); } ExtensionHeader header = reader.ReadExtensionFormatHeader(); if (header.TypeCode != this.TypeCode) { throw new InvalidOperationException("Invalid typeCode."); } var byteLength = reader.ReadInt32(); var isLittleEndian = reader.ReadBoolean(); // Allocate a T[] that we will return. We'll then cast the T[] as byte[] so we can copy the byte sequence directly into it. var result = new T[byteLength / Marshal.SizeOf <T>()]; Span <byte> resultAsBytes = MemoryMarshal.Cast <T, byte>(result); reader.ReadRaw(byteLength).CopyTo(resultAsBytes); // Reverse the byte order if necessary. if (isLittleEndian != BitConverter.IsLittleEndian) { for (int i = 0, j = resultAsBytes.Length - 1; i < j; i++, j--) { byte tmp = resultAsBytes[i]; resultAsBytes[i] = resultAsBytes[j]; resultAsBytes[j] = tmp; } } return(result); }
public TFrameList Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (reader.TryReadNil()) { return((TFrameList)(IList <T>)null); } Interlocked.Increment(ref ParallelGatekeeperSingleton.wrapperDepth); try { options.Security.DepthStep(ref reader); try { FrameFormatterSerializationOptions frameOptions = options.GetOptionParams(); if (frameOptions.MthWorkerConfig.MaxConcurrentTasks == 1 || ParallelGatekeeperSingleton.wrapperDepth > 1) { return(DeserializeSynchronous(ref reader, options)); } var readerBackup = reader.CreatePeekReader(); int count = reader.ReadArrayHeader(); if (count == 0) { reader = readerBackup; return(DeserializeSynchronous(ref reader, options)); } var peekreader = reader.CreatePeekReader(); if (FrameItemFormatter <T> .ReadElementHeader(ref peekreader) == Frame <T> .unassigned) { if (frameOptions.ThrowOnUnnasignedFrameDeserialization) { throw new StreamSerializationException($"Unassigned buffer length found during parallel deserialize for {nameof(TFrameList)}"); } reader = readerBackup; return(DeserializeSynchronous(ref reader, options)); } IMessagePackFormatter <T> formatterT = options.Resolver.GetFormatterWithVerify <T>(); ListFrameWrapper valueWrapper = GetTFrameListWrapper(count); Frame <T>[] resItems = valueWrapper.AsFrameArray(); BatchSizeEstimator batchEstimator = new BatchSizeEstimator(frameOptions.BatchSizeEstimatorConfig); void ProcessBatch(BatchWithBufferWritersAndElementOffset batch, CancellationToken token) { try { ReadOnlySpan <int> lengths = batch.buffers.lengths.WrittenSpan; ReadOnlyMemory <byte> bodies = batch.buffers.concatenatedBodies.WrittenMemory; int batchSize = batch.buffers.lengths.WrittenCount; var destSpan = resItems.AsSpan(batch.offset, batchSize); for (int ix = 0, bodyStartIx = 0; ix < batchSize; ix++) { int itemLen = lengths[ix]; ReadOnlyMemory <byte> body = bodies.Slice(bodyStartIx, itemLen); MessagePackReader tmpReader = new MessagePackReader(body) { CancellationToken = token }; destSpan[ix].BufferLength = body.Length; destSpan[ix].Item = formatterT.Deserialize(ref tmpReader, options); bodyStartIx += itemLen; } } finally { objPoolBufferWriterBodies.Return(batch.buffers.concatenatedBodies); objPoolBufferWriterBodyLengths.Return(batch.buffers.lengths); } } using (var mtw = new MultiThreadedWorker <BatchWithBufferWritersAndElementOffset>( frameOptions.MthWorkerConfig, ProcessBatch)) { int i = 0; while (i < count) { int batchSize = Math.Min(count - i, batchEstimator.RecomendedBatchSize); var currentBatch = new BatchWithBufferWritersAndElementOffset() { offset = i, buffers = new BatchWithBufferWriters() { concatenatedBodies = objPoolBufferWriterBodies.Get(), lengths = objPoolBufferWriterBodyLengths.Get() } }; for (int seqIx = 0; seqIx < batchSize; seqIx++) { int itemLength = FrameItemFormatter <T> .ReadElementHeader(ref reader); if (itemLength == Frame <T> .unassigned) { throw new StreamSerializationException($"Unassigned buffer length found during parallel deserialize for {nameof(TFrameList)}"); } currentBatch.buffers.lengths.GetSpan(1)[0] = itemLength; currentBatch.buffers.lengths.Advance(1); ReadOnlySequence <byte> raw = reader.ReadRaw(itemLength); raw.CopyTo(currentBatch.buffers.concatenatedBodies.GetSpan(itemLength)); currentBatch.buffers.concatenatedBodies.Advance(itemLength); batchEstimator.UpdateEstimate(itemLength); } mtw.AddWorkItem(currentBatch, reader.CancellationToken); i += batchSize; } } return(valueWrapper.AsFrameList()); } finally { reader.Depth--; } } finally { Interlocked.Decrement(ref ParallelGatekeeperSingleton.wrapperDepth); } }
private object[] ReadArguments(ref MessagePackReader reader, string target) { var subscription = this.Connection.GetSubscription(target); object[] args = null; if (subscription == null || subscription.callbacks == null || subscription.callbacks.Count == 0) { reader.Skip(); } else { int count = reader.ReadArrayHeader(); if (subscription.callbacks[0].ParamTypes != null) { args = new object[subscription.callbacks[0].ParamTypes.Length]; for (int i = 0; i < subscription.callbacks[0].ParamTypes.Length; ++i) { args[i] = MessagePackSerializer.Deserialize(subscription.callbacks[0].ParamTypes[i], reader.ReadRaw()); //args[i] = MessagePackSerializer.Deserialize(subscription.callbacks[0].ParamTypes[i], ref reader); } } else { args = null; } } return(args); }