public DAIGuid GetDaiGuidFieldValue(DAIField field)
        {
            Debug.Assert(field.ValueType == DAIFieldType.DAI_Guid, "this method can only be applied to GUID fields");

            var  guid      = new DAIGuid();
            uint UIntValue = field.GetUIntValue();

            if ((UIntValue >> 31) == 1)
            {
                /* External Guid */
                DAIExternalGuid Guid = this.ExternalGuids.ElementAt((int)(UIntValue & 0x7fffffff));
                guid.external     = true;
                guid.fileGuid     = GuidToString(Guid.FileGuid);
                guid.instanceGuid = GuidToString(Guid.InstanceGuid);
            }
            else if (UIntValue == 0)
            {
                /* NULL Guid */
                guid.instanceGuid = "null";
            }
            else
            {
                /* Internal Guid */
                byte[] Guid = this.InternalGuids[(int)(UIntValue - 1)];
                guid.instanceGuid = GuidToString(Guid);
            }

            return(guid);
        }
        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 void ToXml(DAIEbx EbxFile, ref StringBuilder sb)
        {
            if (Descriptor.FieldName == "$")
            {
                DAIEbx.TabCount--;
                ComplexValue.ToXml(EbxFile, ref sb);
                DAIEbx.TabCount++;
                return;
            }

            sb.Append(DAIEbx.Tabs() + "<" + Descriptor.FieldName + ">");

            switch (ValueType)
            {
            case DAIFieldType.DAI_Complex:
            case DAIFieldType.DAI_Array:
                sb.Append("\n");
                if (ComplexValue != null)
                {
                    ComplexValue.ToXml(EbxFile, ref sb);
                }
                else
                {
                    sb.Append("[null]\n");
                }
                sb.Append(DAIEbx.Tabs() + "</" + Descriptor.FieldName + ">\n");
                return;

            case DAIFieldType.DAI_String:
                sb.Append(GetStringValue());
                break;

            case DAIFieldType.DAI_Int:
                sb.Append(GetIntValue().ToString("X8"));
                break;

            case DAIFieldType.DAI_UInt:
                sb.Append(GetUIntValue().ToString("X8"));
                break;

            case DAIFieldType.DAI_Float:
                sb.Append(GetFloatValue().ToString("F3"));
                break;

            case DAIFieldType.DAI_Short:
                sb.Append(GetShortValue().ToString("X4"));
                break;

            case DAIFieldType.DAI_UShort:
                sb.Append(GetUShortValue().ToString("X4"));
                break;

            case DAIFieldType.DAI_Byte:
                sb.Append(GetByteValue().ToString("X2"));
                break;

            case DAIFieldType.DAI_UByte:
                sb.Append(GetByteValue().ToString("X2"));
                break;

            case DAIFieldType.DAI_Long:
                sb.Append(GetLongValue().ToString("X16"));
                break;

            case DAIFieldType.DAI_LongLong:
                for (int i = 0; i < Value.Length; i++)
                {
                    sb.Append(Value[i].ToString("X2"));
                }
                break;

            case DAIFieldType.DAI_Bool:
                sb.Append(GetBoolValue().ToString());
                break;

            case DAIFieldType.DAI_Enum:
                sb.Append(GetEnumValue());
                break;

            case DAIFieldType.DAI_Guid:
            {
                uint UIntValue = GetUIntValue();
                if ((UIntValue >> 31) == 1)
                {
                    /* External Guid */
                    DAIExternalGuid Guid = EbxFile.ExternalGuids.ElementAt((int)(UIntValue & 0x7fffffff));
                    System.Data.SQLite.SQLiteConnection con = Database.GetConnection();
                    con.Open();
                    System.Data.SQLite.SQLiteDataReader reader = new System.Data.SQLite.SQLiteCommand("SELECT name,type FROM ebx WHERE guid = '" + Guid.FileGuidString() + "'", con).ExecuteReader();
                    reader.Read();
                    sb.Append("[" + reader.GetString(1) + "] " + reader.GetString(0));
                }
                else if (UIntValue == 0)
                {
                    /* NULL Guid */
                    sb.Append("[null]");
                }
                else
                {
                    /* Internal Guid */
                    byte[] Guid = EbxFile.InternalGuids[(int)(UIntValue - 1)];
                    sb.Append("[" + EbxFile.Instances[Guid].Descriptor.FieldName + "] ");
                    for (int i = 0; i < Guid.Length; i++)
                    {
                        sb.Append(Guid[i].ToString("X2"));
                    }
                }
            }
            break;
            }

            sb.Append("</" + Descriptor.FieldName + ">\n");
            return;
        }