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(); }
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); } }
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); }
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); }
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); }
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); } }
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); } }