Exemplo n.º 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;
        }
Exemplo n.º 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.");
                }
            }
        }