public DatabaseFile(string databasePath, string schemaPath) : this()
        {
            base.DataSetName = "database";
            using (DatabaseBinaryReader reader = new DatabaseBinaryReader(EndianBitConverter.Little, File.Open(databasePath, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                int       num;
                Exception exception;
                Dictionary <DataColumn, string[]> dR = new Dictionary <DataColumn, string[]>();
                XmlDocument SXML = new XmlDocument();
                SXML.Load(File.Open(schemaPath, FileMode.Open, FileAccess.Read, FileShare.Read));
                int itemNum = 0;
                int nodeNum = 0;
                base.DataSetName = reader.ReadUInt32().ToString();
                uint schemaVersion = 0;

                if (SXML.DocumentElement.ChildNodes[nodeNum].Name == "schemaVersion")
                {
                    // Dirt 3 schemaVer, and schemaVerXml is different so don't do the error check
                    uint schemaVersionXml = Convert.ToUInt32(SXML.DocumentElement.ChildNodes[nodeNum].Attributes["version"].Value);
                    schemaVersion = reader.ReadUInt32();
                    if (schemaVersion != schemaVersionXml && schemaVersion != 3914959594)
                    {
                        throw new ArgumentException("The schema does not match with this database file.", nameof(schemaPath));
                    }
                    base.DataSetName = base.DataSetName + ";" + schemaVersion.ToString();
                    nodeNum++;
                }

                // Figure out the offset to the strings
                // this only applies to certain games
                // Does not apply to Dirt 3, despite having a schemaVersion
                // F12013 1000; GridAutosport 1407330540; Dirt3 3914959594;
                int offset = 12;
                if (schemaVersion == 1000 || schemaVersion == 1407330540)
                {
                    num = 1;
                    while (num < SXML.DocumentElement.ChildNodes.Count)
                    {
                        reader.Seek(offset, SeekOrigin.Begin);
                        int num6       = reader.ReadInt32();
                        int fieldCount = SXML.DocumentElement.ChildNodes[num].ChildNodes.OfType <XmlElement>().Count(x => x.Name == "field");
                        offset += ((num6 * (fieldCount + 1)) * 4) + 8;
                        num++;
                    }
                    offset += 4;
                    reader.Seek(8, SeekOrigin.Begin);
                }

                while (reader.BaseStream.Position < reader.BaseStream.Length &&
                       nodeNum < SXML.DocumentElement.ChildNodes.Count)
                {
                    DataTable table = new DataTable(SXML.DocumentElement.ChildNodes[nodeNum].Attributes["name"].InnerText);
                    reader.Seek(4, SeekOrigin.Current);
                    itemNum = reader.ReadInt32();
                    foreach (XmlElement element in SXML.DocumentElement.ChildNodes[nodeNum])
                    {
                        if (element.Name != "field")
                        {
                            continue;
                        }

                        DataColumn column = new DataColumn();
                        table.Columns.Add(column);
                        column.ColumnName = element.Attributes["name"].InnerText;
                        if (element.HasAttribute("key"))
                        {
                            if (element.Attributes["key"].InnerText == "primary")
                            {
                                table.PrimaryKey = new DataColumn[] { column };
                            }
                            else
                            {
                                string[] strArray = element.Attributes["key"].InnerText.Split(new char[] { '.' });
                                dR.Add(column, strArray);
                            }
                        }
                        switch (element.Attributes["type"].InnerText)
                        {
                        case "float":
                            column.DataType     = typeof(float);
                            column.DefaultValue = 0f;
                            break;

                        case "int":
                            column.DataType     = typeof(int);
                            column.DefaultValue = 0;
                            break;

                        case "string":
                            column.DataType = typeof(string);
                            if (element.HasAttribute("size"))
                            {
                                column.MaxLength = Convert.ToInt32(element.Attributes["size"].InnerText);
                            }
                            column.DefaultValue = string.Empty;
                            break;

                        case "bool":
                            column.DataType     = typeof(bool);
                            column.DefaultValue = false;
                            break;

                        default:
                            column.DataType     = typeof(int);
                            column.DefaultValue = 0;
                            break;
                        }
                    }
                    for (num = 0; num < itemNum; num++)
                    {
                        DataRow       row  = table.NewRow();
                        List <object> list = new List <object>();
                        reader.Seek(4, SeekOrigin.Current);
                        foreach (XmlElement element in SXML.DocumentElement.ChildNodes[nodeNum])
                        {
                            if (element.Name != "field")
                            {
                                continue;
                            }

                            switch (element.Attributes["type"].InnerText)
                            {
                            case "float":
                                list.Add(reader.ReadSingle());
                                break;

                            case "int":
                                list.Add(reader.ReadInt32());
                                break;

                            case "string":
                                if (schemaVersion == 1000 || schemaVersion == 1407330540)
                                {
                                    int returnPosition = (int)reader.BaseStream.Position + 4;
                                    reader.Seek(offset + reader.ReadInt32(), SeekOrigin.Begin);
                                    list.Add(reader.ReadTerminatedString(0));
                                    reader.Seek(returnPosition, SeekOrigin.Begin);
                                }
                                else
                                {
                                    list.Add(reader.ReadDatabaseString(table.Columns[element.Attributes["name"].InnerText].MaxLength));
                                }
                                break;

                            case "bool":
                                list.Add(reader.ReadBoolean());
                                reader.ReadBytes(3);
                                break;

                            default:
                                list.Add(reader.ReadInt32());
                                break;
                            }
                        }
                        row.ItemArray = list.ToArray();
                        try
                        {
                            table.Rows.Add(row);
                        }
                        catch (Exception exception2)
                        {
                            float num8;
                            int   num9;
                            bool  flag;
                            exception = exception2;
                            if (exception is ConstraintException)
                            {
                                try
                                {
                                    this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                                    table.PrimaryKey = null;
                                    table.Rows.Add(row);
                                    this._loadErrors[this._loadErrors.Count - 1][2] = "The rows were kept but it is recommended that you fix the problem.";
                                }
                                catch (Exception exception3)
                                {
                                    (this._loadErrors[this._loadErrors.Count - 1])[1] += " " + exception3.Message;
                                    (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                                    foreach (object value in list)
                                    {
                                        if (value is float)
                                        {
                                            num8 = (float)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                                        }
                                        else if (value is int)
                                        {
                                            num9 = (int)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                                        }
                                        else if (value is string)
                                        {
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                                        }
                                        else if (value is bool)
                                        {
                                            flag = (bool)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                                        }
                                    }
                                }
                            }
                            else
                            {
                                this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                                (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                                foreach (object value in list)
                                {
                                    if (value is float)
                                    {
                                        num8 = (float)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                                    }
                                    else if (value is int)
                                    {
                                        num9 = (int)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                                    }
                                    else if (value is string)
                                    {
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                                    }
                                    else if (value is bool)
                                    {
                                        flag = (bool)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                                    }
                                }
                            }
                        }
                    }
                    base.Tables.Add(table);
                    nodeNum++;
                }
                foreach (KeyValuePair <DataColumn, string[]> pair in dR)
                {
                    DataRelation relation = new DataRelation(pair.Key.Table.TableName + "." + pair.Key.ColumnName, base.Tables[pair.Value[0]].Columns[pair.Value[1]], pair.Key);
                    pair.Key.Table.ExtendedProperties.Add(pair.Key.ColumnName, pair.Value[0]);
                    try
                    {
                        base.Relations.Add(relation);
                    }
                    catch (Exception exception4)
                    {
                        exception = exception4;
                        if ((exception is ConstraintException) && (exception.Message.Contains("to exist in the parent table.") && !exception.Message.Contains("values (0)")))
                        {
                            this._loadErrors.Add(new string[] { pair.Key.Table.TableName, exception.Message, string.Empty });
                            this._loadErrors[this._loadErrors.Count - 1][2] = "It is recommended that you fix the problem. To help you find the row, search for the value() from the above line in the " + pair.Key + " column.";
                        }
                    }
                }
            }
            base.Namespace = Path.GetFileName(schemaPath);
            base.AcceptChanges();
        }
 public DatabaseFile(string databasePath, string schemaPath)
 {
     this._loadErrors = new List<string[]>();
     base.DataSetName = "database";
     using (DatabaseBinaryReader reader = new DatabaseBinaryReader(EndianBitConverter.Little, File.Open(databasePath, FileMode.Open, FileAccess.Read, FileShare.Read)))
     {
         int num;
         Exception exception;
         Dictionary<DataColumn, string[]> dR = new Dictionary<DataColumn, string[]>();
         this._loadErrors = new List<string[]>();
         XmlDocument SXML = new XmlDocument();
         SXML.Load(File.Open(schemaPath, FileMode.Open, FileAccess.Read, FileShare.Read));
         int itemNum = 0;
         int nodeNum = 0;
         base.DataSetName = reader.ReadUInt32().ToString();
         uint num4 = 0;
         if (SXML.DocumentElement.ChildNodes[nodeNum].Name == "schemaVersion")
         {
             num4 = reader.ReadUInt32();
             base.DataSetName = base.DataSetName + ";" + num4.ToString();
             nodeNum++;
         }
         int offset = 12;
         if (num4 == 0x3e8)
         {
             num = 1;
             while (num < SXML.DocumentElement.ChildNodes.Count)
             {
                 reader.Seek(offset, SeekOrigin.Begin);
                 int num6 = reader.ReadInt32();
                 offset += ((num6 * (SXML.DocumentElement.ChildNodes[num].ChildNodes.Count + 1)) * 4) + 8;
                 num++;
             }
             offset += 4;
             reader.Seek(8, SeekOrigin.Begin);
         }
         while (reader.BaseStream.Position < reader.BaseStream.Length)
         {
             string innerText;
             if (nodeNum >= SXML.DocumentElement.ChildNodes.Count)
             {
                 break;
             }
             DataTable table = new DataTable(SXML.DocumentElement.ChildNodes[nodeNum].Attributes["name"].InnerText);
             reader.Seek(4, SeekOrigin.Current);
             itemNum = reader.ReadInt32();
             foreach (XmlElement element in SXML.DocumentElement.ChildNodes[nodeNum])
             {
                 DataColumn column = new DataColumn();
                 table.Columns.Add(column);
                 column.ColumnName = element.Attributes["name"].InnerText;
                 if (element.HasAttribute("key"))
                 {
                     if (element.Attributes["key"].InnerText == "primary")
                     {
                         table.PrimaryKey = new DataColumn[] { column };
                     }
                     else
                     {
                         string[] strArray = element.Attributes["key"].InnerText.Split(new char[] { '.' });
                         dR.Add(column, strArray);
                     }
                 }
                 innerText = element.Attributes["type"].InnerText;
                 if (innerText == null)
                 {
                     goto Label_03E8;
                 }
                 if (!(innerText == "float"))
                 {
                     if (innerText == "int")
                     {
                         goto Label_0346;
                     }
                     if (innerText == "string")
                     {
                         goto Label_036B;
                     }
                     if (innerText == "bool")
                     {
                         goto Label_03C6;
                     }
                     goto Label_03E8;
                 }
                 column.DataType = typeof(float);
                 column.DefaultValue = 0f;
                 continue;
             Label_0346:
                 column.DataType = typeof(int);
                 column.DefaultValue = 0;
                 continue;
             Label_036B:
                 column.DataType = typeof(string);
                 if (element.HasAttribute("size"))
                 {
                     column.MaxLength = Convert.ToInt32(element.Attributes["size"].InnerText);
                 }
                 column.DefaultValue = string.Empty;
                 continue;
             Label_03C6:
                 column.DataType = typeof(bool);
                 column.DefaultValue = false;
                 continue;
             Label_03E8:
                 column.DataType = typeof(int);
                 column.DefaultValue = 0;
             }
             for (num = 0; num < itemNum; num++)
             {
                 DataRow row = table.NewRow();
                 List<object> list = new List<object>();
                 reader.Seek(4, SeekOrigin.Current);
                 foreach (XmlElement element in SXML.DocumentElement.ChildNodes[nodeNum])
                 {
                     innerText = element.Attributes["type"].InnerText;
                     if (innerText == null)
                     {
                         goto Label_05C0;
                     }
                     if (!(innerText == "float"))
                     {
                         if (innerText == "int")
                         {
                             goto Label_0502;
                         }
                         if (innerText == "string")
                         {
                             goto Label_051A;
                         }
                         if (innerText == "bool")
                         {
                             goto Label_05A3;
                         }
                         goto Label_05C0;
                     }
                     list.Add(reader.ReadSingle());
                     continue;
                 Label_0502:
                     list.Add(reader.ReadInt32());
                     continue;
                 Label_051A:
                     if (num4 == 0x3e8)
                     {
                         int num7 = ((int)reader.BaseStream.Position) + 4;
                         reader.Seek(offset + reader.ReadInt32(), SeekOrigin.Begin);
                         list.Add(reader.ReadTerminatedString(0));
                         reader.Seek(num7, SeekOrigin.Begin);
                     }
                     else
                     {
                         list.Add(reader.ReadDatabaseString(table.Columns[element.Attributes["name"].InnerText].MaxLength));
                     }
                     continue;
                 Label_05A3:
                     list.Add(reader.ReadBoolean());
                     reader.ReadBytes(3);
                     continue;
                 Label_05C0:
                     list.Add(reader.ReadInt32());
                 }
                 row.ItemArray = list.ToArray();
                 try
                 {
                     table.Rows.Add(row);
                 }
                 catch (Exception exception2)
                 {
                     float num8;
                     int num9;
                     bool flag;
                     exception = exception2;
                     if (exception is ConstraintException)
                     {
                         try
                         {
                             this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                             table.PrimaryKey = null;
                             table.Rows.Add(row);
                             this._loadErrors[this._loadErrors.Count - 1][2] = "The rows were kept but it is recommended that you fix the problem.";
                         }
                         catch (Exception exception3)
                         {
                             (this._loadErrors[this._loadErrors.Count - 1])[1] += " " + exception3.Message;
                             (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                             foreach (object value in list)
                             {
                                 if (value is float)
                                 {
                                     num8 = (float)value;
                                     (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                                 }
                                 else if (value is int)
                                 {
                                     num9 = (int)value;
                                     (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                                 }
                                 else if (value is string)
                                 {
                                     (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                                 }
                                 else if (value is bool)
                                 {
                                     flag = (bool)value;
                                     (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                                 }
                             }
                         }
                     }
                     else
                     {
                         this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                         (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                         foreach (object value in list)
                         {
                             if (value is float)
                             {
                                 num8 = (float)value;
                                 (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                             }
                             else if (value is int)
                             {
                                 num9 = (int)value;
                                 (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                             }
                             else if (value is string)
                             {
                                 (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                             }
                             else if (value is bool)
                             {
                                 flag = (bool)value;
                                 (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                             }
                         }
                     }
                 }
             }
             base.Tables.Add(table);
             nodeNum++;
         }
         foreach (KeyValuePair<DataColumn, string[]> pair in dR)
         {
             DataRelation relation = new DataRelation(pair.Key.Table.TableName + "." + pair.Key.ColumnName, base.Tables[pair.Value[0]].Columns[pair.Value[1]], pair.Key);
             pair.Key.Table.ExtendedProperties.Add(pair.Key.ColumnName, pair.Value[0]);
             try
             {
                 base.Relations.Add(relation);
             }
             catch (Exception exception4)
             {
                 exception = exception4;
                 if ((exception is ConstraintException) && (exception.Message.Contains("to exist in the parent table.") && !exception.Message.Contains("values (0)")))
                 {
                     this._loadErrors.Add(new string[] { pair.Key.Table.TableName, exception.Message, string.Empty });
                     this._loadErrors[this._loadErrors.Count - 1][2] = "It is recommended that you fix the problem. To help you find the row, search for the value() from the above line in the " + pair.Key + " column.";
                 }
             }
         }
     }
     base.Namespace = Path.GetFileName(schemaPath);
     base.AcceptChanges();
 }
Example #3
0
        public DatabaseFile(string databasePath, string schemaPath)
        {
            this._loadErrors = new List <string[]>();
            base.DataSetName = "database";
            using (DatabaseBinaryReader reader = new DatabaseBinaryReader(EndianBitConverter.Little, File.Open(databasePath, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                int       num;
                Exception exception;
                Dictionary <DataColumn, string[]> dR = new Dictionary <DataColumn, string[]>();
                this._loadErrors = new List <string[]>();
                XmlDocument SXML = new XmlDocument();
                SXML.Load(File.Open(schemaPath, FileMode.Open, FileAccess.Read, FileShare.Read));
                int itemNum = 0;
                int nodeNum = 0;
                base.DataSetName = reader.ReadUInt32().ToString();
                uint num4 = 0;
                if (SXML.DocumentElement.ChildNodes[nodeNum].Name == "schemaVersion")
                {
                    num4             = reader.ReadUInt32();
                    base.DataSetName = base.DataSetName + ";" + num4.ToString();
                    nodeNum++;
                }
                int offset = 12;
                if (num4 == 0x3e8)
                {
                    num = 1;
                    while (num < SXML.DocumentElement.ChildNodes.Count)
                    {
                        reader.Seek(offset, SeekOrigin.Begin);
                        int num6 = reader.ReadInt32();
                        offset += ((num6 * (SXML.DocumentElement.ChildNodes[num].ChildNodes.Count + 1)) * 4) + 8;
                        num++;
                    }
                    offset += 4;
                    reader.Seek(8, SeekOrigin.Begin);
                }
                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    string innerText;
                    if (nodeNum >= SXML.DocumentElement.ChildNodes.Count)
                    {
                        break;
                    }
                    DataTable table = new DataTable(SXML.DocumentElement.ChildNodes[nodeNum].Attributes["name"].InnerText);
                    reader.Seek(4, SeekOrigin.Current);
                    itemNum = reader.ReadInt32();
                    foreach (XmlElement element in SXML.DocumentElement.ChildNodes[nodeNum])
                    {
                        DataColumn column = new DataColumn();
                        table.Columns.Add(column);
                        column.ColumnName = element.Attributes["name"].InnerText;
                        if (element.HasAttribute("key"))
                        {
                            if (element.Attributes["key"].InnerText == "primary")
                            {
                                table.PrimaryKey = new DataColumn[] { column };
                            }
                            else
                            {
                                string[] strArray = element.Attributes["key"].InnerText.Split(new char[] { '.' });
                                dR.Add(column, strArray);
                            }
                        }
                        innerText = element.Attributes["type"].InnerText;
                        if (innerText == null)
                        {
                            goto Label_03E8;
                        }
                        if (!(innerText == "float"))
                        {
                            if (innerText == "int")
                            {
                                goto Label_0346;
                            }
                            if (innerText == "string")
                            {
                                goto Label_036B;
                            }
                            if (innerText == "bool")
                            {
                                goto Label_03C6;
                            }
                            goto Label_03E8;
                        }
                        column.DataType     = typeof(float);
                        column.DefaultValue = 0f;
                        continue;
Label_0346:
                        column.DataType     = typeof(int);
                        column.DefaultValue = 0;
                        continue;
Label_036B:
                        column.DataType = typeof(string);
                        if (element.HasAttribute("size"))
                        {
                            column.MaxLength = Convert.ToInt32(element.Attributes["size"].InnerText);
                        }
                        column.DefaultValue = string.Empty;
                        continue;
Label_03C6:
                        column.DataType     = typeof(bool);
                        column.DefaultValue = false;
                        continue;
Label_03E8:
                        column.DataType     = typeof(int);
                        column.DefaultValue = 0;
                    }
                    for (num = 0; num < itemNum; num++)
                    {
                        DataRow       row  = table.NewRow();
                        List <object> list = new List <object>();
                        reader.Seek(4, SeekOrigin.Current);
                        foreach (XmlElement element in SXML.DocumentElement.ChildNodes[nodeNum])
                        {
                            innerText = element.Attributes["type"].InnerText;
                            if (innerText == null)
                            {
                                goto Label_05C0;
                            }
                            if (!(innerText == "float"))
                            {
                                if (innerText == "int")
                                {
                                    goto Label_0502;
                                }
                                if (innerText == "string")
                                {
                                    goto Label_051A;
                                }
                                if (innerText == "bool")
                                {
                                    goto Label_05A3;
                                }
                                goto Label_05C0;
                            }
                            list.Add(reader.ReadSingle());
                            continue;
Label_0502:
                            list.Add(reader.ReadInt32());
                            continue;
Label_051A:
                            if (num4 == 0x3e8)
                            {
                                int num7 = ((int)reader.BaseStream.Position) + 4;
                                reader.Seek(offset + reader.ReadInt32(), SeekOrigin.Begin);
                                list.Add(reader.ReadTerminatedString(0));
                                reader.Seek(num7, SeekOrigin.Begin);
                            }
                            else
                            {
                                list.Add(reader.ReadDatabaseString(table.Columns[element.Attributes["name"].InnerText].MaxLength));
                            }
                            continue;
Label_05A3:
                            list.Add(reader.ReadBoolean());
                            reader.ReadBytes(3);
                            continue;
Label_05C0:
                            list.Add(reader.ReadInt32());
                        }
                        row.ItemArray = list.ToArray();
                        try
                        {
                            table.Rows.Add(row);
                        }
                        catch (Exception exception2)
                        {
                            float num8;
                            int   num9;
                            bool  flag;
                            exception = exception2;
                            if (exception is ConstraintException)
                            {
                                try
                                {
                                    this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                                    table.PrimaryKey = null;
                                    table.Rows.Add(row);
                                    this._loadErrors[this._loadErrors.Count - 1][2] = "The rows were kept but it is recommended that you fix the problem.";
                                }
                                catch (Exception exception3)
                                {
                                    (this._loadErrors[this._loadErrors.Count - 1])[1] += " " + exception3.Message;
                                    (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                                    foreach (object value in list)
                                    {
                                        if (value is float)
                                        {
                                            num8 = (float)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                                        }
                                        else if (value is int)
                                        {
                                            num9 = (int)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                                        }
                                        else if (value is string)
                                        {
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                                        }
                                        else if (value is bool)
                                        {
                                            flag = (bool)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                                        }
                                    }
                                }
                            }
                            else
                            {
                                this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                                (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                                foreach (object value in list)
                                {
                                    if (value is float)
                                    {
                                        num8 = (float)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                                    }
                                    else if (value is int)
                                    {
                                        num9 = (int)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                                    }
                                    else if (value is string)
                                    {
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                                    }
                                    else if (value is bool)
                                    {
                                        flag = (bool)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                                    }
                                }
                            }
                        }
                    }
                    base.Tables.Add(table);
                    nodeNum++;
                }
                foreach (KeyValuePair <DataColumn, string[]> pair in dR)
                {
                    DataRelation relation = new DataRelation(pair.Key.Table.TableName + "." + pair.Key.ColumnName, base.Tables[pair.Value[0]].Columns[pair.Value[1]], pair.Key);
                    pair.Key.Table.ExtendedProperties.Add(pair.Key.ColumnName, pair.Value[0]);
                    try
                    {
                        base.Relations.Add(relation);
                    }
                    catch (Exception exception4)
                    {
                        exception = exception4;
                        if ((exception is ConstraintException) && (exception.Message.Contains("to exist in the parent table.") && !exception.Message.Contains("values (0)")))
                        {
                            this._loadErrors.Add(new string[] { pair.Key.Table.TableName, exception.Message, string.Empty });
                            this._loadErrors[this._loadErrors.Count - 1][2] = "It is recommended that you fix the problem. To help you find the row, search for the value() from the above line in the " + pair.Key + " column.";
                        }
                    }
                }
            }
            base.Namespace = Path.GetFileName(schemaPath);
            base.AcceptChanges();
        }
        public DatabaseFile(string databasePath, string schemaPath) : this()
        {
            base.DataSetName = "database";
            using (DatabaseBinaryReader reader = new DatabaseBinaryReader(EndianBitConverter.Little, File.Open(databasePath, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                Exception exception;
                Dictionary <DataColumn, string[]> dR = new Dictionary <DataColumn, string[]>();
                XmlDocument SXML = new XmlDocument();
                SXML.Load(File.Open(schemaPath, FileMode.Open, FileAccess.Read, FileShare.Read));
                if (SXML.DocumentElement is null)
                {
                    throw new InvalidDataException("The schema root xml element does not exist.");
                }

                int itemNum = 0;
                int nodeNum = 0;
                base.DataSetName = reader.ReadUInt32().ToString();
                uint schemaVersion = 0;

                bool hasStringTable = false;
                if (SXML.DocumentElement.ChildNode(nodeNum).Name == "schemaVersion")
                {
                    uint schemaVersionXml = Convert.ToUInt32(SXML.DocumentElement.ChildNode(nodeNum).Attribute("version").Value);
                    schemaVersion = reader.ReadUInt32();

                    // Dirt 3 schemaVer, and schemaVerXml is different so don't do the error check
                    // Also D3 doesn't have a string table despite having a schemaVersion
                    if (schemaVersion != 3934935529) // Dirt has 3934935529 in db, and 3914959594 in schema
                    {
                        if (schemaVersion != schemaVersionXml)
                        {
                            throw new ArgumentException("The schema does not match with this database file.", nameof(schemaPath));
                        }

                        hasStringTable = true;
                    }

                    base.DataSetName = base.DataSetName + ";" + schemaVersion.ToString();
                    nodeNum++;
                }

                // Figure out the offset to the strings
                // this only applies to certain games
                // Does not apply to Dirt 3, despite having a schemaVersion
                // F12013 1000; GridAutosport 1407330540; Dirt3 3914959594, Dirt Rally 539233987;
                int offset = 12;
                if (hasStringTable)
                {
                    // Loop through the tables in the schema, and jump through the database file to find the string table offset
                    for (int i = 1; i < SXML.DocumentElement.ChildNodes.Count; ++i)
                    {
                        reader.Seek(offset, SeekOrigin.Begin);
                        int tableRowCount = reader.ReadInt32();
                        int fieldCount    = SXML.DocumentElement.ChildNode(i).ChildNodes.OfType <XmlElement>().Count(x => x.Name == "field");
                        offset += ((tableRowCount * (fieldCount + 1)) * 4) + 8;
                    }
                    offset += 4;
                    reader.Seek(8, SeekOrigin.Begin);
                }

                // Loop through all the data table by table
                while (reader.BaseStream.Position < reader.BaseStream.Length &&
                       nodeNum < SXML.DocumentElement.ChildNodes.Count)
                {
                    reader.Seek(2, SeekOrigin.Current);
                    var tableID = reader.ReadUInt16();
                    if ((hasStringTable && tableID != 10795) || (!hasStringTable && tableID != 21570)) // 0x2A2B or 0x5442 (BT from LBT)
                    {
                        throw new ArgumentException("The schema does not match with this database file.", nameof(schemaPath));
                    }
                    itemNum = reader.ReadInt32();

                    // Setup DataTable with proper columns based on the schema
                    DataTable table = new DataTable(SXML.DocumentElement.ChildNode(nodeNum).Attribute("name").InnerText);
                    foreach (XmlElement element in SXML.DocumentElement.ChildNode(nodeNum))
                    {
                        if (element.Name != "field")
                        {
                            continue;
                        }

                        DataColumn column = new DataColumn();
                        table.Columns.Add(column);
                        column.ColumnName = element.Attribute("name").InnerText;
                        if (element.HasAttribute("key"))
                        {
                            if (element.Attribute("key").InnerText == "primary")
                            {
                                table.PrimaryKey = new DataColumn[] { column };
                            }
                            else
                            {
                                string[] strArray = element.Attribute("key").InnerText.Split(new char[] { '.' });
                                dR.Add(column, strArray);
                            }
                        }
                        switch (element.Attribute("type").InnerText)
                        {
                        case "float":
                            column.DataType     = typeof(float);
                            column.DefaultValue = 0f;
                            break;

                        case "int":
                            column.DataType     = typeof(int);
                            column.DefaultValue = 0;
                            break;

                        case "string":
                            column.DataType = typeof(string);
                            if (element.HasAttribute("size"))
                            {
                                column.MaxLength = Convert.ToInt32(element.Attribute("size").InnerText);
                            }
                            column.DefaultValue = string.Empty;
                            break;

                        case "bool":
                            column.DataType     = typeof(bool);
                            column.DefaultValue = false;
                            break;

                        default:
                            column.DataType     = typeof(int);
                            column.DefaultValue = 0;
                            break;
                        }
                    }

                    // Read the data for this table
                    for (int num = 0; num < itemNum; num++)
                    {
                        var itmID = reader.ReadUInt16();
                        if (hasStringTable && itmID != 10797) // 0x2A2D
                        {
                            throw new ArgumentException("The schema does not match with this database file.", nameof(schemaPath));
                        }
                        reader.Seek(2, SeekOrigin.Current);

                        // Read the data for each field in the schema
                        DataRow       row  = table.NewRow();
                        List <object> list = new List <object>();
                        foreach (XmlElement element in SXML.DocumentElement.ChildNode(nodeNum))
                        {
                            if (element.Name != "field")
                            {
                                continue;
                            }

                            switch (element.Attribute("type").InnerText)
                            {
                            case "float":
                                list.Add(reader.ReadSingle());
                                break;

                            case "int":
                                list.Add(reader.ReadInt32());
                                break;

                            case "string":
                                if (hasStringTable)
                                {
                                    int returnPosition = (int)reader.BaseStream.Position + 4;
                                    reader.Seek(offset + reader.ReadInt32(), SeekOrigin.Begin);
                                    list.Add(reader.ReadTerminatedString(0));
                                    reader.Seek(returnPosition, SeekOrigin.Begin);
                                }
                                else
                                {
                                    list.Add(reader.ReadDatabaseString(table.Column(element.Attribute("name").InnerText).MaxLength));
                                }
                                break;

                            case "bool":
                                list.Add(reader.ReadBoolean());
                                reader.ReadBytes(3);
                                break;

                            default:
                                list.Add(reader.ReadInt32());
                                break;
                            }
                        }
                        row.ItemArray = list.ToArray();
                        try
                        {
                            table.Rows.Add(row);
                        }
                        catch (Exception exception2)
                        {
                            float num8;
                            int   num9;
                            bool  flag;
                            exception = exception2;
                            if (exception is ConstraintException)
                            {
                                try
                                {
                                    this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                                    table.PrimaryKey = Array.Empty <DataColumn>();
                                    table.Rows.Add(row);
                                    this._loadErrors[this._loadErrors.Count - 1][2] = "The rows were kept but it is recommended that you fix the problem.";
                                }
                                catch (Exception exception3)
                                {
                                    (this._loadErrors[this._loadErrors.Count - 1])[1] += " " + exception3.Message;
                                    (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                                    foreach (object value in list)
                                    {
                                        if (value is float)
                                        {
                                            num8 = (float)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                                        }
                                        else if (value is int)
                                        {
                                            num9 = (int)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                                        }
                                        else if (value is string)
                                        {
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                                        }
                                        else if (value is bool)
                                        {
                                            flag = (bool)value;
                                            (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                                        }
                                    }
                                }
                            }
                            else
                            {
                                this._loadErrors.Add(new string[] { table.TableName, exception.Message, string.Empty });
                                (this._loadErrors[this._loadErrors.Count - 1])[1] += " The row was removed. Below are its contents separated by \" | \". Make sure to fix the problem if you are going to add it again.";
                                foreach (object value in list)
                                {
                                    if (value is float)
                                    {
                                        num8 = (float)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += num8.ToString() + "|";
                                    }
                                    else if (value is int)
                                    {
                                        num9 = (int)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += num9.ToString() + "|";
                                    }
                                    else if (value is string)
                                    {
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += ((string)value) + "|";
                                    }
                                    else if (value is bool)
                                    {
                                        flag = (bool)value;
                                        (this._loadErrors[this._loadErrors.Count - 1])[2] += flag.ToString() + "|";
                                    }
                                }
                            }
                        }
                    }
                    base.Tables.Add(table);
                    nodeNum++;
                }
                foreach (KeyValuePair <DataColumn, string[]> pair in dR)
                {
                    if (pair.Key.Table is null)
                    {
                        throw new InvalidDataException($"Data column {pair.Key.ColumnName} does not have a data table.");
                    }
                    DataRelation relation = new DataRelation(pair.Key.Table.TableName + "." + pair.Key.ColumnName, this.Table(pair.Value[0]).Column(pair.Value[1]), pair.Key);
                    pair.Key.Table.ExtendedProperties.Add(pair.Key.ColumnName, pair.Value[0]);
                    try
                    {
                        base.Relations.Add(relation);
                    }
                    catch (Exception exception4)
                    {
                        exception = exception4;
                        if ((exception is ConstraintException) && (exception.Message.Contains("to exist in the parent table.") && !exception.Message.Contains("values (0)")))
                        {
                            this._loadErrors.Add(new string[] { pair.Key.Table.TableName, exception.Message, string.Empty });
                            this._loadErrors[this._loadErrors.Count - 1][2] = "It is recommended that you fix the problem. To help you find the row, search for the value() from the above line in the " + pair.Key + " column.";
                        }
                    }
                }
            }
            base.Namespace = Path.GetFileName(schemaPath);
            base.AcceptChanges();
        }