public ulong GetEnumerableLength(ReadOnlySpan <byte> bytes)
        {
            if (bytes.Length == 1)
            {
                return(bytes[0]);
            }
            else if (bytes.Length == 2)
            {
                return(BitConverter.ToUInt16(bytes));
            }
            else if (bytes.Length == 4)
            {
                return(BitConverter.ToUInt32(bytes));
            }
            else if (bytes.Length == 8)
            {
                return(BitConverter.ToUInt64(bytes));
            }
            else
            {
                ThrowHelper.ThrowBinaryException();
            }

            return(0);
        }
 public void WriteEnumerableIndex(long idx, BinaryWriter writer)
 {
     if (EnumerableIndexBytes == 1)
     {
         writer.WriteByteValue((byte)idx);
     }
     else if (EnumerableIndexBytes == 2)
     {
         writer.WriteUInt16Value((ushort)idx);
     }
     else if (EnumerableIndexBytes == 4)
     {
         writer.WriteUInt32Value((UInt32)idx);
     }
     else if (EnumerableIndexBytes == 8)
     {
         writer.WriteUInt64Value((ulong)idx);
     }
     else
     {
         ThrowHelper.ThrowBinaryException();
     }
 }
        internal bool TryForwardRead(BinaryTypeInfo typeInfo, ref int offset)
        {
            if (typeInfo.SerializeType == ClassType.Value)
            {
                if (_binaryTypeToBytesLen.ContainsKey(typeInfo.Type))
                {
                    int len = _binaryTypeToBytesLen[typeInfo.Type];
                    if (!TryRequestData(offset, len))
                    {
                        return(false);
                    }

                    offset += len;
                    return(true);
                }
                else if (typeInfo.Type == TypeEnum.Nullable)
                {
                    int curOffset = offset;
                    if (!TryReadTypeSeq(ref curOffset, out ushort typeSeq))
                    {
                        return(false);
                    }
                    if (typeSeq == TypeMap.NullTypeSeq)
                    {
                        offset = curOffset;
                        return(true);
                    }
                    if (!TryForwardRead(_typeMap.GetTypeInfo(typeSeq), ref curOffset))
                    {
                        return(false);
                    }

                    offset = curOffset;
                    return(true);
                }
                else
                {
                    if (!TrySkipBytes(ref offset))
                    {
                        return(false);
                    }
                }
            }
            else if (typeInfo.SerializeType == ClassType.Object)
            {
                int curOffset = offset;
                // 引用、非引用
                if (!TryRequestData(curOffset, 1))
                {
                    return(false);
                }

                byte _ = _buffer[curOffset++];

                if (!TryRequestData(curOffset, 4))
                {
                    return(false);
                }
                curOffset += 4;

                // 读取属性
                if (!TrySkipObjectProperties(ref curOffset))
                {
                    return(false);
                }

                offset = curOffset;
            }
            else if (typeInfo.SerializeType == ClassType.Enumerable)
            {
                int curOffset = offset;
                // 可枚举类型
                // 引用、非引用
                if (!TryRequestData(curOffset, 1))
                {
                    return(false);
                }

                byte refSign = _buffer[curOffset++];

                // 引用
                if (!TryRequestData(curOffset, 4))
                {
                    return(false);
                }
                curOffset += 4;

                // 非引用
                if (refSign == 0x00)
                {
                    // 索引长度
                    if (!TryRequestData(curOffset, 1))
                    {
                        return(false);
                    }

                    byte lenBytes = _buffer[curOffset++];
                    if (!TryRequestData(curOffset, lenBytes))
                    {
                        return(false);
                    }

                    var   lenSpan = _buffer.Slice(curOffset, lenBytes);
                    ulong len     = GetEnumerableLength(lenSpan);
                    curOffset += lenBytes;

                    // 按顺序读取
                    ulong curIdx = 0;
                    while (curIdx < len)
                    {
                        // 读取索引
                        if (!TrySkipBytes(ref curOffset, lenBytes))
                        {
                            return(false);
                        }

                        if (!TryReadTypeSeq(ref curOffset, out ushort typeSeq))
                        {
                            return(false);
                        }

                        if (typeSeq == TypeMap.NullTypeSeq)
                        {
                            continue;
                        }

                        BinaryTypeInfo ti = _typeMap.GetTypeInfo(typeSeq);
                        if (!TryForwardRead(ti, ref curOffset))
                        {
                            return(false);
                        }
                        curIdx++;
                    }
                }


                // 读取自定义属性
                if (!TrySkipObjectProperties(ref curOffset))
                {
                    return(false);
                }

                offset = curOffset;
            }
            else if (typeInfo.SerializeType == ClassType.Dictionary)
            {
                int curOffset = offset;
                // 引用、非引用
                if (!TryRequestData(curOffset, 1))
                {
                    return(false);
                }

                byte refSign = _buffer[curOffset++];

                if (!TryRequestData(curOffset, 4))
                {
                    return(false);
                }
                curOffset += 4;

                if (refSign == 0x00)
                {
                    // Key Value
                    while (true)
                    {
                        if (!TryRequestData(curOffset, 1))
                        {
                            return(false);
                        }

                        byte keySeq = _buffer[curOffset++];

                        if (keySeq == BinarySerializerConstants.EndDictionaryKey)
                        {
                            break;
                        }
                        else if (keySeq != BinarySerializerConstants.DictionaryKeySeq)
                        {
                            ThrowHelper.ThrowBinaryReaderException(ref this, ExceptionResource.InvalidByte);
                        }

                        // Key
                        if (!TryReadTypeSeq(ref curOffset, out ushort typeSeq))
                        {
                            return(false);
                        }

                        if (typeSeq != TypeMap.NullTypeSeq)
                        {
                            BinaryTypeInfo ti = _typeMap.GetTypeInfo(typeSeq);
                            if (!TryForwardRead(ti, ref curOffset))
                            {
                                return(false);
                            }
                        }

                        // Value
                        if (!TryReadTypeSeq(ref curOffset, out typeSeq))
                        {
                            return(false);
                        }

                        if (typeSeq != TypeMap.NullTypeSeq)
                        {
                            BinaryTypeInfo ti = _typeMap.GetTypeInfo(typeSeq);
                            if (!TryForwardRead(ti, ref curOffset))
                            {
                                return(false);
                            }
                        }
                    }
                }


                // 读取属性
                if (!TrySkipObjectProperties(ref curOffset))
                {
                    return(false);
                }

                offset = curOffset;
            }
            else
            {
                ThrowHelper.ThrowBinaryException();
            }

            return(true);
        }