public void Decompile() { NameDataReader = new IO.EndianReader( new MemoryStream(NameData, writable: false), Shell.EndianFormat.Little, name: "NameDataReader"); ValueDataPool = new BinaryDataTreeMemoryPool(ValueData); Nodes = new List <BinaryDataTreeBuildNode>(PackedNodes.Length); for (int x = 0; x < PackedNodes.Length; x++) { Nodes.Add(new BinaryDataTreeBuildNode()); } for (int x = 0; x < PackedNodes.Length; x++) { var packed_node = PackedNodes[x]; var build_node = Nodes[x]; build_node.SetParent(this, packed_node); int num_child_nodes; CalculateChildNodesCount(x, out num_child_nodes); build_node.SetChildren(this, packed_node, num_child_nodes); int num_name_values; CalculateNameValuesCount(x, out num_name_values); if (num_name_values == 0) { throw new InvalidDataException("No name-values: #" + x); } build_node.SetNameValues(this, packed_node, num_name_values); } Util.DisposeAndNull(ref NameDataReader); }
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()); } }