Пример #1
0
        public override void WriteOffsetMap(BinaryWriter bw, DBEntry entry, List <Tuple <int, short> > OffsetMap)
        {
            var minmax     = entry.MinMax();
            var ids        = new List <int>(entry.GetUniqueRows().Select(x => x.Field <int>(IdIndex)));
            var duplicates = entry.Header.OffsetDuplicates;

            int m = 0;

            for (int x = minmax.Item1; x <= minmax.Item2; x++)
            {
                if (ids.Contains(x)) //Insert the offset map
                {
                    var kvp = OffsetMap[m];
                    bw.Write(kvp.Item1);
                    bw.Write(kvp.Item2);
                    m++;
                }
                else if (duplicates.ContainsKey(x)) //Reinsert our duplicates
                {
                    var hiddenkvp = OffsetMap[duplicates[x]];
                    bw.Write(hiddenkvp.Item1);
                    bw.Write(hiddenkvp.Item2);
                }
                else
                {
                    bw.BaseStream.Position += sizeof(int) + sizeof(short); //0 fill
                }
            }

            ids.Clear();
        }
Пример #2
0
        public virtual void WriteHeader(BinaryWriter bw, DBEntry entry)
        {
            //Signature
            bw.Write(Encoding.UTF8.GetBytes(Signature));

            //Record count
            if (IsTypeOf <WDB5>() && !(this as WDB5).HasOffsetTable && entry.Header.CopyTableSize > 0)
            {
                bw.Write(entry.GetUniqueRows().Count());
            }
            else
            {
                bw.Write(entry.Data.Rows.Count);
            }

            //WCH7 specific field
            if (IsTypeOf <WCH7>())
            {
                bw.Write(UnknownWCH7);
            }

            //FieldCount
            if (IsTypeOf <WDB5>())
            {
                bw.Write(((WDB5)this).HasIndexTable ? FieldCount - 1 : FieldCount); //Index Table
            }
            else
            {
                bw.Write(FieldCount);
            }

            //Record size
            bw.Write(RecordSize);

            //StringBlockSize placeholder
            if (IsTypeOf <WDB5>() || IsTypeOf <WCH7>())
            {
                bw.Write((uint)2);
            }
            else
            {
                bw.Write((uint)1);
            }
        }
Пример #3
0
        public override void WriteIndexTable(BinaryWriter bw, DBEntry entry)
        {
            int m = 0;

            int[] ids;
            int   index = entry.Data.Columns.IndexOf(entry.Key);

            if (!HasOffsetTable && entry.Header.CopyTableSize > 0)
            {
                ids = entry.GetUniqueRows().Select(x => x.Field <int>(index)).ToArray();
            }
            else
            {
                ids = entry.GetPrimaryKeys().ToArray();
            }

            if (entry.Header.HasRelationshipData)
            {
                //TODO figure out if it is always the 2nd column
                ushort[] secondids = entry.Data.Rows.Cast <DataRow>().Select(x => x.Field <ushort>(2)).ToArray();

                //Write all of the secondary ids
                foreach (ushort id in secondids)
                {
                    //Populate missing secondary ids with 0
                    if (m > 0 && (ids[m] - ids[m - 1]) > 1)
                    {
                        bw.BaseStream.Position += sizeof(int) * (ids[m] - ids[m - 1] - 1);
                    }

                    bw.Write((int)id);
                    m++;
                }
            }

            //Write all the IDs
            bw.WriteArray(ids);
        }
Пример #4
0
        public override void WriteIndexTable <T>(BinaryWriter bw, DBEntry <T> entry)
        {
            int m = 0;

            int[]        ids;
            PropertyInfo secondId = entry.TableStructure[2];

            if (!HasOffsetTable)
            {
                ids = entry.GetUniqueRows().Select(x => (int)entry.PrimaryKey.GetValue(x)).ToArray();
            }
            else
            {
                ids = entry.GetPrimaryKeys().ToArray();
            }

            if (entry.Header.HasSecondIndex)
            {
                //TODO figure out if it is always the 2nd column
                ushort[] secondids = entry.Rows.Select(x => (ushort)secondId.GetValue(x)).ToArray();

                //Write all of the secondary ids
                foreach (ushort id in secondids)
                {
                    //Populate missing secondary ids with 0
                    if (m > 0 && (ids[m] - ids[m - 1]) > 1)
                    {
                        bw.BaseStream.Position += sizeof(int) * (ids[m] - ids[m - 1] - 1);
                    }

                    bw.Write((int)id);
                    m++;
                }
            }

            //Write all the IDs
            bw.WriteArray(ids);
        }
Пример #5
0
        public virtual void WriteHeader <T>(BinaryWriter bw, DBEntry <T> entry) where T : class
        {
            //Signature
            bw.Write(Encoding.UTF8.GetBytes(Signature));

            //Record count
            if (IsTypeOf <WDB5>() && !HasOffsetTable && CopyTableSize > 0)
            {
                bw.Write(entry.GetUniqueRows().Count());
            }
            else
            {
                bw.Write(entry.Rows.Count);
            }

            //WCH7 specific field
            if (IsTypeOf <WCH7>())
            {
                bw.Write(UnknownWCH7);
            }

            //FieldCount
            if (IsTypeOf <WDB5>() && HasIndexTable)
            {
                FieldCount--;
            }
            bw.Write(FieldCount);

            //Record size
            bw.Write(RecordSize);

            //StringBlockSize placeholder
            uint stringblocksize = (uint)((IsTypeOf <WDB5>() || IsTypeOf <WCH7>()) ? 2 : 1);

            bw.Write(stringblocksize);
        }
Пример #6
0
        public void Write(DBEntry entry, string savepath)
        {
            using (var fs = new FileStream(savepath, FileMode.Create))
                using (var ms = new MemoryStream())
                    using (var bw = new BinaryWriter(ms))
                    {
                        StringTable st = new StringTable(entry.Header.ExtendedStringTable); //Preloads null byte(s)
                        entry.Header.WriteHeader(bw, entry);

                        if (entry.Header.IsTypeOf <WDB5>() && !entry.Header.HasOffsetTable)
                        {
                            ReadIntoFile(entry, bw, entry.GetUniqueRows().ToArray(), ref st); //Insert unique rows
                        }
                        else
                        {
                            ReadIntoFile(entry, bw, entry.Data.AsEnumerable(), ref st); //Insert all rows
                        }
                        //Copy StringTable and StringTable size if it doesn't have inline strings
                        if (st.Size > 0 && !entry.Header.HasOffsetTable)
                        {
                            long pos = bw.BaseStream.Position;
                            bw.Scrub(entry.Header.StringTableOffset);
                            bw.Write(st.Size);
                            bw.Scrub(pos);
                            st.CopyTo(bw.BaseStream);
                        }
                        st.Dispose();

                        //Legion+ only
                        if (entry.Header.IsLegionFile)
                        {
                            //WCH7 Map
                            if (entry.Header.IsTypeOf <WCH7>())
                            {
                                bw.WriteArray(((WCH7)entry.Header).WCH7Table);
                            }

                            //OffsetMap
                            if (entry.Header.HasOffsetTable)
                            {
                                //Update StringTableOffset with current position
                                long pos = bw.BaseStream.Position;
                                bw.Scrub(entry.Header.StringTableOffset);
                                bw.Write((int)pos);
                                bw.Scrub(pos);

                                entry.Header.WriteOffsetMap(bw, entry, OffsetMap);

                                OffsetMap.Clear(); //Cleanup
                            }

                            //Index Table
                            if (entry.Header.HasIndexTable)
                            {
                                entry.Header.WriteIndexTable(bw, entry);
                            }

                            //CopyTable - WDB5 only
                            if (entry.Header.IsTypeOf <WDB5>())
                            {
                                ((WDB5)entry.Header).WriteCopyTable(bw, entry);
                            }
                        }

                        //Copy data to file
                        ms.Position = 0;
                        ms.CopyTo(fs);
                    }
        }
Пример #7
0
        public static void Write <T>(DBEntry <T> entry, string savepath) where T : class
        {
            if (entry.Rows.HasDuplicateKeys)
            {
                throw new Exception("Collection contains duplicate keys");
            }


            using (var fs = new FileStream(savepath, FileMode.Create))
                using (var ms = new MemoryStream())
                    using (var bw = new BinaryWriter(ms))
                    {
                        StringTable stringtable = new StringTable(entry.Header.ExtendedStringTable); //Preloads null byte(s)
                        entry.Header.WriteHeader(bw, entry);

                        if (entry.Header.IsTypeOf <WDB5>() && !entry.Header.HasOffsetTable && entry.Header.CopyTableSize > 0)
                        {
                            WriteIntoFile(entry, bw, entry.GetUniqueRows().ToArray(), ref stringtable); //Insert unique rows
                        }
                        else
                        {
                            WriteIntoFile(entry, bw, entry.Rows.AsEnumerable(), ref stringtable); //Insert all rows
                        }

                        //Copy StringTable and StringTable size if it doesn't have inline strings
                        if (stringtable.Size > 0 && !entry.Header.HasOffsetTable)
                        {
                            long pos = bw.BaseStream.Position;
                            bw.Scrub(entry.Header.StringTableOffset);
                            bw.Write(stringtable.Size);
                            bw.Scrub(pos);
                            stringtable.CopyTo(bw.BaseStream);
                        }
                        stringtable.Dispose();

                        //Legion+ only
                        if (entry.Header.IsLegionFile)
                        {
                            //WCH7 Map
                            if (entry.Header.IsTypeOf <WCH7>())
                            {
                                bw.WriteArray(((WCH7)entry.Header).WCH7Table);
                            }

                            //OffsetMap
                            if (entry.Header.HasOffsetTable)
                            {
                                //Update StringTableOffset with current position
                                long pos = bw.BaseStream.Position;
                                bw.Scrub(entry.Header.StringTableOffset);
                                bw.Write((int)pos);
                                bw.Scrub(pos);

                                entry.Header.WriteOffsetMap(bw, entry, OffsetMap);

                                OffsetMap.Clear(); //Cleanup
                            }

                            //Index Table
                            if (entry.Header.HasIndexTable)
                            {
                                entry.Header.WriteIndexTable(bw, entry);
                            }

                            //CopyTable - WDB5 only
                            if (entry.Header.IsTypeOf <WDB5>())
                            {
                                ((WDB5)entry.Header).WriteCopyTable(bw, entry);
                            }

                            //CommonDataTable
                            if (entry.Header.IsTypeOf <WDB6>())
                            {
                                ((WDB6)entry.Header).WriteCommonDataTable(bw, entry);
                            }
                        }

                        //Copy data to file
                        ms.Position = 0;
                        ms.CopyTo(fs);
                    }
        }