internal void Write(BitWriter writer) { writer.StartCrcCalculation(); writer.WriteStringAscii(Version.VersionString(), nullTerminated: false); writer.WriteBytes(0, 0, 0, 0, 0); if (Version == DwgVersionId.R14) { writer.WriteByte((byte)MaintenenceVersion); } else { writer.WriteByte(0); } writer.WriteByte(1); writer.WriteInt(ImagePointer); writer.WriteBytes(0, 0); writer.WriteShort(CodePage); writer.WriteInt(5); // 5 records HeaderVariablesLocator.Write(writer); ClassSectionLocator.Write(writer); ObjectMapLocator.Write(writer); UnknownSection_R13C3AndLaterLocator.Write(writer); UnknownSection_PaddingLocator.Write(writer); writer.WriteCrc(xorValue: 0x3CC4); // value for 5 records writer.WriteBytes(HeaderSentinel); }
internal void WriteSecondHeader(BitWriter writer, DwgHeaderVariables headerVariables, int pointer) { // write to memory the backtrack to fill in size and crc using (var ms = new MemoryStream()) { var tempWriter = new BitWriter(ms); tempWriter.WriteBytes(SecondHeaderStartSentinel); var sizeOffset = tempWriter.Position; tempWriter.Write_RL(0); // size, filled in later tempWriter.Write_BL(pointer); tempWriter.WriteStringAscii(Version.VersionString(), nullTerminated: false); tempWriter.WriteBytes(new byte[] { 0, 0, 0, 0, 0, 0 }); // 6 zero bytes tempWriter.WriteBits(0x00000000, 4); // 4 zero bits tempWriter.WriteBytes(new byte[] { 0, 0 }); // 2 unknown bytes tempWriter.WriteBytes(SecondHeaderMidSentinel); tempWriter.WriteByte(5); // record locator count HeaderVariablesLocator.Write(tempWriter, writingSecondHeader: true); ClassSectionLocator.Write(tempWriter, writingSecondHeader: true); ObjectMapLocator.Write(tempWriter, writingSecondHeader: true); UnknownSection_R13C3AndLaterLocator.Write(tempWriter, writingSecondHeader: true); UnknownSection_PaddingLocator.Write(tempWriter, writingSecondHeader: true); tempWriter.Write_BS(14); headerVariables.NextAvailableHandle.WriteSecondHeader(tempWriter, 0); headerVariables.BlockControlObjectHandle.WriteSecondHeader(tempWriter, 1); headerVariables.LayerControlObjectHandle.WriteSecondHeader(tempWriter, 2); headerVariables.StyleObjectControlHandle.WriteSecondHeader(tempWriter, 3); headerVariables.LineTypeObjectControlHandle.WriteSecondHeader(tempWriter, 4); headerVariables.ViewControlObjectHandle.WriteSecondHeader(tempWriter, 5); headerVariables.UcsControlObjectHandle.WriteSecondHeader(tempWriter, 6); headerVariables.ViewPortControlObjectHandle.WriteSecondHeader(tempWriter, 7); headerVariables.AppIdControlObjectHandle.WriteSecondHeader(tempWriter, 8); headerVariables.DimStyleControlObjectHandle.WriteSecondHeader(tempWriter, 9); headerVariables.ViewPortEntityHeaderControlObjectHandle.WriteSecondHeader(tempWriter, 10); headerVariables.NamedObjectsDictionaryHandle.WriteSecondHeader(tempWriter, 11); headerVariables.MLineStyleDictionaryHandle.WriteSecondHeader(tempWriter, 12); headerVariables.GroupDictionaryHandle.WriteSecondHeader(tempWriter, 13); tempWriter.WriteByte(0); // unknown tempWriter.AlignByte(); var crcOffset = tempWriter.Position; tempWriter.WriteShort(0); // CRC, filled in later if (Version == DwgVersionId.R14) { // unknown garbage bytes tempWriter.WriteBytes(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); } tempWriter.WriteBytes(SecondHeaderEndSentinel); // get bytes of header var secondHeaderBytes = tempWriter.AsBytes(); // fill in size var sizeBytes = BitConverter.GetBytes(secondHeaderBytes.Length - SecondHeaderStartSentinel.Length - SecondHeaderEndSentinel.Length); if (!BitConverter.IsLittleEndian) { Array.Reverse(sizeBytes); } Array.Copy(sizeBytes, 0, secondHeaderBytes, sizeOffset, sizeBytes.Length); // fill in crc var crc = BitReaderExtensions.ComputeCRC(secondHeaderBytes, sizeOffset, crcOffset - sizeOffset, DwgHeaderVariables.InitialCrcValue); var crcBytes = BitConverter.GetBytes(crc); if (!BitConverter.IsLittleEndian) { Array.Reverse(crcBytes); } Array.Copy(crcBytes, 0, secondHeaderBytes, crcOffset, crcBytes.Length); // write to the real writer writer.WriteBytes(secondHeaderBytes); } }