示例#1
0
        public static DwgDrawing Load(byte[] data)
        {
            var reader  = new BitReader(data);
            var drawing = new DwgDrawing();

            drawing.FileHeader = DwgFileHeader.Parse(reader);
            drawing.Variables  = DwgHeaderVariables.Parse(reader.FromOffset(drawing.FileHeader.HeaderVariablesLocator.Pointer), drawing.FileHeader.Version);
            drawing.Classes    = DwgClasses.Parse(reader.FromOffset(drawing.FileHeader.ClassSectionLocator.Pointer), drawing.FileHeader.Version);
            // don't read the R13C3 and later unknown section
            drawing.FileHeader.ValidateSecondHeader(reader, drawing.Variables);
            drawing.ImageData = DwgImageData.Parse(reader.FromOffset(drawing.FileHeader.ImagePointer));

            var objectCache = DwgObjectCache.Parse(reader.FromOffset(drawing.FileHeader.ObjectMapLocator.Pointer), drawing.FileHeader.Version);

            drawing.LoadObjects(reader, objectCache);

            return(drawing);
        }
示例#2
0
        internal static DwgHeaderVariables Parse(BitReader reader, DwgVersionId version)
        {
            var header = new DwgHeaderVariables();

            reader.ValidateSentinel(StartSentinel);
            reader.StartCrcCheck();
            var size        = reader.Read_RL();
            var startOffset = reader.Offset;

            header.ReadVariables(reader, version);
            reader.AlignToByte();
            var unreadByteCount = Math.Max(startOffset + size - reader.Offset, 0);
            var unreadBytes     = reader.ReadBytes(unreadByteCount);

            reader.ValidateCrc(initialValue: InitialCrcValue);
            reader.ValidateSentinel(EndSentinel);
            return(header);
        }
示例#3
0
        public DwgDrawing()
        {
            FileHeader = new DwgFileHeader(DwgVersionId.Default, 0, 0, 0);
            Variables  = new DwgHeaderVariables();
            Classes    = new List <DwgClassDefinition>();

            var continuous = new DwgLineType("CONTINUOUS")
            {
                Description = "Solid line"
            };
            var defaultLayer = new DwgLayer("0")
            {
                LineType = continuous
            };
            var standardStyle      = new DwgStyle("STANDARD");
            var standardMLineStyle = DwgMLineStyle.GetDefaultMLineStyle();

            BlockHeaders = new DwgBlockControlObject()
            {
                DwgBlockHeader.GetPaperSpaceBlockRecord(defaultLayer),
                DwgBlockHeader.GetModelSpaceBlockRecord(defaultLayer)
            };
            Layers = new DwgLayerControlObject
            {
                defaultLayer
            };
            Styles = new DwgStyleControlObject()
            {
                standardStyle
            };
            LineTypes = new DwgLineTypeControlObject()
            {
                new DwgLineType("BYLAYER"),
                new DwgLineType("BYBLOCK"),
                continuous
            };
            Views     = new DwgViewControlObject();
            UCSs      = new DwgUCSControlObject();
            ViewPorts = new DwgViewPortControlObject()
            {
                DwgViewPort.GetActiveViewPort()
            };
            AppIds = new DwgAppIdControlObject()
            {
                DwgAppId.GetAcadAppId(),
                    DwgAppId.GetAcadMLeaderVersionAppId()
            };
            DimStyles = new DwgDimStyleControlObject()
            {
                DwgDimStyle.GetStandardDimStyle(standardStyle)
            };
            ViewPortEntityHeaders = new DwgViewPortEntityHeaderControlObject();
            GroupDictionary       = new DwgDictionary();
            MLineStyleDictionary  = new DwgDictionary()
            {
                { standardMLineStyle.Name, standardMLineStyle }
            };
            NamedObjectDictionary = new DwgDictionary();

            PaperSpaceBlockRecord = BlockHeaders["*PAPER_SPACE"];
            ModelSpaceBlockRecord = BlockHeaders["*MODEL_SPACE"];
            ByLayerLineType       = LineTypes["BYLAYER"];
            ByBlockLineType       = LineTypes["BYBLOCK"];
            ContinuousLineType    = LineTypes["CONTINUOUS"];
            CurrentLayer          = Layers["0"];
            TextStyle             = Styles["STANDARD"];
            CurrentEntityLineType = LineTypes["BYBLOCK"];
            DimensionStyle        = DimStyles["STANDARD"];
            CurrentMultiLineStyle = (DwgMLineStyle)MLineStyleDictionary["Standard"];
            DimensionTextStyle    = Styles["STANDARD"];
        }
示例#4
0
        public void SetNextAvailableHandle(DwgHeaderVariables variables)
        {
            var next = _nextHandle++;

            variables.NextAvailableHandle = new DwgHandleReference(DwgHandleReferenceCode.Declaration, next);
        }
示例#5
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);
            }
        }
示例#6
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}");
            }
        }