Exemple #1
0
        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);
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        internal void ValidateSecondHeader(BitReader parentReader, DwgHeaderVariables headerVariables)
        {
            var reader = parentReader.FromOffset(SecondHeaderPointer);

            reader.ValidateSentinel(SecondHeaderStartSentinel);
            var sectionStart = reader.Offset;

            reader.StartCrcCheck();
            var reportedSectionSize = reader.Read_RL();
            var expectedLocation    = reader.Read_BL();

            if (expectedLocation != sectionStart - SecondHeaderStartSentinel.Length)
            {
                throw new DwgReadException("Reported second header location incorrect.");
            }

            var version = DwgVersionIdExtensions.VersionIdFromString(reader.ReadStringAscii(6));

            if (version != Version)
            {
                throw new DwgReadException("Inconsistent reported version.");
            }

            reader.ReadBytes(6);
            reader.Read_B();
            reader.Read_B();
            reader.Read_B();
            reader.Read_B();
            reader.ReadBytes(2);
            reader.ValidateBytes(SecondHeaderMidSentinel);

            var recordLocatorCount = reader.ReadByte();

            for (int i = 0; i < recordLocatorCount; i++)
            {
                var id      = reader.ReadByte();
                var pointer = reader.Read_BL();
                var length  = reader.Read_BL();

                if (pointer != 0)
                {
                    switch (i)
                    {
                    case 0:
                        HeaderVariablesLocator.ValidateLocator(id, pointer, length);
                        break;

                    case 1:
                        ClassSectionLocator.ValidateLocator(id, pointer, length);
                        break;

                    case 2:
                        ObjectMapLocator.ValidateLocator(id, pointer, length);
                        break;

                    case 3:
                        UnknownSection_R13C3AndLaterLocator.ValidateLocator(id, pointer, length);
                        break;

                    case 4:
                        UnknownSection_PaddingLocator.ValidateLocator(id, pointer, length);
                        break;
                    }
                }
            }

            var handleRecordCount = reader.Read_BS();

            for (int i = 0; i < handleRecordCount; i++)
            {
                var byteCount = reader.Read_RC();
                var id        = reader.Read_RC();
                var handle    = DwgHandleReference.ReadSecondHeader(reader, byteCount);

                if (byteCount > 0)
                {
                    if (id != i)
                    {
                        throw new DwgReadException("Invalid record handle ID.");
                    }

                    var actualHandle = -1;
                    switch (i)
                    {
                    case 0:
                        actualHandle = headerVariables.NextAvailableHandle.HandleOrOffset;
                        break;

                    case 1:
                        actualHandle = headerVariables.BlockControlObjectHandle.HandleOrOffset;
                        break;

                    case 2:
                        actualHandle = headerVariables.LayerControlObjectHandle.HandleOrOffset;
                        break;

                    case 3:
                        actualHandle = headerVariables.StyleObjectControlHandle.HandleOrOffset;
                        break;

                    case 4:
                        actualHandle = headerVariables.LineTypeObjectControlHandle.HandleOrOffset;
                        break;

                    case 5:
                        actualHandle = headerVariables.ViewControlObjectHandle.HandleOrOffset;
                        break;

                    case 6:
                        actualHandle = headerVariables.UcsControlObjectHandle.HandleOrOffset;
                        break;

                    case 7:
                        actualHandle = headerVariables.ViewPortControlObjectHandle.HandleOrOffset;
                        break;

                    case 8:
                        actualHandle = headerVariables.AppIdControlObjectHandle.HandleOrOffset;
                        break;

                    case 9:
                        actualHandle = headerVariables.DimStyleControlObjectHandle.HandleOrOffset;
                        break;

                    case 10:
                        actualHandle = headerVariables.ViewPortEntityHeaderControlObjectHandle.HandleOrOffset;
                        break;

                    case 11:
                        actualHandle = headerVariables.NamedObjectsDictionaryHandle.HandleOrOffset;
                        break;

                    case 12:
                        actualHandle = headerVariables.MLineStyleDictionaryHandle.HandleOrOffset;
                        break;

                    case 13:
                        actualHandle = headerVariables.GroupDictionaryHandle.HandleOrOffset;
                        break;
                    }

                    if (actualHandle > 0)
                    {
                        if (handle != actualHandle)
                        {
                            throw new DwgReadException($"Invalid record handle ID at location {i}.  Expected: {handle}, Actual: {actualHandle}");
                        }
                    }
                }
            }

            reader.ReadByte();
            reader.ValidateCrc(initialValue: DwgHeaderVariables.InitialCrcValue);
            var junkByteCount = Math.Max(0, reportedSectionSize - (reader.Offset - sectionStart));

            reader.SkipBytes(junkByteCount);
            reader.ValidateSentinel(SecondHeaderEndSentinel);

            var computedSectionSize = reader.Offset - sectionStart - SecondHeaderEndSentinel.Length;

            if (computedSectionSize != reportedSectionSize)
            {
                throw new DwgReadException($"Reported and actual second header sizes differ.  Expected: {reportedSectionSize}, Actual: {computedSectionSize}");
            }
        }