private const uint WDB4FmtSig = 0x34424457; // WDB4 public WDB4Writer(WDB4Reader reader, IDictionary <int, T> storage, Stream stream) : base(reader) { // always 2 empties StringTableSize++; WDB4RowSerializer <T> serializer = new WDB4RowSerializer <T>(this); serializer.Serialize(storage); serializer.GetCopyRows(); RecordsCount = serializer.Records.Count - CopyData.Count; using (var writer = new BinaryWriter(stream)) { int minIndex = storage.Keys.Min(); int maxIndex = storage.Keys.Max(); int copyTableSize = Flags.HasFlagExt(DB2Flags.Sparse) ? 0 : CopyData.Count * 8; writer.Write(WDB4FmtSig); writer.Write(RecordsCount); writer.Write(FieldsCount); writer.Write(RecordSize); writer.Write(StringTableSize); // if flags & 0x01 != 0, offset to the offset_map writer.Write(reader.TableHash); writer.Write(reader.Build); writer.Write((uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds()); writer.Write(minIndex); writer.Write(maxIndex); writer.Write(reader.Locale); writer.Write(copyTableSize); writer.Write((uint)Flags); if (storage.Count == 0) { return; } // record data uint recordsOffset = (uint)writer.BaseStream.Position; foreach (var record in serializer.Records) { if (!CopyData.ContainsKey(record.Key)) { record.Value.CopyTo(writer.BaseStream); } } // string table if (!Flags.HasFlagExt(DB2Flags.Sparse)) { writer.WriteCString(""); foreach (var str in StringTableStingAsKeyPosAsValue) { writer.WriteCString(str.Key); } } // sparse data if (Flags.HasFlagExt(DB2Flags.Sparse)) { // change the StringTableSize to the offset_map position long oldPos = writer.BaseStream.Position; writer.BaseStream.Position = 16; writer.Write((uint)oldPos); writer.BaseStream.Position = oldPos; WriteOffsetRecords(writer, serializer, recordsOffset, maxIndex - minIndex + 1); } // secondary key if (Flags.HasFlagExt(DB2Flags.SecondaryKey)) { WriteSecondaryKeyData(writer, storage, maxIndex - minIndex + 1); } // index table if (Flags.HasFlagExt(DB2Flags.Index)) { writer.WriteArray(serializer.Records.Keys.Except(CopyData.Keys).ToArray()); } // copy table if (!Flags.HasFlagExt(DB2Flags.Sparse)) { foreach (var copyRecord in CopyData) { writer.Write(copyRecord.Key); writer.Write(copyRecord.Value); } } } }