Beispiel #1
0
        /// <summary>
        /// Decoder step 1: get message header 10 bytes
        /// </summary>
        /// <param name="length"></param>
        /// <param name="need"></param>
        /// <returns>The decoder step to execute next.</returns>
        private int DecoderStep1GetMessageHeader(ref int length, out int need)
        {
            if (!StreamDecoder.CheckAvailable(length, 10, out need))
            {
                return(1);
            }

            this.messageHeader      = MessageHeader.Decode(new ReadOnlySpan <byte>(this.Buffer, this.decodeIndex, 10));
            this.decodeIndex       += 10;
            this.messageDataLength -= 10;
            length -= 10;
            if (this.messageDataLength == 0)
            {
                if (this.messageHeader.MessageType == MessageType.DataMessage)
                {
                    this.dataMessageHandler(this.messageHeader, new SecsMessage(this.messageHeader.S, this.messageHeader.F, string.Empty, replyExpected: this.messageHeader.ReplyExpected));
                }
                else
                {
                    this.controlMessageHandler(this.messageHeader);
                }

                return(0);
            }

            if (length >= this.messageDataLength)
            {
                Trace.WriteLine("Get Complete Data Message with total data");
                this.dataMessageHandler(this.messageHeader, new SecsMessage(this.messageHeader.S, this.messageHeader.F, string.Empty, StreamDecoder.BufferedDecodeItem(this.Buffer, ref this.decodeIndex), this.messageHeader.ReplyExpected));
                length -= (int)this.messageDataLength;
                this.messageDataLength = 0;
                return(0);                //completeWith message received
            }
            return(this.DecoderStep2GetItemHeader(ref length, out need));
        }
Beispiel #2
0
        /// <summary>
        /// Decoder step 2: get _format + lengthBits(2bit) 1 byte
        /// </summary>
        /// <param name="length"></param>
        /// <param name="need"></param>
        /// <returns>The decoder step to execute next.</returns>
        private int DecoderStep2GetItemHeader(ref int length, out int need)
        {
            if (!StreamDecoder.CheckAvailable(length, 1, out need))
            {
                return(2);
            }

            this.format     = (SecsFormat)(this.Buffer[this.decodeIndex] & 0xFC);
            this.lengthBits = (byte)(this.Buffer[this.decodeIndex] & 3);
            this.decodeIndex++;
            this.messageDataLength--;
            length--;
            return(this.DecoderStep3GetItemLength(ref length, out need));
        }
Beispiel #3
0
        /// <summary>
        /// Decoder step 0: get total message length 4 bytes
        /// </summary>
        /// <param name="length"></param>
        /// <param name="need"></param>
        /// <returns>The decoder step to execute next.</returns>
        private int DecoderStep0GetTotalMessageLength(ref int length, out int need)
        {
            if (!StreamDecoder.CheckAvailable(length, 4, out need))
            {
                return(0);
            }

            Array.Reverse(this.Buffer, this.decodeIndex, 4);
            this.messageDataLength = BitConverter.ToUInt32(this.Buffer, this.decodeIndex);
            Trace.WriteLine($"Get Message Length: {this.messageDataLength}");
            this.decodeIndex += 4;
            length           -= 4;
            return(this.DecoderStep1GetMessageHeader(ref length, out need));
        }
Beispiel #4
0
        /// <summary>
        /// Decoder step 3: get _itemLength _lengthBits bytes, at most 3 byte
        /// </summary>
        /// <param name="length"></param>
        /// <param name="need"></param>
        /// <returns>The decoder step to execute next.</returns>
        private int DecoderStep3GetItemLength(ref int length, out int need)
        {
            if (!StreamDecoder.CheckAvailable(length, this.lengthBits, out need))
            {
                return(3);
            }

            Array.Copy(this.Buffer, this.decodeIndex, this.itemLengthBytes, 0, this.lengthBits);
            Array.Reverse(this.itemLengthBytes, 0, this.lengthBits);

            this.itemLength = BitConverter.ToInt32(this.itemLengthBytes, 0);
            Array.Clear(this.itemLengthBytes, 0, 4);
            Trace.WriteLineIf(this.format != SecsFormat.List, $"Get format: {this.format}, length: {this.itemLength}");

            this.decodeIndex       += this.lengthBits;
            this.messageDataLength -= this.lengthBits;
            length -= this.lengthBits;
            return(this.DecoderStep4GetItem(ref length, out need));
        }
Beispiel #5
0
        /// <summary>
        /// Decoder step 4: get item value
        /// </summary>
        /// <param name="length"></param>
        /// <param name="need"></param>
        /// <returns>The decoder step to execute next.</returns>
        private int DecoderStep4GetItem(ref int length, out int need)
        {
            need = 0;
            Item item;

            if (this.format == SecsFormat.List)
            {
                if (this.itemLength == 0)
                {
                    item = Item.L();
                }
                else
                {
                    this.stack.Push(new List <Item>(this.itemLength));
                    return(this.DecoderStep2GetItemHeader(ref length, out need));
                }
            }
            else
            {
                if (!StreamDecoder.CheckAvailable(length, this.itemLength, out need))
                {
                    return(4);
                }

                item = Item.BytesDecode(this.format, this.Buffer, this.decodeIndex, this.itemLength);
                Trace.WriteLine($"Complete Item: {this.format}");

                this.decodeIndex       += this.itemLength;
                this.messageDataLength -= (uint)this.itemLength;
                length -= this.itemLength;
            }

            if (this.stack.Count == 0)
            {
                Trace.WriteLine("Get Complete Data Message by stream decoded");
                this.dataMessageHandler(this.messageHeader, new SecsMessage(this.messageHeader.S, this.messageHeader.F, string.Empty, item, this.messageHeader.ReplyExpected));
                return(0);
            }

            var list = this.stack.Peek();

            list.Add(item);
            while (list.Count == list.Capacity)
            {
                item = Item.L(this.stack.Pop());
                Trace.WriteLine($"Complete List: {item.Count}");
                if (this.stack.Count > 0)
                {
                    list = this.stack.Peek();
                    list.Add(item);
                }
                else
                {
                    Trace.WriteLine("Get Complete Data Message by stream decoded");
                    this.dataMessageHandler(this.messageHeader, new SecsMessage(this.messageHeader.S, this.messageHeader.F, string.Empty, item, this.messageHeader.ReplyExpected));
                    return(0);
                }
            }

            return(this.DecoderStep2GetItemHeader(ref length, out need));
        }