internal PoolEntry DeBuffer(BinaryDataTreeNameValue nameValue)
        {
            var  type_desc        = nameValue.GuessTypeDesc();
            uint offset           = nameValue.Offset;
            bool size_is_indirect = nameValue.SizeIsIndirect;

            return(DeBuffer(type_desc, offset, size_is_indirect));
        }
        internal void Read(BinaryDataTreeMemoryPool pool, BinaryDataTreeNameValue nameValue)
        {
            TypeDesc = nameValue.GuessTypeDesc();

            bool direct_encoding = nameValue.DirectEncoding;

            uint total_data_size = nameValue.Size;

            if (nameValue.SizeIsIndirect)
            {
                if (direct_encoding)
                {
                    throw new InvalidOperationException();
                }

                total_data_size = pool.GetSizeValue(nameValue.Offset);

                if (total_data_size < BinaryDataTreeNameValue.kIndirectSizeThreshold)
                {
                    throw new InvalidOperationException();
                }
            }

            if (TypeDesc.SizeOf > 0)
            {
                if ((total_data_size % TypeDesc.SizeOf) != 0)
                {
                    throw new InvalidOperationException(nameValue.ToString());
                }

                ArrayLength = (int)(total_data_size / TypeDesc.SizeOf);
            }

            if (ArrayLength > 1)
            {
                if (Type != BinaryDataTreeVariantType.String)
                {
                    OpaqueArrayRef = TypeDesc.MakeArray(ArrayLength);
                }

                pool.InternalBuffer.Seek(nameValue.Offset);
            }

            switch (Type)
            {
            case BinaryDataTreeVariantType.Null:
                break;

            case BinaryDataTreeVariantType.Bool:
                if (ArrayLength > 1)
                {
                    TypeDesc.ReadArray(pool.InternalBuffer, OpaqueArrayRef);
                }
                else
                {
                    this.Bool = nameValue.Bool;
                }
                break;

            case BinaryDataTreeVariantType.Int:
                if (ArrayLength > 1)
                {
                    TypeDesc.ReadArray(pool.InternalBuffer, OpaqueArrayRef);
                }
                else
                {
                    if (TypeDesc.SizeOf < sizeof(long))
                    {
                        this.Int = nameValue.Int;
                    }
                    else
                    {
                        this.Int64 = pool.InternalBuffer.ReadUInt64();
                    }
                }
                break;

            case BinaryDataTreeVariantType.Float:
                if (ArrayLength > 1)
                {
                    TypeDesc.ReadArray(pool.InternalBuffer, OpaqueArrayRef);
                }
                else
                {
                    if (TypeDesc.SizeOf < sizeof(double))
                    {
                        this.Single = nameValue.Single;
                    }
                    else
                    {
                        this.Double = pool.InternalBuffer.ReadDouble();
                    }
                }
                break;

            case BinaryDataTreeVariantType.String:
                ArrayLength = 1;
                if (!IsUnicode && total_data_size <= sizeof(uint))
                {
                    var sb = new System.Text.StringBuilder();
                    for (uint x = 0, v = nameValue.Int; x < sizeof(uint); x++, v >>= Bits.kByteBitCount)
                    {
                        sb.Append((char)(v & 0xFF));
                    }

                    this.String = sb.ToString();
                }
                else
                {
                    this.String = pool.InternalBuffer.ReadString(IsUnicode
                                                        ? Memory.Strings.StringStorage.CStringUnicode
                                                        : Memory.Strings.StringStorage.CStringAscii);
                }
                break;

            default: throw new KSoft.Debug.UnreachableException(Type.ToString());
            }
        }