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);
        }