public TlVStream?DeserializeTlvStream(ref SequenceReader <byte> reader) { if (reader.Remaining <= 0) { return(null); } var message = new TlVStream(); while (reader.Remaining > 0) { ulong recordType = reader.ReadBigSize(); ulong recordLength = reader.ReadBigSize(); if (recordLength > MAX_RECORD_SIZE) { // check the max size throw new SerializationException("Record is too large"); } if ((long)recordLength > reader.Remaining) { // check the max size throw new SerializationException("Record length exceeds the remaining message"); } // check if known type if (TryGetType(recordType, out ITlvRecordSerializer? recordSerializer)) { // type known ReadOnlySequence <byte> sequence = reader.Sequence.Slice(reader.Position, (int)recordLength); var innerReader = new SequenceReader <byte>(sequence); TlvRecord record = recordSerializer.Deserialize(ref innerReader); message.Records.Add(record); if (innerReader.Consumed != (long)recordLength) { throw new SerializationException("Record length inconsistent to tlv length"); } reader.Advance((long)recordLength); } else { // type unknown if (recordType % 2 == 0) { //if even, throw throw new MessageSerializationException("TlvSerialization error, sequence error"); } else { message.Records.Add(new TlvRecord() { Type = recordType, Size = recordLength }); // read record value (we aren't interested in these bytes so we just advance) reader.Advance((long)recordLength); } } } return(message); }