Пример #1
0
        public int Decode(ReadOnlySequence <byte> buffer)
        {
            DecoderHelper.ValidateSize(buffer.Length);
            if (isValueDecoded)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.FramingValueNotAvailable));
            }
            int bytesConsumed = 0;

            while (bytesConsumed < buffer.Length)
            {
                var data = buffer.First.Span;
                int next = data[0];
                value |= (next & 0x7F) << (index * 7);
                bytesConsumed++;
                if (index == LastIndex && (next & 0xF8) != 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataException(SR.FramingSizeTooLarge));
                }
                index++;
                if ((next & 0x80) == 0)
                {
                    isValueDecoded = true;
                    break;
                }
                buffer = buffer.Slice(buffer.GetPosition(1));
            }
            return(bytesConsumed);
        }
Пример #2
0
        public override int Decode(ReadOnlySequence <byte> buffer)
        {
            DecoderHelper.ValidateSize(buffer.Length);
            var data = buffer.First.Span;

            try
            {
                int bytesConsumed;
                switch (currentState)
                {
                case State.ReadingVersionRecord:
                    ValidateRecordType(FramingRecordType.Version, (FramingRecordType)data[0]);
                    currentState  = State.ReadingMajorVersion;
                    bytesConsumed = 1;
                    break;

                case State.ReadingMajorVersion:
                    majorVersion = data[0];
                    ValidateMajorVersion(majorVersion);
                    currentState  = State.ReadingMinorVersion;
                    bytesConsumed = 1;
                    break;

                case State.ReadingMinorVersion:
                    minorVersion  = data[0];
                    currentState  = State.ReadingModeRecord;
                    bytesConsumed = 1;
                    break;

                case State.ReadingModeRecord:
                    ValidateRecordType(FramingRecordType.Mode, (FramingRecordType)data[0]);
                    currentState  = State.ReadingModeValue;
                    bytesConsumed = 1;
                    break;

                case State.ReadingModeValue:
                    mode = (FramingMode)data[0];
                    ValidateFramingMode(mode);
                    currentState  = State.Done;
                    bytesConsumed = 1;
                    break;

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                              CreateException(new InvalidDataException(SR.InvalidDecoderStateMachine)));
                }

                return(bytesConsumed);
            }
            catch (InvalidDataException e)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateException(e));
            }
        }
Пример #3
0
        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));
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        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));
            }
        }