Exemple #1
0
        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);
        }
Exemple #2
0
        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));
            }
        }
Exemple #3
0
        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));
            }
        }