Exemple #1
0
        private static MetaStructure MakeStructureWithComplexReferencedData()
        {
            var structureWithComplexReferenceDataInfo = new StructureInfo_GTA5_pc();
            var structureWithComplexReferenceData     = new MetaStructure(null, structureWithComplexReferenceDataInfo);

            structureWithComplexReferenceData.Values = new Dictionary <int, IMetaValue>();
            structureWithComplexReferenceData.Values.Add(unchecked ((int)0x6F004ECC), MakeStructureArray());
            structureWithComplexReferenceData.Values.Add(unchecked ((int)0x8F3E7BA7), MakeStructurePointerArray());
            return(structureWithComplexReferenceData);
        }
        public void AssertStructure(MetaStructure expectedStructure, MetaStructure actualStructure)
        {
            var expectedValues = expectedStructure.Values;
            var actualValues   = actualStructure.Values;

            Assert.AreEqual(expectedValues.Count, actualValues.Count);
            foreach (var key in expectedValues.Keys)
            {
                AssertValue(expectedValues[key], actualValues[key]);
            }
        }
Exemple #3
0
 private void WriteStructureContentXml(MetaStructure value, XmlWriter writer)
 {
     foreach (var field in value.Values)
     {
         var fieldNameHash = field.Key;
         var fieldValue    = field.Value;
         writer.WriteStartElement(GetNameForHash(fieldNameHash));
         WriteStructureElementContentXml(fieldValue, writer);
         writer.WriteEndElement();
     }
 }
Exemple #4
0
        public static MetaStructure MakeDataset()
        {
            var valueInfo = new StructureInfo_GTA5_pc();

            valueInfo.StructureNameHash = 0x22DD6F04;

            var rootStructure = new MetaStructure(null, valueInfo);

            rootStructure.Values = new Dictionary <int, IMetaValue>();
            rootStructure.Values.Add(unchecked ((int)0x38C62F77), MakeStructureWithSimpleData());
            rootStructure.Values.Add(unchecked ((int)0x97CC848A), MakeStructureWithEnumData());
            rootStructure.Values.Add(0x3A5B9F33, MakeStructureWithSimpleReferencedData());
            rootStructure.Values.Add(0x53663957, MakeStructureWithComplexReferencedData());
            return(rootStructure);
        }
Exemple #5
0
        private static MetaStructure MakeStructureWithSimpleData()
        {
            var structureWithSimpleTypesInfo = new StructureInfo_GTA5_pc();
            var structureWithSimpleTypes     = new MetaStructure(null, structureWithSimpleTypesInfo);

            structureWithSimpleTypes.Values = new Dictionary <int, IMetaValue>();
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x36C55540), new MetaBoolean(false));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x707975FF), new MetaBoolean(true));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x96142337), new MetaByte_A(-128));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xD4D9059D), new MetaByte_A(-127));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x710D0955), new MetaByte_A(126));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x860ACDD8), new MetaByte_A(127));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xCDFD7789), new MetaByte_B(0));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x7DCCF225), new MetaByte_B(1));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xA0AB9B78), new MetaByte_B(254));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x3A223898), new MetaByte_B(255));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x2F07F270), new MetaInt16_A(-32768));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x83E5053E), new MetaInt16_A(-32767));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x86F3BC1E), new MetaInt16_A(32766));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x2C916F02), new MetaInt16_A(32767));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x1972DD39), new MetaInt16_B(0));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x1433E9A2), new MetaInt16_B(1));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xABF22E97), new MetaInt16_B(65534));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xCAD920FA), new MetaInt16_B(65535));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x96AA9C22), new MetaInt32_A(-2147483648));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xBE498F77), new MetaInt32_A(-2147483647));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xDEA66123), new MetaInt32_A(2147483646));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xA7A347FE), new MetaInt32_A(2147483647));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x5940A2C4), new MetaInt32_B(0));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x7AE8E34B), new MetaInt32_B(1));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x48758F24), new MetaInt32_B(4294967294));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x2DCCF53B), new MetaInt32_B(4294967295));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x7C6BAA24), new MetaFloat(1.2f));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xC81C39E6), new MetaFloat(12.0f));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xC599B2B0), new MetaFloat4_XYZ(1.2f, 3.4f, 5.6f));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xA2B4F045), new MetaFloat4_XYZ(12.0f, 34.0f, 56.0f));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xE0B18333), new MetaFloat4_XYZW(1.2f, 3.4f, 5.6f, 7.8f));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0xA7E3D660), new MetaFloat4_XYZW(12.0f, 34.0f, 56.0f, 78.0f));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x3B8AF0C2), new MetaArrayOfBytes(new byte[] { 0, 1, 254, 255 }));
            var charinfo = new StructureEntryInfo_GTA5_pc();

            charinfo.ReferenceKey = 64;
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x8FF34AB5), new MetaArrayOfChars(charinfo, "A String"));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x17525AB1), new MetaInt32_Hash(unchecked ((int)0xF63A8BC0)));
            structureWithSimpleTypes.Values.Add(unchecked ((int)0x10D59C62), new MetaInt32_Hash(0));
            return(structureWithSimpleTypes);
        }
Exemple #6
0
        private static MetaStructure MakeStructureWithEnumData()
        {
            var structureWithEnumsInfo = new StructureInfo_GTA5_pc();
            var structureWithEnums     = new MetaStructure(null, structureWithEnumsInfo);

            structureWithEnums.Values = new Dictionary <int, IMetaValue>();
            structureWithEnums.Values.Add(unchecked ((int)0x2300AF3B), MakeByteEnum());
            structureWithEnums.Values.Add(unchecked ((int)0x56E94C50), MakeIntEnumA());
            structureWithEnums.Values.Add(unchecked ((int)0x43F0EEF4), MakeIntEnumB());
            structureWithEnums.Values.Add(unchecked ((int)0xB4B7824B), MakeShortFlagsA());
            structureWithEnums.Values.Add(unchecked ((int)0x1B3098A9), MakeShortFlagsB());
            structureWithEnums.Values.Add(unchecked ((int)0xA51CF61E), MakeIntFlags1A());
            structureWithEnums.Values.Add(unchecked ((int)0x11045D33), MakeIntFlags1B());
            structureWithEnums.Values.Add(unchecked ((int)0xC66A7EC6), MakeIntFlags2A());
            structureWithEnums.Values.Add(unchecked ((int)0x53C471C0), MakeIntFlags2B());
            structureWithEnums.Values.Add(unchecked ((int)0x89D91A45), MakeIntFlags2C());
            return(structureWithEnums);
        }
Exemple #7
0
        private static MetaStructure MakeStructureWithSimpleReferencedData()
        {
            var structureWithSimpleReferenceDataInfo = new StructureInfo_GTA5_pc();
            var structureWithSimpleReferenceData     = new MetaStructure(null, structureWithSimpleReferenceDataInfo);

            structureWithSimpleReferenceData.Values = new Dictionary <int, IMetaValue>();
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0xEF099C3A), MakeCharArray());
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0x79FE4E42), MakeShortArray());
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0x62AFD2A7), MakeIntArray());
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0x8FD208FE), MakeFloatArray());
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0xD094EFE2), MakeFloatVectorArray());
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0x68B43521), MakeHashArray());
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0x3A6E4591), new MetaCharPointer("A String"));
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0xC9811541), new MetaCharPointer(null));
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0xC8C01542), new MetaDataBlockPointer(null, new byte[] { 0, 1, 254, 255 }));
            structureWithSimpleReferenceData.Values.Add(unchecked ((int)0x2FCAB965), new MetaDataBlockPointer(null, null));
            return(structureWithSimpleReferenceData);
        }
Exemple #8
0
        private static MetaArray MakeStructurePointerArray()
        {
            var metainf111 = new StructureInfo_GTA5_pc();

            metainf111.StructureNameHash = 0x2D8B6A9C;
            MetaStructure metasubstr1 = new MetaStructure(null, metainf111);

            metasubstr1.Values = new Dictionary <int, IMetaValue>();
            metasubstr1.Values.Add(unchecked ((int)0x04792618), new MetaBoolean(false));
            metasubstr1.Values.Add(unchecked ((int)0xD302778A), new MetaBoolean(true));
            MetaGeneric pointerValue1 = new MetaGeneric();

            pointerValue1.Value = metasubstr1;

            var metainf222 = new StructureInfo_GTA5_pc();

            metainf222.StructureNameHash = unchecked ((int)0xA71A1B09);
            MetaStructure metasubstr2 = new MetaStructure(null, metainf222);

            metasubstr2.Values = new Dictionary <int, IMetaValue>();
            metasubstr2.Values.Add(unchecked ((int)0x8705BF6F), new MetaBoolean(true));
            metasubstr2.Values.Add(unchecked ((int)0x981F3DBC), new MetaBoolean(false));
            MetaGeneric pointerValue2 = new MetaGeneric();

            pointerValue2.Value = metasubstr2;

            MetaGeneric pointerValue3 = new MetaGeneric();

            pointerValue3.Value = null;

            MetaArray pointerArray = new MetaArray();

            pointerArray.info          = new StructureEntryInfo_GTA5_pc();
            pointerArray.info.DataType = StructureEntryDataType.Structure;
            pointerArray.Entries       = new List <IMetaValue>();
            pointerArray.Entries.Add(pointerValue1);
            pointerArray.Entries.Add(pointerValue2);
            pointerArray.Entries.Add(pointerValue3);
            return(pointerArray);
        }
Exemple #9
0
        private static MetaArray MakeStructureArray()
        {
            MetaStructure substr1 = new MetaStructure(null, null);

            substr1.Values = new Dictionary <int, IMetaValue>();
            substr1.Values.Add(unchecked ((int)0x620795CF), new MetaBoolean(false));
            substr1.Values.Add(unchecked ((int)0x2518B65F), new MetaBoolean(true));

            MetaStructure substr2 = new MetaStructure(null, null);

            substr2.Values = new Dictionary <int, IMetaValue>();
            substr2.Values.Add(unchecked ((int)0x620795CF), new MetaBoolean(true));
            substr2.Values.Add(unchecked ((int)0x2518B65F), new MetaBoolean(false));

            MetaArray structureArray = new MetaArray();

            structureArray.info          = new StructureEntryInfo_GTA5_pc();
            structureArray.info.DataType = StructureEntryDataType.Structure;
            structureArray.Entries       = new List <IMetaValue>();
            structureArray.Entries.Add(substr1);
            structureArray.Entries.Add(substr2);
            return(structureArray);
        }
        public MetaStructure ParseStructure(XmlNode node, MetaStructureXml info)
        {
            MetaStructure resultStructure = null;

            foreach (var x in strList)
            {
                if (x.StructureKey == info.Key)
                {
                    resultStructure = new MetaStructure(null, x);
                }
            }
            resultStructure.Values = new Dictionary <int, IMetaValue>();

            foreach (var xmlEntry in info.Entries)
            {
                XmlNode xmlNode = null;
                foreach (XmlNode x in node.ChildNodes)
                {
                    var hash = GetHashForName(x.Name);
                    if (hash == xmlEntry.NameHash)
                    {
                        xmlNode = x;
                    }
                }

                StructureEntryInfo_GTA5_pc entryInfo = null;
                foreach (var x in resultStructure.info.Entries)
                {
                    if (x.EntryNameHash == xmlEntry.NameHash)
                    {
                        entryInfo = x;
                    }
                }

                var type = (StructureEntryDataType)xmlEntry.Type;
                if (type == StructureEntryDataType.Array)
                {
                    var arrayType = (StructureEntryDataType)xmlEntry.ArrayType.Type;
                    if (arrayType == StructureEntryDataType.StructurePointer)
                    {
                        MetaArray arrayValue = ReadPointerArray(xmlNode);
                        arrayValue.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arrayValue);
                    }
                    if (arrayType == StructureEntryDataType.Structure)
                    {
                        MetaArray arryVal = ReadStructureArray(xmlNode, xmlEntry.ArrayType.TypeHash);
                        arryVal.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    if (arrayType == StructureEntryDataType.UnsignedByte)
                    {
                        MetaArray arryVal = ReadByteArray(xmlNode);
                        arryVal.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    if (arrayType == StructureEntryDataType.UnsignedShort)
                    {
                        MetaArray arryVal = ReadShortArray(xmlNode);
                        arryVal.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    if (arrayType == StructureEntryDataType.UnsignedInt)
                    {
                        MetaArray arryVal = ReadIntArray(xmlNode);
                        arryVal.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    if (arrayType == StructureEntryDataType.Float)
                    {
                        MetaArray arryVal = ReadFloatArray(xmlNode);
                        arryVal.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    if (arrayType == StructureEntryDataType.Float_XYZ)
                    {
                        MetaArray arryVal = ReadFloatVectorArray(xmlNode);
                        arryVal.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                    if (arrayType == StructureEntryDataType.Hash)
                    {
                        MetaArray arryVal = ReadHashArray(xmlNode);
                        arryVal.info = resultStructure.info.Entries[entryInfo.ReferenceTypeIndex];
                        resultStructure.Values.Add(xmlEntry.NameHash, arryVal);
                    }
                }


                if (type == StructureEntryDataType.Boolean)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadBoolean(xmlNode));
                }
                if (type == StructureEntryDataType.SignedByte)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadSignedByte(xmlNode));
                }
                if (type == StructureEntryDataType.UnsignedByte)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadUnsignedByte(xmlNode));
                }
                if (type == StructureEntryDataType.SignedShort)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadSignedShort(xmlNode));
                }
                if (type == StructureEntryDataType.UnsignedShort)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadUnsignedShort(xmlNode));
                }
                if (type == StructureEntryDataType.SignedInt)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadSignedInt(xmlNode));
                }
                if (type == StructureEntryDataType.UnsignedInt)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadUnsignedInt(xmlNode));
                }
                if (type == StructureEntryDataType.Float)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadFloat(xmlNode));
                }
                if (type == StructureEntryDataType.Float_XYZ)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadFloatXYZ(xmlNode));
                }
                if (type == StructureEntryDataType.Float_XYZW)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadFloatXYZW(xmlNode));
                }
                if (type == StructureEntryDataType.ByteEnum)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadByteEnum(xmlNode, entryInfo.ReferenceKey));
                }
                if (type == StructureEntryDataType.IntEnum)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadIntEnum(xmlNode, entryInfo.ReferenceKey));
                }
                if (type == StructureEntryDataType.ShortFlags)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadShortFlags(xmlNode, entryInfo.ReferenceKey));
                }
                if (type == StructureEntryDataType.IntFlags1)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadIntFlags1(xmlNode, entryInfo.ReferenceKey));
                }
                if (type == StructureEntryDataType.IntFlags2)
                {
                    resultStructure.Values.Add(xmlEntry.NameHash, ReadIntFlags2(xmlNode, entryInfo.ReferenceKey));
                }



                if (type == StructureEntryDataType.ArrayOfBytes)
                {
                    var byteArrayValue = new MetaArrayOfBytes();
                    byteArrayValue.Value = ByteFromString(xmlNode.InnerText);
                    resultStructure.Values.Add(xmlEntry.NameHash, byteArrayValue);
                }
                if (type == StructureEntryDataType.ArrayOfChars)
                {
                    var charArrayValue = new MetaArrayOfChars(entryInfo);
                    charArrayValue.Value = xmlNode.InnerText;
                    resultStructure.Values.Add(xmlEntry.NameHash, charArrayValue);
                }
                if (type == StructureEntryDataType.Hash)
                {
                    var hashValue = new MetaInt32_Hash();
                    if (xmlNode.InnerText.Trim().Length > 0)
                    {
                        hashValue.Value = GetHashForName(xmlNode.InnerText);
                    }
                    resultStructure.Values.Add(xmlEntry.NameHash, hashValue);
                }
                if (type == StructureEntryDataType.CharPointer)
                {
                    var charPointerValue = new MetaCharPointer();
                    charPointerValue.Value = xmlNode.InnerText;
                    if (charPointerValue.Value.Equals(""))
                    {
                        charPointerValue.Value = null;
                    }
                    resultStructure.Values.Add(xmlEntry.NameHash, charPointerValue);
                }
                if (type == StructureEntryDataType.DataBlockPointer)
                {
                    var dataBlockValue = new MetaDataBlockPointer(entryInfo);
                    dataBlockValue.Data = ByteFromString(xmlNode.InnerText);
                    if (dataBlockValue.Data.Length == 0)
                    {
                        dataBlockValue.Data = null;
                    }
                    resultStructure.Values.Add(xmlEntry.NameHash, dataBlockValue);
                }
                if (type == StructureEntryDataType.Structure)
                {
                    var xmlInfo        = FindAndCheckStructure(xmlEntry.TypeHash, xmlNode);
                    var structureValue = ParseStructure(xmlNode, xmlInfo);
                    resultStructure.Values.Add(xmlEntry.NameHash, structureValue);
                }
            }

            return(resultStructure);
        }
Exemple #11
0
        private void WriteStructure(MetaDataWriter writer, MetaStructure value)
        {
            var updateStack = new Stack <IMetaValue>();

            // build stack for update...
            var structuresToCheck = new Stack <MetaStructure>();

            structuresToCheck.Push(value);
            while (structuresToCheck.Count > 0)
            {
                var structureToCheck = structuresToCheck.Pop();

                // add structure to list of occurring structures
                usedStructureKeys.Add(structureToCheck.info.StructureKey);

                foreach (var structureEntryToCheck in structureToCheck.Values)
                {
                    if (structureEntryToCheck.Value is MetaArray)
                    {
                        updateStack.Push(structureEntryToCheck.Value);

                        var arrayStructureEntryToCheck = structureEntryToCheck.Value as MetaArray;
                        if (arrayStructureEntryToCheck.Entries != null)
                        {
                            for (int k = arrayStructureEntryToCheck.Entries.Count - 1; k >= 0; k--)
                            {
                                var x = arrayStructureEntryToCheck.Entries[k];
                                if (x is MetaStructure)
                                {
                                    structuresToCheck.Push(x as MetaStructure);
                                }
                                if (x is MetaGeneric)
                                {
                                    updateStack.Push(x);
                                    structuresToCheck.Push((MetaStructure)(x as MetaGeneric).Value);
                                }
                            }
                        }
                    }
                    if (structureEntryToCheck.Value is MetaCharPointer)
                    {
                        updateStack.Push(structureEntryToCheck.Value);
                    }
                    if (structureEntryToCheck.Value is MetaDataBlockPointer)
                    {
                        updateStack.Push(structureEntryToCheck.Value);
                    }
                    if (structureEntryToCheck.Value is MetaGeneric)
                    {
                        updateStack.Push(structureEntryToCheck.Value);

                        var genericStructureEntryToCheck = structureEntryToCheck.Value as MetaGeneric;
                        structuresToCheck.Push((MetaStructure)genericStructureEntryToCheck.Value);
                    }
                    if (structureEntryToCheck.Value is MetaStructure)
                    {
                        structuresToCheck.Push((MetaStructure)structureEntryToCheck.Value);
                    }
                }
            }

            // update structures...
            while (updateStack.Count > 0)
            {
                var v = updateStack.Pop();
                if (v is MetaArray)
                {
                    var arrayValue = (MetaArray)v;
                    if (arrayValue.Entries != null)
                    {
                        if (arrayValue.info.DataType == StructureEntryDataType.Structure)
                        {
                            // WORKAROUND
                            if (arrayValue.IsAlwaysAtZeroOffset)
                            {
                                writer.CreateBlockByNameHash(arrayValue.info.ReferenceKey);
                                writer.Position = writer.Length;
                            }
                            else
                            {
                                writer.SelectBlockByNameHash(arrayValue.info.ReferenceKey);
                                writer.Position = writer.Length;
                            }
                        }
                        else
                        {
                            writer.SelectBlockByNameHash((int)arrayValue.info.DataType);
                            writer.Position = writer.Length;
                        }
                        arrayValue.BlockIndex      = writer.BlockIndex + 1;
                        arrayValue.Offset          = (int)writer.Position;
                        arrayValue.NumberOfEntries = arrayValue.Entries.Count;
                        foreach (var entry in arrayValue.Entries)
                        {
                            entry.Write(writer);
                        }
                    }
                    else
                    {
                        arrayValue.BlockIndex      = 0;
                        arrayValue.Offset          = 0;
                        arrayValue.NumberOfEntries = 0;
                    }
                }
                if (v is MetaCharPointer)
                {
                    var charPointerValue = (MetaCharPointer)v;
                    if (charPointerValue.Value != null)
                    {
                        writer.SelectBlockByNameHash(0x10);
                        writer.Position = writer.Length;
                        charPointerValue.DataBlockIndex = writer.BlockIndex + 1;
                        charPointerValue.DataOffset     = (int)writer.Position;
                        charPointerValue.StringLength   = charPointerValue.Value.Length;
                        charPointerValue.StringCapacity = charPointerValue.Value.Length + 1;
                        writer.Write(charPointerValue.Value);
                    }
                    else
                    {
                        charPointerValue.DataBlockIndex = 0;
                        charPointerValue.DataOffset     = 0;
                        charPointerValue.StringLength   = 0;
                        charPointerValue.StringCapacity = 0;
                    }
                }
                if (v is MetaDataBlockPointer)
                {
                    var charPointerValue = (MetaDataBlockPointer)v;
                    if (charPointerValue.Data != null)
                    {
                        writer.CreateBlockByNameHash(0x11);
                        writer.Position             = 0;
                        charPointerValue.BlockIndex = writer.BlockIndex + 1;
                        writer.Write(charPointerValue.Data);
                    }
                    else
                    {
                        charPointerValue.BlockIndex = 0;
                    }
                }
                if (v is MetaGeneric)
                {
                    var genericValue = (MetaGeneric)v;
                    writer.SelectBlockByNameHash(((MetaStructure)genericValue.Value).info.StructureNameHash);
                    writer.Position         = writer.Length;
                    genericValue.BlockIndex = writer.BlockIndex + 1;
                    genericValue.Offset     = (int)writer.Position / 16;
                    genericValue.Value.Write(writer);
                }
            }

            // now only the root itself is left...
            writer.SelectBlockByNameHash(value.info.StructureNameHash);
            writer.Position = writer.Length;
            value.Write(writer);
        }