Example #1
0
        private static void ValidationChecks <T>(DBHeader header, out uint Build)
        {
            var attr = typeof(T).GetCustomAttribute(typeof(DBTableAttribute), false) as DBTableAttribute;

            if (attr == null)
            {
                throw new NotSupportedException("Missing DBTableAttribute.");
            }

            if (attr.Build < (int)Expansion.Alpha)
            {
                throw new ArgumentException("Invalid Build Number.");
            }

            //No header - must be invalid
            if (!header.IsTypeOf <DBHeader>())
            {
                throw new Exception("Unknown file type.");
            }

            if (!header.IsTypeOf <HTFX>() && (header.RecordCount == 0 || header.RecordSize == 0))
            {
                throw new Exception("File contains no records.");
            }

            Build = attr.Build;
        }
Example #2
0
        private static DBEntry <T> Read <T>(FileStream stream, string dbFile, DBHeader counterpart = null) where T : class
        {
            FileName        = dbFile;
            stream.Position = 0;

            using (var dbReader = new BinaryReader(stream, Encoding.UTF8))
            {
                DBHeader header = ReadHeader(dbReader, counterpart);
                long     pos    = dbReader.BaseStream.Position;

                ValidationChecks <T>(header, out uint build);

                DBEntry <T> entry = new DBEntry <T>(header, dbFile, build);
                if (entry.TableStructure == null)
                {
                    throw new Exception("Definition missing.");
                }

                if (header.IsTypeOf <WDBC>() || header.IsTypeOf <WDB2>())
                {
                    long stringTableStart = dbReader.BaseStream.Position += header.RecordCount * header.RecordSize;
                    Dictionary <int, string> StringTable = new StringTable().Read(dbReader, stringTableStart); //Get stringtable
                    dbReader.Scrub(pos);

                    ReadIntoTable(ref entry, dbReader, StringTable); //Read data

                    stream.Dispose();
                    return(entry);
                }
                else if (header.IsTypeOf <WDB5>() || header.IsTypeOf <WCH5>() || header.IsTypeOf <WDB6>())
                {
                    int  CopyTableSize       = header.CopyTableSize;       //Only WDB5 has a copy table
                    uint CommonDataTableSize = header.CommonDataTableSize; //Only WDB6 has a CommonDataTable

                    //StringTable - only if applicable
                    long copyTablePos     = dbReader.BaseStream.Length - CommonDataTableSize - CopyTableSize;
                    long indexTablePos    = copyTablePos - (header.HasIndexTable ? header.RecordCount * 4 : 0);
                    long wch7TablePos     = indexTablePos - (header.UnknownWCH7 * 4);
                    long stringTableStart = wch7TablePos - header.StringBlockSize;

                    Dictionary <int, string> StringTable = new Dictionary <int, string>();
                    if (!header.HasOffsetTable) //Stringtable is only present if there isn't an offset map
                    {
                        dbReader.Scrub(stringTableStart);
                        StringTable = new StringTable().Read(dbReader, stringTableStart, stringTableStart + header.StringBlockSize);
                        dbReader.Scrub(pos);
                    }

                    //Read the data
                    using (MemoryStream ms = new MemoryStream(header.ReadData(dbReader, pos, entry.Build)))
                        using (BinaryReader dataReader = new BinaryReader(ms, Encoding.UTF8))
                        {
                            ReadIntoTable(ref entry, dataReader, StringTable);
                        }

                    //Cleanup
                    header.OffsetLengths = null;

                    stream.Dispose();
                    return(entry);
                }
                else if (header.IsTypeOf <WDB>())
                {
                    WDB wdb = (WDB)header;
                    using (MemoryStream ms = new MemoryStream(wdb.ReadData(dbReader)))
                        using (BinaryReader dataReader = new BinaryReader(ms, Encoding.UTF8))
                        {
                            ReadIntoTable(ref entry, dataReader, new Dictionary <int, string>());
                        }

                    stream.Dispose();
                    return(entry);
                }
                else if (header.IsTypeOf <HTFX>())
                {
                    HTFX htfx = (HTFX)header;
                    using (MemoryStream ms = new MemoryStream(htfx.ReadData(counterpart as WDB6)))
                        using (BinaryReader dataReader = new BinaryReader(ms, Encoding.UTF8))
                        {
                            ReadIntoTable(ref entry, dataReader, new Dictionary <int, string>());
                        }

                    stream.Dispose();
                    return(entry);
                }
                else
                {
                    stream.Dispose();
                    throw new Exception($"Invalid filetype.");
                }
            }
        }
Example #3
0
        private static DBHeader ReadHeader(BinaryReader dbReader, DBHeader counterpart = null)
        {
            DBHeader header    = null;
            string   signature = dbReader.ReadString(4);

            if (string.IsNullOrWhiteSpace(signature))
            {
                return(null);
            }

            if (signature[0] != 'W')
            {
                signature = signature.Reverse();
            }

            switch (signature)
            {
            case "WDBC":
                header = new WDBC();
                break;

            case "WDB2":
            case "WCH2":
                header = new WDB2();
                break;

            case "WDB5":
                header = new WDB5();
                break;

            case "WDB6":
                header = new WDB6();
                break;

            case "WCH5":
                header = new WCH5(counterpart);
                break;

            case "WCH7":
                header = new WCH7(counterpart);
                break;

            case "WCH8":
                header = new WCH8(counterpart);
                break;

            case "WMOB":
            case "WGOB":
            case "WQST":
            case "WIDB":
            case "WNDB":
            case "WITX":
            case "WNPC":
            case "WPTX":
            case "WRDN":
                header = new WDB();
                break;

            case "HTFX":
                header = new HTFX();
                break;
            }

            header?.ReadHeader(ref dbReader, signature);
            return(header);
        }
Example #4
0
 public static DBEntry <T> Read <T>(string dbFile, DBHeader counterpart = null) where T : class
 {
     return(Read <T>(new FileInfo(dbFile).OpenRead(), dbFile, counterpart));
 }