public int Decode(byte[] buffer, int offset, int size) { DecoderHelper.ValidateSize(size); int bytesConsumed; switch (_currentState) { case State.ReadingSize: bytesConsumed = _sizeDecoder.Decode(buffer, offset, size); 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 && size >= _encodedSize && CompareBuffers(_encodedBytes, buffer, offset)) { bytesConsumed = _bytesNeeded; OnComplete(_value); } else { bytesConsumed = _bytesNeeded; if (size < _bytesNeeded) { bytesConsumed = size; } Buffer.BlockCopy(buffer, offset, _encodedBytes, _encodedSize - _bytesNeeded, bytesConsumed); _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(byte[] bytes, int offset, int size) { DecoderHelper.ValidateSize(size); try { int bytesConsumed; FramingRecordType recordType; switch (CurrentState) { case ClientFramingDecoderState.ReadingUpgradeRecord: recordType = (FramingRecordType)bytes[offset]; if (recordType == FramingRecordType.UpgradeResponse) { bytesConsumed = 1; base.CurrentState = ClientFramingDecoderState.UpgradeResponse; } else { bytesConsumed = 0; base.CurrentState = ClientFramingDecoderState.ReadingAckRecord; } break; case ClientFramingDecoderState.UpgradeResponse: bytesConsumed = 0; base.CurrentState = ClientFramingDecoderState.ReadingUpgradeRecord; break; case ClientFramingDecoderState.ReadingAckRecord: recordType = (FramingRecordType)bytes[offset]; if (recordType == FramingRecordType.Fault) { bytesConsumed = 1; _faultDecoder = new FaultStringDecoder(); base.CurrentState = ClientFramingDecoderState.ReadingFaultString; break; } ValidatePreambleAck(recordType); bytesConsumed = 1; base.CurrentState = ClientFramingDecoderState.Start; break; case ClientFramingDecoderState.Start: bytesConsumed = 0; base.CurrentState = ClientFramingDecoderState.ReadingEnvelopeRecord; break; case ClientFramingDecoderState.ReadingEnvelopeRecord: recordType = (FramingRecordType)bytes[offset]; if (recordType == FramingRecordType.End) { bytesConsumed = 1; base.CurrentState = ClientFramingDecoderState.End; break; } else if (recordType == FramingRecordType.Fault) { bytesConsumed = 1; _faultDecoder = new FaultStringDecoder(); base.CurrentState = ClientFramingDecoderState.ReadingFaultString; break; } ValidateRecordType(FramingRecordType.SizedEnvelope, recordType); bytesConsumed = 1; base.CurrentState = ClientFramingDecoderState.ReadingEnvelopeSize; _sizeDecoder.Reset(); break; case ClientFramingDecoderState.ReadingEnvelopeSize: bytesConsumed = _sizeDecoder.Decode(bytes, offset, size); if (_sizeDecoder.IsValueDecoded) { base.CurrentState = ClientFramingDecoderState.EnvelopeStart; _envelopeSize = _sizeDecoder.Value; _envelopeBytesNeeded = _envelopeSize; } break; case ClientFramingDecoderState.EnvelopeStart: bytesConsumed = 0; base.CurrentState = ClientFramingDecoderState.ReadingEnvelopeBytes; break; case ClientFramingDecoderState.ReadingEnvelopeBytes: bytesConsumed = size; if (bytesConsumed > _envelopeBytesNeeded) { bytesConsumed = _envelopeBytesNeeded; } _envelopeBytesNeeded -= bytesConsumed; if (_envelopeBytesNeeded == 0) { base.CurrentState = ClientFramingDecoderState.EnvelopeEnd; } break; case ClientFramingDecoderState.EnvelopeEnd: bytesConsumed = 0; base.CurrentState = ClientFramingDecoderState.ReadingEnvelopeRecord; break; case ClientFramingDecoderState.ReadingFaultString: bytesConsumed = _faultDecoder.Decode(bytes, offset, size); if (_faultDecoder.IsValueDecoded) { base.CurrentState = ClientFramingDecoderState.Fault; } break; case ClientFramingDecoderState.Fault: bytesConsumed = 0; base.CurrentState = ClientFramingDecoderState.ReadingEndRecord; break; case ClientFramingDecoderState.ReadingEndRecord: ValidateRecordType(FramingRecordType.End, (FramingRecordType)bytes[offset]); bytesConsumed = 1; base.CurrentState = ClientFramingDecoderState.End; break; case ClientFramingDecoderState.End: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateException(new InvalidDataException(SR.FramingAtEnd))); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( CreateException(new InvalidDataException(SR.InvalidDecoderStateMachine))); } StreamPosition += bytesConsumed; return(bytesConsumed); } catch (InvalidDataException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateException(e)); } }
public int Decode(byte[] bytes, int offset, int size) { DecoderHelper.ValidateSize(size); try { int bytesConsumed; switch (_currentState) { case State.ReadingEnvelopeChunkSize: bytesConsumed = _sizeDecoder.Decode(bytes, offset, size); 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 = size; 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)bytes[offset]); 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))); } StreamPosition += bytesConsumed; return(bytesConsumed); } catch (InvalidDataException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateException(e)); } }