public StreamDecoder(int streamBufferSize, Action <MessageHeader> controlMsgHandler, Action <MessageHeader, SecsMessage> dataMsgHandler) { _buffer = new byte[streamBufferSize]; _bufferOffset = 0; _decodeIndex = 0; _dataMsgHandler = dataMsgHandler; _controlMsgHandler = controlMsgHandler; _decoders = new Decoder[] { GetTotalMessageLength, GetMessageHeader, GetItemHeader, GetItemLength, GetItem, }; // 0: get total message length 4 bytes int GetTotalMessageLength(ref int length, out int need) { if (!CheckAvailable(ref length, 4, out need)) { return(0); } Array.Reverse(_buffer, _decodeIndex, 4); _messageDataLength = BitConverter.ToUInt32(_buffer, _decodeIndex); Trace.WriteLine($"Get Message Length: {_messageDataLength}"); _decodeIndex += 4; length -= 4; return(GetMessageHeader(ref length, out need)); } // 1: get message header 10 bytes int GetMessageHeader(ref int length, out int need) { if (!CheckAvailable(ref length, 10, out need)) { return(1); } _msgHeader = MessageHeader.Decode(_buffer, _decodeIndex); _decodeIndex += 10; _messageDataLength -= 10; length -= 10; if (_messageDataLength == 0) { if (_msgHeader.MessageType == MessageType.DataMessage) { _dataMsgHandler(_msgHeader, new SecsMessage(_msgHeader.S, _msgHeader.F, _msgHeader.ReplyExpected, string.Empty)); } else { _controlMsgHandler(_msgHeader); } return(0); } if (length >= _messageDataLength) { Trace.WriteLine("Get Complete Data Message with total data"); _dataMsgHandler(_msgHeader, new SecsMessage(_msgHeader.S, _msgHeader.F, _msgHeader.ReplyExpected, string.Empty, BufferedDecodeItem(_buffer, ref _decodeIndex))); length -= (int)_messageDataLength; _messageDataLength = 0; return(0); //completeWith message received } return(GetItemHeader(ref length, out need)); } // 2: get _format + lengthBits(2bit) 1 byte int GetItemHeader(ref int length, out int need) { if (!CheckAvailable(ref length, 1, out need)) { return(2); } _format = (SecsFormat)(_buffer[_decodeIndex] & 0xFC); _lengthBits = (byte)(_buffer[_decodeIndex] & 3); _decodeIndex++; _messageDataLength--; length--; return(GetItemLength(ref length, out need)); } // 3: get _itemLength _lengthBits bytes, at most 3 byte int GetItemLength(ref int length, out int need) { if (!CheckAvailable(ref length, _lengthBits, out need)) { return(3); } Array.Copy(_buffer, _decodeIndex, _itemLengthBytes, 0, _lengthBits); Array.Reverse(_itemLengthBytes, 0, _lengthBits); _itemLength = BitConverter.ToInt32(_itemLengthBytes, 0); Array.Clear(_itemLengthBytes, 0, 4); Trace.WriteLineIf(_format != SecsFormat.List, $"Get format: {_format}, length: {_itemLength}"); _decodeIndex += _lengthBits; _messageDataLength -= _lengthBits; length -= _lengthBits; return(GetItem(ref length, out need)); } // 4: get item value int GetItem(ref int length, out int need) { need = 0; Item item; if (_format == SecsFormat.List) { if (_itemLength == 0) { item = Item.L(); } else { _stack.Push(new List <Item>(_itemLength)); return(GetItemHeader(ref length, out need)); } } else { if (!CheckAvailable(ref length, _itemLength, out need)) { return(4); } item = Item.BytesDecode(ref _format, _buffer, ref _decodeIndex, ref _itemLength); Trace.WriteLine($"Complete Item: {_format}"); _decodeIndex += _itemLength; _messageDataLength -= (uint)_itemLength; length -= _itemLength; } if (_stack.Count == 0) { Trace.WriteLine("Get Complete Data Message by stream decoded"); _dataMsgHandler(_msgHeader, new SecsMessage(_msgHeader.S, _msgHeader.F, _msgHeader.ReplyExpected, string.Empty, item)); return(0); } var list = _stack.Peek(); list.Add(item); while (list.Count == list.Capacity) { item = Item.L(_stack.Pop()); Trace.WriteLine($"Complete List: {item.Count}"); if (_stack.Count > 0) { list = _stack.Peek(); list.Add(item); } else { Trace.WriteLine("Get Complete Data Message by stream decoded"); _dataMsgHandler(_msgHeader, new SecsMessage(_msgHeader.S, _msgHeader.F, _msgHeader.ReplyExpected, string.Empty, item)); return(0); } } return(GetItemHeader(ref length, out need)); } bool CheckAvailable(ref int length, int required, out int need) { need = required - length; if (need > 0) { return(false); } need = 0; return(true); } }
internal PrimaryMessageWrapper(SecsGem secsGem, MessageHeader header, SecsMessage msg) { _secsGem = secsGem; _header = header; Message = msg; }
internal PrimaryMessageWrapper(SecsGem secsGem, MessageHeader header, SecsMessage message) { this.weakReferenceSecsGem = new WeakReference <SecsGem>(secsGem); this.header = header; this.Message = message; }
internal PrimaryMessageWrapper(SecsGem secsGem, MessageHeader header, SecsMessage msg) { _secsGem = secsGem; _header = header; Message = msg; }