public int Decode(ReadOnlySequence <byte> buffer) { DecoderHelper.ValidateSize(buffer.Length); int bytesConsumed; switch (currentState) { case State.ReadingSize: bytesConsumed = sizeDecoder.Decode(buffer); if (sizeDecoder.IsValueDecoded) { encodedSize = sizeDecoder.Value; if (encodedSize > sizeQuota) { Exception quotaExceeded = OnSizeQuotaExceeded(encodedSize); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(quotaExceeded); } if (encodedBytes == null || encodedBytes.Length < encodedSize) { encodedBytes = Fx.AllocateByteArray(encodedSize); value = null; } currentState = State.ReadingBytes; bytesNeeded = encodedSize; } break; case State.ReadingBytes: if (value != null && valueLengthInBytes == encodedSize && bytesNeeded == encodedSize && buffer.Length >= encodedSize && CompareBuffers(encodedBytes, buffer)) { bytesConsumed = bytesNeeded; OnComplete(value); } else { bytesConsumed = bytesNeeded; if (buffer.Length < bytesNeeded) { bytesConsumed = (int)buffer.Length; } Span <byte> span = encodedBytes; Span <byte> slicedBytes = span.Slice(encodedSize - bytesNeeded, bytesConsumed); var tempBuffer = buffer.Slice(0, bytesConsumed); tempBuffer.CopyTo(slicedBytes); bytesNeeded -= bytesConsumed; if (bytesNeeded == 0) { value = Encoding.UTF8.GetString(encodedBytes, 0, encodedSize); valueLengthInBytes = encodedSize; OnComplete(value); } } break; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataException(SR.InvalidDecoderStateMachine)); } return(bytesConsumed); }
public override int Decode(ReadOnlySequence <byte> buffer) { DecoderHelper.ValidateSize(buffer.Length); var data = buffer.First.Span; try { int bytesConsumed; FramingRecordType recordType; switch (currentState) { case State.ReadingViaRecord: recordType = (FramingRecordType)data[0]; ValidateRecordType(FramingRecordType.Via, recordType); bytesConsumed = 1; viaDecoder.Reset(); currentState = State.ReadingViaString; break; case State.ReadingViaString: bytesConsumed = viaDecoder.Decode(buffer); if (viaDecoder.IsValueDecoded) { currentState = State.ReadingContentTypeRecord; } break; case State.ReadingContentTypeRecord: recordType = (FramingRecordType)data[0]; if (recordType == FramingRecordType.KnownEncoding) { bytesConsumed = 1; currentState = State.ReadingContentTypeByte; } else { ValidateRecordType(FramingRecordType.ExtensibleEncoding, recordType); bytesConsumed = 1; contentTypeDecoder.Reset(); currentState = State.ReadingContentTypeString; } break; case State.ReadingContentTypeByte: contentType = ContentTypeStringDecoder.GetString((FramingEncodingType)data[0]); bytesConsumed = 1; currentState = State.PreUpgradeStart; break; case State.ReadingContentTypeString: bytesConsumed = contentTypeDecoder.Decode(buffer); if (contentTypeDecoder.IsValueDecoded) { currentState = State.PreUpgradeStart; contentType = contentTypeDecoder.Value; } break; case State.PreUpgradeStart: bytesConsumed = 0; currentState = State.ReadingUpgradeRecord; break; case State.ReadingUpgradeRecord: recordType = (FramingRecordType)data[0]; if (recordType == FramingRecordType.UpgradeRequest) { bytesConsumed = 1; contentTypeDecoder.Reset(); currentState = State.ReadingUpgradeString; } else { bytesConsumed = 0; currentState = State.ReadingPreambleEndRecord; } break; case State.ReadingUpgradeString: bytesConsumed = contentTypeDecoder.Decode(buffer); if (contentTypeDecoder.IsValueDecoded) { currentState = State.UpgradeRequest; upgrade = contentTypeDecoder.Value; } break; case State.UpgradeRequest: bytesConsumed = 0; currentState = State.ReadingUpgradeRecord; break; case State.ReadingPreambleEndRecord: recordType = (FramingRecordType)data[0]; ValidateRecordType(FramingRecordType.PreambleEnd, recordType); bytesConsumed = 1; currentState = State.Start; break; case State.Start: bytesConsumed = 0; currentState = State.ReadingEndRecord; break; case State.ReadingEndRecord: recordType = (FramingRecordType)data[0]; if (recordType == FramingRecordType.End) { bytesConsumed = 1; currentState = State.End; } else { bytesConsumed = 0; currentState = State.ReadingEnvelopeRecord; } break; case State.ReadingEnvelopeRecord: ValidateRecordType(FramingRecordType.SizedEnvelope, (FramingRecordType)data[0]); bytesConsumed = 1; currentState = State.ReadingEnvelopeSize; sizeDecoder.Reset(); break; case State.ReadingEnvelopeSize: bytesConsumed = sizeDecoder.Decode(buffer); if (sizeDecoder.IsValueDecoded) { currentState = State.EnvelopeStart; envelopeSize = sizeDecoder.Value; envelopeBytesNeeded = envelopeSize; } break; case State.EnvelopeStart: bytesConsumed = 0; currentState = State.ReadingEnvelopeBytes; break; case State.ReadingEnvelopeBytes: bytesConsumed = (int)buffer.Length; if (bytesConsumed > envelopeBytesNeeded) { bytesConsumed = envelopeBytesNeeded; } envelopeBytesNeeded -= bytesConsumed; if (envelopeBytesNeeded == 0) { currentState = State.EnvelopeEnd; } break; case State.EnvelopeEnd: bytesConsumed = 0; currentState = State.ReadingEndRecord; break; case State.End: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateException(new InvalidDataException(SR.FramingAtEnd))); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateException(new InvalidDataException(SR.InvalidDecoderStateMachine))); } return(bytesConsumed); } catch (InvalidDataException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateException(e)); } }
public override int Decode(ReadOnlySequence <byte> buffer) { DecoderHelper.ValidateSize(buffer.Length); var data = buffer.First.Span; try { int bytesConsumed; switch (currentState) { case State.ReadingEnvelopeChunkSize: bytesConsumed = sizeDecoder.Decode(buffer); if (sizeDecoder.IsValueDecoded) { chunkSize = sizeDecoder.Value; sizeDecoder.Reset(); if (chunkSize == 0) { currentState = State.EnvelopeEnd; } else { currentState = State.ChunkStart; chunkBytesNeeded = chunkSize; } } break; case State.ChunkStart: bytesConsumed = 0; currentState = State.ReadingEnvelopeBytes; break; case State.ReadingEnvelopeBytes: bytesConsumed = (int)buffer.Length; if (bytesConsumed > chunkBytesNeeded) { bytesConsumed = chunkBytesNeeded; } chunkBytesNeeded -= bytesConsumed; if (chunkBytesNeeded == 0) { currentState = State.ChunkEnd; } break; case State.ChunkEnd: bytesConsumed = 0; currentState = State.ReadingEnvelopeChunkSize; break; case State.EnvelopeEnd: ValidateRecordType(FramingRecordType.End, (FramingRecordType)data[0]); bytesConsumed = 1; currentState = State.End; break; case State.End: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateException(new InvalidDataException(SR.FramingAtEnd))); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateException(new InvalidDataException(SR.InvalidDecoderStateMachine))); } return(bytesConsumed); } catch (InvalidDataException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateException(e)); } }