Exemplo n.º 1
0
        private bool TryParseCompressedMessage(DataLinkMessageType type, ReadOnlySequence <byte> buffer, int inlinelength, out DCTransportMessage transportMessage)
        {
            var isShortForm = inlinelength != 0x0f;
            int length;

            if (isShortForm)
            {
                if (buffer.Length <= 1)
                {
                    transportMessage = DCTransportMessage.Incomplete;
                    return(false);
                }
                length = (inlinelength << 8) + buffer.FirstSpan[0];
                buffer = buffer.Slice(1);
            }
            else
            {
                if (buffer.Length <= 4)
                {
                    transportMessage = DCTransportMessage.Incomplete;
                    return(false);
                }
                length = ReadInt32(ref buffer);
            }
            if (buffer.Length < length)
            {
                transportMessage = DCTransportMessage.Incomplete;
                return(false);
            }
            transportMessage = new DCTransportMessage(1 + (isShortForm ? 1 : 4) + length, type, buffer.Slice(0, length));
            return(true);
        }
Exemplo n.º 2
0
        public bool TryParseTransportMessage(ReadOnlySequence <byte> buffer, out DCTransportMessage transportMessage)
        {
            const int HighFourBitMask = 0xF0;
            const int LowFourBitMask  = 0x0F;

            var first       = buffer.FirstSpan[0];
            var highFourBit = first & HighFourBitMask;

            if (highFourBit == 0)
            {
                switch ((DataLinkMessageType)first)
                {
                case DataLinkMessageType.Unknown:
                case DataLinkMessageType.Incomplete:
                    throw new InvalidOperationException("Bad tranport data.");

                case DataLinkMessageType.Disconnect:
                case DataLinkMessageType.SyncNode:
                    // No body message.
                    transportMessage = new DCTransportMessage(1, (DataLinkMessageType)first, ReadOnlySequence <byte> .Empty);
                    return(true);

                case DataLinkMessageType.AckNo:
                case DataLinkMessageType.AckYes:
                case DataLinkMessageType.Ping:
                case DataLinkMessageType.Sub:
                case DataLinkMessageType.Unsub:
                    // 4 bytes body.
                    if (buffer.Length < 1 + 4)
                    {
                        transportMessage = DCTransportMessage.Incomplete;
                        return(false);
                    }
                    transportMessage = new DCTransportMessage(1 + 4, (DataLinkMessageType)first, buffer.Slice(1, 4));
                    return(true);

                case DataLinkMessageType.Query:
                    // 8 bytes body.
                    if (buffer.Length < 1 + 4 + 4)
                    {
                        transportMessage = DCTransportMessage.Incomplete;
                        return(false);
                    }
                    transportMessage = new DCTransportMessage(1 + 4 + 4, (DataLinkMessageType)first, buffer.Slice(1, 4 + 4));
                    return(true);

                default:
                    break;
                }
            }
            else
            {
                switch ((DataLinkMessageType)highFourBit)
                {
                case DataLinkMessageType.Connect:
                case DataLinkMessageType.ReplySyncNode:
                case DataLinkMessageType.Payload:
                case DataLinkMessageType.PayloadWithAck:
                    return(TryParseCompressedMessage((DataLinkMessageType)highFourBit, buffer.Slice(1), first & LowFourBitMask, out transportMessage));

                default:
                    break;
                }
            }

            throw new InvalidOperationException("Bad tranport data.");
        }