public void Serialize(Stream s)
        {
            int Magic = Tools.ReadInt(s);

            if (Magic == 0x0fb2d1ce)
            {
                Header = new DAIHeader();
                Header.Serialize(s);

                /* File GUID */
                FileGuid = new byte[16];
                s.Read(FileGuid, 0, 16);

                /* Padding */
                while (s.Position % 16 != 0)
                {
                    s.Seek(1, SeekOrigin.Current);
                }

                /* External GUIDs */
                ExternalGuids = new List <DAIExternalGuid>();
                for (int i = 0; i < Header.ExternalGuidCount; i++)
                {
                    DAIExternalGuid ExternalGuid = new DAIExternalGuid();
                    s.Read(ExternalGuid.FileGuid, 0, 16);
                    s.Read(ExternalGuid.InstanceGuid, 0, 16);

                    ExternalGuids.Add(ExternalGuid);
                }

                /* Keywords */
                KeywordDict = new Dictionary <int, string>();
                Int64 StartPos = s.Position;

                while ((s.Position - StartPos) < Header.NameLength)
                {
                    String Keyword = Tools.ReadNullString(s);
                    int    Hash    = Hasher(Keyword);

                    if (!KeywordDict.ContainsKey(Hash))
                    {
                        KeywordDict.Add(Hash, Keyword);
                    }
                }

                /* Field descriptors */
                FieldDescriptors = new List <DAIFieldDescriptor>();
                for (int i = 0; i < Header.FieldCount; i++)
                {
                    DAIFieldDescriptor CurDescriptor = new DAIFieldDescriptor();
                    CurDescriptor.Serialize(s, this);

                    FieldDescriptors.Add(CurDescriptor);
                }

                /* Complex */
                ComplexDescriptors = new List <DAIComplexDescriptor>();
                for (int i = 0; i < Header.ComplexEntryCount; i++)
                {
                    DAIComplexDescriptor CurDescriptor = new DAIComplexDescriptor();
                    CurDescriptor.Serialize(s, this);

                    ComplexDescriptors.Add(CurDescriptor);
                }

                /* Instance repeaters */
                InstanceRepeaters = new List <DAIInstanceRepeater>();
                for (int i = 0; i < Header.InstanceRepeaterCount; i++)
                {
                    DAIInstanceRepeater CurRepeater = new DAIInstanceRepeater();
                    CurRepeater.Serialize(s, this);

                    InstanceRepeaters.Add(CurRepeater);
                }

                /* Padding */
                while (s.Position % 16 != 0)
                {
                    s.Seek(1, SeekOrigin.Current);
                }

                /* Array repeaters */
                ArrayRepeaters = new List <DAIArrayRepeater>();
                for (int i = 0; i < Header.ArrayRepeaterCount; i++)
                {
                    DAIArrayRepeater CurRepeater = new DAIArrayRepeater();
                    CurRepeater.Serialize(s, this);

                    ArrayRepeaters.Add(CurRepeater);
                }

                /* Payload */
                s.Seek(Header.StringOffset + Header.StringLength, SeekOrigin.Begin);
                InternalGuids = new List <byte[]>();
                Instances     = new Dictionary <byte[], DAIComplex>();

                int Idx          = 0;
                int NonGuidIndex = 0;
                foreach (DAIInstanceRepeater CurRepeater in InstanceRepeaters)
                {
                    for (int i = 0; i < CurRepeater.Count; i++)
                    {
                        /* Alignment */
                        while ((s.Position % ComplexDescriptors[CurRepeater.ComplexDescriptorIndex].Alignment) != 0)
                        {
                            s.Seek(1, SeekOrigin.Current);
                        }

                        byte[] InstanceGuid = null;
                        if (Idx < Header.GuidRepeaterCount)
                        {
                            InstanceGuid = new byte[16];
                            s.Read(InstanceGuid, 0, 16);
                        }
                        else
                        {
                            InstanceGuid     = new byte[16];
                            InstanceGuid[12] = (byte)((NonGuidIndex >> 24) & 0xFF);
                            InstanceGuid[13] = (byte)((NonGuidIndex >> 16) & 0xFF);
                            InstanceGuid[14] = (byte)((NonGuidIndex >> 8) & 0xFF);
                            InstanceGuid[15] = (byte)((NonGuidIndex) & 0xFF);
                            NonGuidIndex++;
                        }

                        InternalGuids.Add(InstanceGuid);
                        Instances.Add(InstanceGuid, ReadComplex(s, CurRepeater.ComplexDescriptorIndex, true));
                    }

                    Idx++;
                }

                RootInstance = Instances.Values.ElementAt(0);
            }
        }
        public DAIField ReadField(Stream s, int FieldIndex)
        {
            DAIField Field = new DAIField();

            Field.Descriptor = FieldDescriptors[FieldIndex];
            Field.Offset     = s.Position;

            int FieldType = (Field.Descriptor.FieldType & 0xFFFF);

            if (FieldType == 0x29 || FieldType == 0xd029 || FieldType == 0x00 || FieldType == 0x8029)
            {
                Field.ComplexValue = ReadComplex(s, Field.Descriptor.ComplexReference);
                Field.ValueType    = DAIFieldType.DAI_Complex;
            }
            else if (FieldType == 0x407d || FieldType == 0x409d)
            {
                String StrValue     = "";
                Int64  PrevPos      = s.Position;
                int    StringOffset = Tools.ReadInt(s);

                if (StringOffset == -1)
                {
                    StrValue = "";
                }
                else
                {
                    s.Seek(Header.StringOffset + StringOffset, SeekOrigin.Begin);
                    StrValue = Tools.ReadNullString(s);

                    s.Seek(PrevPos + 4, SeekOrigin.Begin);
                }

                Field.Value = new byte[StrValue.Length];
                for (int i = 0; i < StrValue.Length; i++)
                {
                    Field.Value[i] = (byte)StrValue[i];
                }
                Field.ValueType = DAIFieldType.DAI_String;
            }
            else if (FieldType == 0x35)
            {
                uint UIntValue = Tools.ReadUInt(s);
                Field.ValueType = DAIFieldType.DAI_Guid;
                Field.Value     = BitConverter.GetBytes(UIntValue);
            }
            else if (FieldType == 0xc10d)
            {
                uint UIntValue = Tools.ReadUInt(s);
                Field.Value     = BitConverter.GetBytes(UIntValue);
                Field.ValueType = DAIFieldType.DAI_UInt;
            }
            else if (FieldType == 0xc0fd)
            {
                int IntValue = Tools.ReadInt(s);
                Field.Value     = BitConverter.GetBytes(IntValue);
                Field.ValueType = DAIFieldType.DAI_Int;
            }
            else if (FieldType == 0x417d)
            {
                Int64 LongValue = Tools.ReadLong(s);
                Field.Value     = BitConverter.GetBytes(LongValue);
                Field.ValueType = DAIFieldType.DAI_Long;
            }
            else if (FieldType == 0xc13d)
            {
                float FloatValue = Tools.ReadFloat(s);
                Field.Value     = BitConverter.GetBytes(FloatValue);
                Field.ValueType = DAIFieldType.DAI_Float;
            }
            else if (FieldType == 0xc0ad)
            {
                byte ByteValue = (byte)s.ReadByte();
                Field.Value     = new byte[] { ByteValue };
                Field.ValueType = DAIFieldType.DAI_Bool;
            }
            else if (FieldType == 0xc0bd)
            {
                byte ByteValue = (byte)s.ReadByte();
                Field.Value     = new byte[] { ByteValue };
                Field.ValueType = DAIFieldType.DAI_Byte;
            }
            else if (FieldType == 0xc0cd)
            {
                byte ByteValue = (byte)s.ReadByte();
                Field.Value     = new byte[] { ByteValue };
                Field.ValueType = DAIFieldType.DAI_UByte;
            }
            else if (FieldType == 0xc0dd)
            {
                ushort UShortValue = Tools.ReadUShort(s);
                Field.Value     = BitConverter.GetBytes(UShortValue);
                Field.ValueType = DAIFieldType.DAI_UShort;
            }
            else if (FieldType == 0xc0ed)
            {
                short ShortValue = Tools.ReadShort(s);
                Field.Value     = BitConverter.GetBytes(ShortValue);
                Field.ValueType = DAIFieldType.DAI_Short;
            }
            else if (FieldType == 0xc15d)
            {
                byte[] Value = new byte[16];
                for (int i = 0; i < 16; i++)
                {
                    Value[i] = (byte)s.ReadByte();
                }

                Field.Value     = Value;
                Field.ValueType = DAIFieldType.DAI_LongLong;
            }
            else if (FieldType == 0x89 || FieldType == 0xc089)
            {
                String EnumValue = "";

                int CompareValue = Tools.ReadInt(s);
                DAIComplexDescriptor EnumComplex = ComplexDescriptors[Field.Descriptor.ComplexReference];

                if (EnumComplex.FieldCount != 0)
                {
                    for (int i = EnumComplex.FieldStartIndex; i < EnumComplex.FieldStartIndex + EnumComplex.FieldCount; i++)
                    {
                        if (FieldDescriptors[i].PayloadOffset == CompareValue)
                        {
                            EnumValue = FieldDescriptors[i].FieldName;
                            break;
                        }
                    }
                }

                Field.Value = new byte[EnumValue.Length];
                for (int i = 0; i < EnumValue.Length; i++)
                {
                    Field.Value[i] = (byte)EnumValue[i];
                }
                Field.ValueType = DAIFieldType.DAI_Enum;
            }
            else if (FieldType == 0x41)
            {
                int Index = Tools.ReadInt(s);
                DAIArrayRepeater     ArrayRepeater    = ArrayRepeaters[Index];
                DAIComplexDescriptor ArrayComplexDesc = ComplexDescriptors[Field.Descriptor.ComplexReference];

                s.Seek(Header.ArraySectionStart + ArrayRepeater.Offset, SeekOrigin.Begin);
                DAIComplex ArrayComplex = new DAIComplex();
                ArrayComplex.Descriptor = ArrayComplexDesc;
                ArrayComplex.Offset     = s.Position;

                ArrayComplex.Fields = new List <DAIField>();
                for (int i = 0; i < ArrayRepeater.Count; i++)
                {
                    ArrayComplex.Fields.Add(ReadField(s, ArrayComplexDesc.FieldStartIndex));
                }

                Field.ComplexValue = ArrayComplex;
                Field.ValueType    = DAIFieldType.DAI_Array;
            }
            else
            {
            }

            return(Field);
        }