LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/cad/libopencad/dwg - r2000.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 899 2279 39.4 %
Date: 2024-05-14 13:00:50 Functions: 24 49 49.0 %

          Line data    Source code
       1             : /*******************************************************************************
       2             :  *  Project: libopencad
       3             :  *  Purpose: OpenSource CAD formats support library
       4             :  *  Author: Alexandr Borzykh, mush3d at gmail.com
       5             :  *  Author: Dmitry Baryshnikov, bishop.dev@gmail.com
       6             :  *  Language: C++
       7             :  *******************************************************************************
       8             :  *  The MIT License (MIT)
       9             :  *
      10             :  *  Copyright (c) 2016 Alexandr Borzykh
      11             :  *  Copyright (c) 2016-2018 NextGIS, <info@nextgis.com>
      12             :  *
      13             :  *  Permission is hereby granted, free of charge, to any person obtaining a copy
      14             :  *  of this software and associated documentation files (the "Software"), to deal
      15             :  *  in the Software without restriction, including without limitation the rights
      16             :  *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      17             :  *  copies of the Software, and to permit persons to whom the Software is
      18             :  *  furnished to do so, subject to the following conditions:
      19             :  *
      20             :  *  The above copyright notice and this permission notice shall be included in all
      21             :  *  copies or substantial portions of the Software.
      22             :  *
      23             :  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      24             :  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25             :  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      26             :  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27             :  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      28             :  *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      29             :  *  SOFTWARE.
      30             :  *******************************************************************************/
      31             : #include "cadgeometry.h"
      32             : #include "cadobjects.h"
      33             : #include "opencad_api.h"
      34             : #include "r2000.h"
      35             : 
      36             : #include <cassert>
      37             : #include <cstring>
      38             : #include <iostream>
      39             : #include <limits>
      40             : #include <memory>
      41             : #include <string>
      42             : 
      43             : #if ((defined(__sun__) || defined(__FreeBSD__)) && __GNUC__ == 4 && __GNUC_MINOR__ == 8) || defined(__ANDROID__)
      44             : // gcc 4.8 on Solaris 11.3 or FreeBSD 11 doesn't have std::string
      45             : #include <sstream>
      46             : namespace std
      47             : {
      48             : template <typename T> std::string to_string(T val)
      49             : {
      50             :     std::ostringstream os;
      51             :     os << val;
      52             :     return os.str();
      53             : }
      54             : }
      55             : #endif
      56             : 
      57             : #define UNKNOWN1 CADHeader::MAX_HEADER_CONSTANT + 1
      58             : #define UNKNOWN2 CADHeader::MAX_HEADER_CONSTANT + 2
      59             : #define UNKNOWN3 CADHeader::MAX_HEADER_CONSTANT + 3
      60             : #define UNKNOWN4 CADHeader::MAX_HEADER_CONSTANT + 4
      61             : #define UNKNOWN5 CADHeader::MAX_HEADER_CONSTANT + 5
      62             : #define UNKNOWN6 CADHeader::MAX_HEADER_CONSTANT + 6
      63             : #define UNKNOWN7 CADHeader::MAX_HEADER_CONSTANT + 7
      64             : #define UNKNOWN8 CADHeader::MAX_HEADER_CONSTANT + 8
      65             : #define UNKNOWN9 CADHeader::MAX_HEADER_CONSTANT + 9
      66             : #define UNKNOWN10 CADHeader::MAX_HEADER_CONSTANT + 10
      67             : #define UNKNOWN11 CADHeader::MAX_HEADER_CONSTANT + 11
      68             : #define UNKNOWN12 CADHeader::MAX_HEADER_CONSTANT + 12
      69             : #define UNKNOWN13 CADHeader::MAX_HEADER_CONSTANT + 13
      70             : #define UNKNOWN14 CADHeader::MAX_HEADER_CONSTANT + 14
      71             : #define UNKNOWN15 CADHeader::MAX_HEADER_CONSTANT + 15
      72             : 
      73             : using namespace std;
      74             : 
      75           8 : int DWGFileR2000::ReadHeader( OpenOptions eOptions )
      76             : {
      77             :     char bufferPre[255];
      78           8 :     unsigned dHeaderVarsSectionLength = 0;
      79           8 :     constexpr size_t dSizeOfSectionSize = sizeof(dHeaderVarsSectionLength);
      80             : 
      81           8 :     pFileIO->Seek( sectionLocatorRecords[0].dSeeker, CADFileIO::SeekOrigin::BEG );
      82           8 :     size_t readSize = pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
      83           8 :     if(readSize < DWGConstants::SentinelLength)
      84             :     {
      85           0 :         DebugMsg( "File is corrupted (size is less than sentinel length)" );
      86             : 
      87           0 :         return CADErrorCodes::HEADER_SECTION_READ_FAILED;
      88             :     }
      89             : 
      90             : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
      91           8 :     if( memcmp( bufferPre, DWGConstants::HeaderVariablesStart,
      92             :                            DWGConstants::SentinelLength ) )
      93             :     {
      94           0 :         DebugMsg( "File is corrupted (wrong pointer to HEADER_VARS section,"
      95             :                           "or HEADERVARS starting sentinel corrupted.)" );
      96             : 
      97           0 :         return CADErrorCodes::HEADER_SECTION_READ_FAILED;
      98             :     }
      99             : #endif
     100             : 
     101           8 :     readSize = pFileIO->Read( &dHeaderVarsSectionLength, dSizeOfSectionSize );
     102           8 :     const auto dHeaderVarsSectionLengthOriginal = dHeaderVarsSectionLength;
     103           8 :     FromLSB(dHeaderVarsSectionLength);
     104           8 :     DebugMsg( "Header variables section length: %d\n",
     105             :               static_cast<int>(dHeaderVarsSectionLength) );
     106           8 :     if(readSize != dSizeOfSectionSize || dHeaderVarsSectionLength > 65536) //NOTE: maybe header section may be bigger
     107             :     {
     108           0 :         DebugMsg( "File is corrupted (HEADER_VARS section length too big)" );
     109           0 :         return CADErrorCodes::HEADER_SECTION_READ_FAILED;
     110             :     }
     111             : 
     112          16 :     CADBuffer buffer(dHeaderVarsSectionLength + dSizeOfSectionSize + 10);
     113           8 :     buffer.WriteRAW(&dHeaderVarsSectionLengthOriginal, dSizeOfSectionSize);
     114           8 :     readSize = pFileIO->Read(buffer.GetRawBuffer(), dHeaderVarsSectionLength + 2 );
     115           8 :     if(readSize != dHeaderVarsSectionLength + 2)
     116             :     {
     117           0 :         DebugMsg( "Failed to read %d byte of file. Read only %d",
     118           0 :                   static_cast<int>(dHeaderVarsSectionLength + 2),
     119             :                   static_cast<int>(readSize) );
     120           0 :         return CADErrorCodes::HEADER_SECTION_READ_FAILED;
     121             :     }
     122             : 
     123           8 :     if( eOptions == OpenOptions::READ_ALL )
     124             :     {
     125           0 :         oHeader.addValue( UNKNOWN1, buffer.ReadBITDOUBLE() );
     126           0 :         oHeader.addValue( UNKNOWN2, buffer.ReadBITDOUBLE() );
     127           0 :         oHeader.addValue( UNKNOWN3, buffer.ReadBITDOUBLE() );
     128           0 :         oHeader.addValue( UNKNOWN4, buffer.ReadBITDOUBLE() );
     129           0 :         oHeader.addValue( UNKNOWN5, buffer.ReadTV() );
     130           0 :         oHeader.addValue( UNKNOWN6, buffer.ReadTV() );
     131           0 :         oHeader.addValue( UNKNOWN7, buffer.ReadTV() );
     132           0 :         oHeader.addValue( UNKNOWN8, buffer.ReadTV() );
     133           0 :         oHeader.addValue( UNKNOWN9, buffer.ReadBITLONG() );
     134           0 :         oHeader.addValue( UNKNOWN10, buffer.ReadBITLONG() );
     135             :     }
     136             :     else
     137             :     {
     138           8 :         buffer.SkipBITDOUBLE();
     139           8 :         buffer.SkipBITDOUBLE();
     140           8 :         buffer.SkipBITDOUBLE();
     141           8 :         buffer.SkipBITDOUBLE();
     142           8 :         buffer.SkipTV();
     143           8 :         buffer.SkipTV();
     144           8 :         buffer.SkipTV();
     145           8 :         buffer.SkipTV();
     146           8 :         buffer.SkipBITLONG();
     147           8 :         buffer.SkipBITLONG();
     148             :     }
     149             : 
     150          16 :     CADHandle stCurrentViewportTable = buffer.ReadHANDLE();
     151           8 :     oTables.AddTable( CADTables::CurrentViewportTable, stCurrentViewportTable );
     152             : 
     153           8 :     if( eOptions == OpenOptions::READ_ALL )
     154             :     {
     155           0 :         oHeader.addValue( CADHeader::DIMASO, buffer.ReadBIT() );     // 1
     156           0 :         oHeader.addValue( CADHeader::DIMSHO, buffer.ReadBIT() );     // 2
     157           0 :         oHeader.addValue( CADHeader::PLINEGEN, buffer.ReadBIT() );   // 3
     158           0 :         oHeader.addValue( CADHeader::ORTHOMODE, buffer.ReadBIT() );  // 4
     159           0 :         oHeader.addValue( CADHeader::REGENMODE, buffer.ReadBIT() );  // 5
     160           0 :         oHeader.addValue( CADHeader::FILLMODE, buffer.ReadBIT() );   // 6
     161           0 :         oHeader.addValue( CADHeader::QTEXTMODE, buffer.ReadBIT() );  // 7
     162           0 :         oHeader.addValue( CADHeader::PSLTSCALE, buffer.ReadBIT() );  // 8
     163           0 :         oHeader.addValue( CADHeader::LIMCHECK, buffer.ReadBIT() );   // 9
     164           0 :         oHeader.addValue( CADHeader::USRTIMER, buffer.ReadBIT() );   // 10
     165           0 :         oHeader.addValue( CADHeader::SKPOLY, buffer.ReadBIT() );     // 11
     166           0 :         oHeader.addValue( CADHeader::ANGDIR, buffer.ReadBIT() );     // 12
     167           0 :         oHeader.addValue( CADHeader::SPLFRAME, buffer.ReadBIT() );   // 13
     168           0 :         oHeader.addValue( CADHeader::MIRRTEXT, buffer.ReadBIT() );   // 14
     169           0 :         oHeader.addValue( CADHeader::WORDLVIEW, buffer.ReadBIT() );  // 15
     170           0 :         oHeader.addValue( CADHeader::TILEMODE, buffer.ReadBIT() );   // 16
     171           0 :         oHeader.addValue( CADHeader::PLIMCHECK, buffer.ReadBIT() );  // 17
     172           0 :         oHeader.addValue( CADHeader::VISRETAIN, buffer.ReadBIT() );  // 18
     173           0 :         oHeader.addValue( CADHeader::DISPSILH, buffer.ReadBIT() );   // 19
     174           0 :         oHeader.addValue( CADHeader::PELLIPSE, buffer.ReadBIT() );   // 20
     175             :     }
     176             :     else
     177             :     {
     178           8 :         buffer.Seek(20);
     179             :     }
     180             : 
     181           8 :     if( eOptions == OpenOptions::READ_ALL )
     182             :     {
     183           0 :         oHeader.addValue( CADHeader::PROXYGRAPHICS, buffer.ReadBITSHORT() ); // 1
     184           0 :         oHeader.addValue( CADHeader::TREEDEPTH, buffer.ReadBITSHORT() );     // 2
     185           0 :         oHeader.addValue( CADHeader::LUNITS, buffer.ReadBITSHORT() );        // 3
     186           0 :         oHeader.addValue( CADHeader::LUPREC, buffer.ReadBITSHORT() );        // 4
     187           0 :         oHeader.addValue( CADHeader::AUNITS, buffer.ReadBITSHORT() );        // 5
     188           0 :         oHeader.addValue( CADHeader::AUPREC, buffer.ReadBITSHORT() );        // 6
     189             :     } else
     190             :     {
     191          56 :         for( char i = 0; i < 6; ++i )
     192          48 :             buffer.SkipBITSHORT();
     193             :     }
     194             : 
     195           8 :     oHeader.addValue( CADHeader::ATTMODE, buffer.ReadBITSHORT() );
     196           8 :     oHeader.addValue( CADHeader::PDMODE, buffer.ReadBITSHORT() );
     197             : 
     198           8 :     if( eOptions == OpenOptions::READ_ALL )
     199             :     {
     200           0 :         oHeader.addValue( CADHeader::USERI1, buffer.ReadBITSHORT() );    // 1
     201           0 :         oHeader.addValue( CADHeader::USERI2, buffer.ReadBITSHORT() );    // 2
     202           0 :         oHeader.addValue( CADHeader::USERI3, buffer.ReadBITSHORT() );    // 3
     203           0 :         oHeader.addValue( CADHeader::USERI4, buffer.ReadBITSHORT() );    // 4
     204           0 :         oHeader.addValue( CADHeader::USERI5, buffer.ReadBITSHORT() );    // 5
     205           0 :         oHeader.addValue( CADHeader::SPLINESEGS, buffer.ReadBITSHORT() );// 6
     206           0 :         oHeader.addValue( CADHeader::SURFU, buffer.ReadBITSHORT() );     // 7
     207           0 :         oHeader.addValue( CADHeader::SURFV, buffer.ReadBITSHORT() );     // 8
     208           0 :         oHeader.addValue( CADHeader::SURFTYPE, buffer.ReadBITSHORT() );  // 9
     209           0 :         oHeader.addValue( CADHeader::SURFTAB1, buffer.ReadBITSHORT() );  // 10
     210           0 :         oHeader.addValue( CADHeader::SURFTAB2, buffer.ReadBITSHORT() );  // 11
     211           0 :         oHeader.addValue( CADHeader::SPLINETYPE, buffer.ReadBITSHORT() );// 12
     212           0 :         oHeader.addValue( CADHeader::SHADEDGE, buffer.ReadBITSHORT() );  // 13
     213           0 :         oHeader.addValue( CADHeader::SHADEDIF, buffer.ReadBITSHORT() );  // 14
     214           0 :         oHeader.addValue( CADHeader::UNITMODE, buffer.ReadBITSHORT() );  // 15
     215           0 :         oHeader.addValue( CADHeader::MAXACTVP, buffer.ReadBITSHORT() );  // 16
     216           0 :         oHeader.addValue( CADHeader::ISOLINES, buffer.ReadBITSHORT() );  // 17
     217           0 :         oHeader.addValue( CADHeader::CMLJUST, buffer.ReadBITSHORT() );   // 18
     218           0 :         oHeader.addValue( CADHeader::TEXTQLTY, buffer.ReadBITSHORT() );  // 19
     219             :     }
     220             :     else
     221             :     {
     222         160 :         for( char i = 0; i < 19; ++i )
     223         152 :             buffer.SkipBITSHORT();
     224             :     }
     225             : 
     226           8 :     oHeader.addValue( CADHeader::LTSCALE, buffer.ReadBITDOUBLE() );
     227           8 :     oHeader.addValue( CADHeader::TEXTSIZE, buffer.ReadBITDOUBLE() );
     228           8 :     oHeader.addValue( CADHeader::TRACEWID, buffer.ReadBITDOUBLE() );
     229           8 :     oHeader.addValue( CADHeader::SKETCHINC, buffer.ReadBITDOUBLE() );
     230           8 :     oHeader.addValue( CADHeader::FILLETRAD, buffer.ReadBITDOUBLE() );
     231           8 :     oHeader.addValue( CADHeader::THICKNESS, buffer.ReadBITDOUBLE() );
     232           8 :     oHeader.addValue( CADHeader::ANGBASE, buffer.ReadBITDOUBLE() );
     233           8 :     oHeader.addValue( CADHeader::PDSIZE, buffer.ReadBITDOUBLE() );
     234           8 :     oHeader.addValue( CADHeader::PLINEWID, buffer.ReadBITDOUBLE() );
     235             : 
     236           8 :     if( eOptions == OpenOptions::READ_ALL )
     237             :     {
     238           0 :         oHeader.addValue( CADHeader::USERR1, buffer.ReadBITDOUBLE() );   // 1
     239           0 :         oHeader.addValue( CADHeader::USERR2, buffer.ReadBITDOUBLE() );   // 2
     240           0 :         oHeader.addValue( CADHeader::USERR3, buffer.ReadBITDOUBLE() );   // 3
     241           0 :         oHeader.addValue( CADHeader::USERR4, buffer.ReadBITDOUBLE() );   // 4
     242           0 :         oHeader.addValue( CADHeader::USERR5, buffer.ReadBITDOUBLE() );   // 5
     243           0 :         oHeader.addValue( CADHeader::CHAMFERA, buffer.ReadBITDOUBLE() ); // 6
     244           0 :         oHeader.addValue( CADHeader::CHAMFERB, buffer.ReadBITDOUBLE() ); // 7
     245           0 :         oHeader.addValue( CADHeader::CHAMFERC, buffer.ReadBITDOUBLE() ); // 8
     246           0 :         oHeader.addValue( CADHeader::CHAMFERD, buffer.ReadBITDOUBLE() ); // 9
     247           0 :         oHeader.addValue( CADHeader::FACETRES, buffer.ReadBITDOUBLE() ); // 10
     248           0 :         oHeader.addValue( CADHeader::CMLSCALE, buffer.ReadBITDOUBLE() ); // 11
     249           0 :         oHeader.addValue( CADHeader::CELTSCALE, buffer.ReadBITDOUBLE() );// 12
     250             : 
     251           0 :         oHeader.addValue( CADHeader::MENU, buffer.ReadTV() );
     252             :     } else
     253             :     {
     254         104 :         for( char i = 0; i < 12; ++i )
     255          96 :             buffer.SkipBITDOUBLE();
     256           8 :         buffer.SkipTV();
     257             :     }
     258             : 
     259             :     long juliandate, millisec;
     260           8 :     juliandate = buffer.ReadBITLONG();
     261           8 :     millisec   = buffer.ReadBITLONG();
     262           8 :     oHeader.addValue( CADHeader::TDCREATE, juliandate, millisec );
     263           8 :     juliandate = buffer.ReadBITLONG();
     264           8 :     millisec   = buffer.ReadBITLONG();
     265           8 :     oHeader.addValue( CADHeader::TDUPDATE, juliandate, millisec );
     266           8 :     juliandate = buffer.ReadBITLONG();
     267           8 :     millisec   = buffer.ReadBITLONG();
     268           8 :     oHeader.addValue( CADHeader::TDINDWG, juliandate, millisec );
     269           8 :     juliandate = buffer.ReadBITLONG();
     270           8 :     millisec   = buffer.ReadBITLONG();
     271           8 :     oHeader.addValue( CADHeader::TDUSRTIMER, juliandate, millisec );
     272             : 
     273           8 :     oHeader.addValue( CADHeader::CECOLOR, buffer.ReadBITSHORT() );
     274             : 
     275           8 :     oHeader.addValue( CADHeader::HANDSEED, buffer.ReadHANDLE() );
     276             : 
     277           8 :     oHeader.addValue( CADHeader::CLAYER, buffer.ReadHANDLE() );
     278           8 :     oHeader.addValue( CADHeader::TEXTSTYLE, buffer.ReadHANDLE() );
     279           8 :     oHeader.addValue( CADHeader::CELTYPE, buffer.ReadHANDLE() );
     280           8 :     oHeader.addValue( CADHeader::DIMSTYLE, buffer.ReadHANDLE() );
     281           8 :     oHeader.addValue( CADHeader::CMLSTYLE, buffer.ReadHANDLE() );
     282             : 
     283           8 :     oHeader.addValue( CADHeader::PSVPSCALE, buffer.ReadBITDOUBLE() );
     284             :     double dX, dY, dZ;
     285           8 :     dX = buffer.ReadBITDOUBLE();
     286           8 :     dY = buffer.ReadBITDOUBLE();
     287           8 :     dZ = buffer.ReadBITDOUBLE();
     288           8 :     oHeader.addValue( CADHeader::PINSBASE, dX, dY, dZ );
     289             : 
     290           8 :     dX = buffer.ReadBITDOUBLE();
     291           8 :     dY = buffer.ReadBITDOUBLE();
     292           8 :     dZ = buffer.ReadBITDOUBLE();
     293           8 :     oHeader.addValue( CADHeader::PEXTMIN, dX, dY, dZ );
     294           8 :     dX = buffer.ReadBITDOUBLE();
     295           8 :     dY = buffer.ReadBITDOUBLE();
     296           8 :     dZ = buffer.ReadBITDOUBLE();
     297           8 :     oHeader.addValue( CADHeader::PEXTMAX, dX, dY, dZ );
     298           8 :     dX = buffer.ReadRAWDOUBLE();
     299           8 :     dY = buffer.ReadRAWDOUBLE();
     300           8 :     oHeader.addValue( CADHeader::PLIMMIN, dX, dY );
     301           8 :     dX = buffer.ReadRAWDOUBLE();
     302           8 :     dY = buffer.ReadRAWDOUBLE();
     303           8 :     oHeader.addValue( CADHeader::PLIMMAX, dX, dY );
     304             : 
     305           8 :     oHeader.addValue( CADHeader::PELEVATION, buffer.ReadBITDOUBLE() );
     306             : 
     307           8 :     dX = buffer.ReadBITDOUBLE();
     308           8 :     dY = buffer.ReadBITDOUBLE();
     309           8 :     dZ = buffer.ReadBITDOUBLE();
     310           8 :     oHeader.addValue( CADHeader::PUCSORG, dX, dY, dZ );
     311           8 :     dX = buffer.ReadBITDOUBLE();
     312           8 :     dY = buffer.ReadBITDOUBLE();
     313           8 :     dZ = buffer.ReadBITDOUBLE();
     314           8 :     oHeader.addValue( CADHeader::PUCSXDIR, dX, dY, dZ );
     315           8 :     dX = buffer.ReadBITDOUBLE();
     316           8 :     dY = buffer.ReadBITDOUBLE();
     317           8 :     dZ = buffer.ReadBITDOUBLE();
     318           8 :     oHeader.addValue( CADHeader::PUCSYDIR, dX, dY, dZ );
     319             : 
     320           8 :     oHeader.addValue( CADHeader::PUCSNAME, buffer.ReadHANDLE() );
     321           8 :     oHeader.addValue( CADHeader::PUCSORTHOREF, buffer.ReadHANDLE() );
     322             : 
     323           8 :     oHeader.addValue( CADHeader::PUCSORTHOVIEW, buffer.ReadBITSHORT() );
     324           8 :     oHeader.addValue( CADHeader::PUCSBASE, buffer.ReadHANDLE() );
     325             : 
     326           8 :     dX = buffer.ReadBITDOUBLE();
     327           8 :     dY = buffer.ReadBITDOUBLE();
     328           8 :     dZ = buffer.ReadBITDOUBLE();
     329           8 :     oHeader.addValue( CADHeader::PUCSORGTOP, dX, dY, dZ );
     330           8 :     dX = buffer.ReadBITDOUBLE();
     331           8 :     dY = buffer.ReadBITDOUBLE();
     332           8 :     dZ = buffer.ReadBITDOUBLE();
     333           8 :     oHeader.addValue( CADHeader::PUCSORGBOTTOM, dX, dY, dZ );
     334           8 :     dX = buffer.ReadBITDOUBLE();
     335           8 :     dY = buffer.ReadBITDOUBLE();
     336           8 :     dZ = buffer.ReadBITDOUBLE();
     337           8 :     oHeader.addValue( CADHeader::PUCSORGLEFT, dX, dY, dZ );
     338           8 :     dX = buffer.ReadBITDOUBLE();
     339           8 :     dY = buffer.ReadBITDOUBLE();
     340           8 :     dZ = buffer.ReadBITDOUBLE();
     341           8 :     oHeader.addValue( CADHeader::PUCSORGRIGHT, dX, dY, dZ );
     342           8 :     dX = buffer.ReadBITDOUBLE();
     343           8 :     dY = buffer.ReadBITDOUBLE();
     344           8 :     dZ = buffer.ReadBITDOUBLE();
     345           8 :     oHeader.addValue( CADHeader::PUCSORGFRONT, dX, dY, dZ );
     346           8 :     dX = buffer.ReadBITDOUBLE();
     347           8 :     dY = buffer.ReadBITDOUBLE();
     348           8 :     dZ = buffer.ReadBITDOUBLE();
     349           8 :     oHeader.addValue( CADHeader::PUCSORGBACK, dX, dY, dZ );
     350             : 
     351           8 :     dX = buffer.ReadBITDOUBLE();
     352           8 :     dY = buffer.ReadBITDOUBLE();
     353           8 :     dZ = buffer.ReadBITDOUBLE();
     354           8 :     oHeader.addValue( CADHeader::INSBASE, dX, dY, dZ );
     355           8 :     dX = buffer.ReadBITDOUBLE();
     356           8 :     dY = buffer.ReadBITDOUBLE();
     357           8 :     dZ = buffer.ReadBITDOUBLE();
     358           8 :     oHeader.addValue( CADHeader::EXTMIN, dX, dY, dZ );
     359           8 :     dX = buffer.ReadBITDOUBLE();
     360           8 :     dY = buffer.ReadBITDOUBLE();
     361           8 :     dZ = buffer.ReadBITDOUBLE();
     362           8 :     oHeader.addValue( CADHeader::EXTMAX, dX, dY, dZ );
     363           8 :     dX = buffer.ReadRAWDOUBLE();
     364           8 :     dY = buffer.ReadRAWDOUBLE();
     365           8 :     oHeader.addValue( CADHeader::LIMMIN, dX, dY );
     366           8 :     dX = buffer.ReadRAWDOUBLE();
     367           8 :     dY = buffer.ReadRAWDOUBLE();
     368           8 :     oHeader.addValue( CADHeader::LIMMAX, dX, dY );
     369             : 
     370           8 :     oHeader.addValue( CADHeader::ELEVATION, buffer.ReadBITDOUBLE() );
     371           8 :     dX = buffer.ReadBITDOUBLE();
     372           8 :     dY = buffer.ReadBITDOUBLE();
     373           8 :     dZ = buffer.ReadBITDOUBLE();
     374           8 :     oHeader.addValue( CADHeader::UCSORG, dX, dY, dZ );
     375           8 :     dX = buffer.ReadBITDOUBLE();
     376           8 :     dY = buffer.ReadBITDOUBLE();
     377           8 :     dZ = buffer.ReadBITDOUBLE();
     378           8 :     oHeader.addValue( CADHeader::UCSXDIR, dX, dY, dZ );
     379           8 :     dX = buffer.ReadBITDOUBLE();
     380           8 :     dY = buffer.ReadBITDOUBLE();
     381           8 :     dZ = buffer.ReadBITDOUBLE();
     382           8 :     oHeader.addValue( CADHeader::UCSYDIR, dX, dY, dZ );
     383             : 
     384           8 :     oHeader.addValue( CADHeader::UCSNAME, buffer.ReadHANDLE() );
     385           8 :     oHeader.addValue( CADHeader::UCSORTHOREF, buffer.ReadHANDLE() );
     386             : 
     387           8 :     oHeader.addValue( CADHeader::UCSORTHOVIEW, buffer.ReadBITSHORT() );
     388             : 
     389           8 :     oHeader.addValue( CADHeader::UCSBASE, buffer.ReadHANDLE() );
     390             : 
     391           8 :     dX = buffer.ReadBITDOUBLE();
     392           8 :     dY = buffer.ReadBITDOUBLE();
     393           8 :     dZ = buffer.ReadBITDOUBLE();
     394           8 :     oHeader.addValue( CADHeader::UCSORGTOP, dX, dY, dZ );
     395           8 :     dX = buffer.ReadBITDOUBLE();
     396           8 :     dY = buffer.ReadBITDOUBLE();
     397           8 :     dZ = buffer.ReadBITDOUBLE();
     398           8 :     oHeader.addValue( CADHeader::UCSORGBOTTOM, dX, dY, dZ );
     399           8 :     dX = buffer.ReadBITDOUBLE();
     400           8 :     dY = buffer.ReadBITDOUBLE();
     401           8 :     dZ = buffer.ReadBITDOUBLE();
     402           8 :     oHeader.addValue( CADHeader::UCSORGLEFT, dX, dY, dZ );
     403           8 :     dX = buffer.ReadBITDOUBLE();
     404           8 :     dY = buffer.ReadBITDOUBLE();
     405           8 :     dZ = buffer.ReadBITDOUBLE();
     406           8 :     oHeader.addValue( CADHeader::UCSORGRIGHT, dX, dY, dZ );
     407           8 :     dX = buffer.ReadBITDOUBLE();
     408           8 :     dY = buffer.ReadBITDOUBLE();
     409           8 :     dZ = buffer.ReadBITDOUBLE();
     410           8 :     oHeader.addValue( CADHeader::UCSORGFRONT, dX, dY, dZ );
     411           8 :     dX = buffer.ReadBITDOUBLE();
     412           8 :     dY = buffer.ReadBITDOUBLE();
     413           8 :     dZ = buffer.ReadBITDOUBLE();
     414           8 :     oHeader.addValue( CADHeader::UCSORGBACK, dX, dY, dZ );
     415             : 
     416           8 :     if( eOptions == OpenOptions::READ_ALL )
     417             :     {
     418           0 :         oHeader.addValue( CADHeader::DIMPOST, buffer.ReadTV() );
     419           0 :         oHeader.addValue( CADHeader::DIMAPOST, buffer.ReadTV() );
     420             : 
     421           0 :         oHeader.addValue( CADHeader::DIMSCALE, buffer.ReadBITDOUBLE() ); // 1
     422           0 :         oHeader.addValue( CADHeader::DIMASZ, buffer.ReadBITDOUBLE() );   // 2
     423           0 :         oHeader.addValue( CADHeader::DIMEXO, buffer.ReadBITDOUBLE() );   // 3
     424           0 :         oHeader.addValue( CADHeader::DIMDLI, buffer.ReadBITDOUBLE() );   // 4
     425           0 :         oHeader.addValue( CADHeader::DIMEXE, buffer.ReadBITDOUBLE() );   // 5
     426           0 :         oHeader.addValue( CADHeader::DIMRND, buffer.ReadBITDOUBLE() );   // 6
     427           0 :         oHeader.addValue( CADHeader::DIMDLE, buffer.ReadBITDOUBLE() );   // 7
     428           0 :         oHeader.addValue( CADHeader::DIMTP, buffer.ReadBITDOUBLE() );    // 8
     429           0 :         oHeader.addValue( CADHeader::DIMTM, buffer.ReadBITDOUBLE() );    // 9
     430             : 
     431           0 :         oHeader.addValue( CADHeader::DIMTOL, buffer.ReadBIT() );
     432           0 :         oHeader.addValue( CADHeader::DIMLIM, buffer.ReadBIT() );
     433           0 :         oHeader.addValue( CADHeader::DIMTIH, buffer.ReadBIT() );
     434           0 :         oHeader.addValue( CADHeader::DIMTOH, buffer.ReadBIT() );
     435           0 :         oHeader.addValue( CADHeader::DIMSE1, buffer.ReadBIT() );
     436           0 :         oHeader.addValue( CADHeader::DIMSE2, buffer.ReadBIT() );
     437             : 
     438           0 :         oHeader.addValue( CADHeader::DIMTAD, buffer.ReadBITSHORT() );
     439           0 :         oHeader.addValue( CADHeader::DIMZIN, buffer.ReadBITSHORT() );
     440           0 :         oHeader.addValue( CADHeader::DIMAZIN, buffer.ReadBITSHORT() );
     441             : 
     442           0 :         oHeader.addValue( CADHeader::DIMTXT, buffer.ReadBITDOUBLE() );   // 1
     443           0 :         oHeader.addValue( CADHeader::DIMCEN, buffer.ReadBITDOUBLE() );   // 2
     444           0 :         oHeader.addValue( CADHeader::DIMTSZ, buffer.ReadBITDOUBLE() );   // 3
     445           0 :         oHeader.addValue( CADHeader::DIMALTF, buffer.ReadBITDOUBLE() );  // 4
     446           0 :         oHeader.addValue( CADHeader::DIMLFAC, buffer.ReadBITDOUBLE() );  // 5
     447           0 :         oHeader.addValue( CADHeader::DIMTVP, buffer.ReadBITDOUBLE() );   // 6
     448           0 :         oHeader.addValue( CADHeader::DIMTFAC, buffer.ReadBITDOUBLE() );  // 7
     449           0 :         oHeader.addValue( CADHeader::DIMGAP, buffer.ReadBITDOUBLE() );   // 8
     450           0 :         oHeader.addValue( CADHeader::DIMALTRND, buffer.ReadBITDOUBLE() );// 9
     451             : 
     452           0 :         oHeader.addValue( CADHeader::DIMALT, buffer.ReadBIT() );
     453             : 
     454           0 :         oHeader.addValue( CADHeader::DIMALTD, buffer.ReadBITSHORT() );
     455             : 
     456           0 :         oHeader.addValue( CADHeader::DIMTOFL, buffer.ReadBIT() );
     457           0 :         oHeader.addValue( CADHeader::DIMSAH, buffer.ReadBIT() );
     458           0 :         oHeader.addValue( CADHeader::DIMTIX, buffer.ReadBIT() );
     459           0 :         oHeader.addValue( CADHeader::DIMSOXD, buffer.ReadBIT() );
     460             : 
     461           0 :         oHeader.addValue( CADHeader::DIMCLRD, buffer.ReadBITSHORT() );   // 1
     462           0 :         oHeader.addValue( CADHeader::DIMCLRE, buffer.ReadBITSHORT() );   // 2
     463           0 :         oHeader.addValue( CADHeader::DIMCLRT, buffer.ReadBITSHORT() );   // 3
     464           0 :         oHeader.addValue( CADHeader::DIMADEC, buffer.ReadBITSHORT() );   // 4
     465           0 :         oHeader.addValue( CADHeader::DIMDEC, buffer.ReadBITSHORT() );    // 5
     466           0 :         oHeader.addValue( CADHeader::DIMTDEC, buffer.ReadBITSHORT() );   // 6
     467           0 :         oHeader.addValue( CADHeader::DIMALTU, buffer.ReadBITSHORT() );   // 7
     468           0 :         oHeader.addValue( CADHeader::DIMALTTD, buffer.ReadBITSHORT() );  // 8
     469           0 :         oHeader.addValue( CADHeader::DIMAUNIT, buffer.ReadBITSHORT() );  // 9
     470           0 :         oHeader.addValue( CADHeader::DIMFRAC, buffer.ReadBITSHORT() );   // 10
     471           0 :         oHeader.addValue( CADHeader::DIMLUNIT, buffer.ReadBITSHORT() );  // 11
     472           0 :         oHeader.addValue( CADHeader::DIMDSEP, buffer.ReadBITSHORT() );   // 12
     473           0 :         oHeader.addValue( CADHeader::DIMTMOVE, buffer.ReadBITSHORT() );  // 13
     474           0 :         oHeader.addValue( CADHeader::DIMJUST, buffer.ReadBITSHORT() );   // 14
     475             : 
     476           0 :         oHeader.addValue( CADHeader::DIMSD1, buffer.ReadBIT() );
     477           0 :         oHeader.addValue( CADHeader::DIMSD2, buffer.ReadBIT() );
     478             : 
     479           0 :         oHeader.addValue( CADHeader::DIMTOLJ, buffer.ReadBITSHORT() );
     480           0 :         oHeader.addValue( CADHeader::DIMTZIN, buffer.ReadBITSHORT() );
     481           0 :         oHeader.addValue( CADHeader::DIMALTZ, buffer.ReadBITSHORT() );
     482           0 :         oHeader.addValue( CADHeader::DIMALTTZ, buffer.ReadBITSHORT() );
     483             : 
     484           0 :         oHeader.addValue( CADHeader::DIMUPT, buffer.ReadBIT() );
     485             : 
     486           0 :         oHeader.addValue( CADHeader::DIMATFIT, buffer.ReadBITSHORT() );
     487             : 
     488           0 :         oHeader.addValue( CADHeader::DIMTXSTY, buffer.ReadHANDLE() );
     489           0 :         oHeader.addValue( CADHeader::DIMLDRBLK, buffer.ReadHANDLE() );
     490           0 :         oHeader.addValue( CADHeader::DIMBLK, buffer.ReadHANDLE() );
     491           0 :         oHeader.addValue( CADHeader::DIMBLK1, buffer.ReadHANDLE() );
     492           0 :         oHeader.addValue( CADHeader::DIMBLK2, buffer.ReadHANDLE() );
     493             : 
     494           0 :         oHeader.addValue( CADHeader::DIMLWD, buffer.ReadBITSHORT() );
     495           0 :         oHeader.addValue( CADHeader::DIMLWE, buffer.ReadBITSHORT() );
     496             :     } else
     497             :     {
     498           8 :         buffer.SkipTV();
     499           8 :         buffer.SkipTV();
     500             : 
     501          80 :         for( char i = 0; i < 9; ++i )
     502          72 :             buffer.SkipBITDOUBLE();
     503             : 
     504           8 :         buffer.Seek(6);
     505             : 
     506          32 :         for( char i = 0; i < 3; ++i )
     507          24 :             buffer.SkipBITSHORT();
     508             : 
     509          80 :         for( char i = 0; i < 9; ++i )
     510          72 :             buffer.SkipBITDOUBLE();
     511             : 
     512           8 :         buffer.Seek(1);
     513             : 
     514           8 :         buffer.SkipBITSHORT();
     515             : 
     516           8 :         buffer.Seek(4);
     517             : 
     518         120 :         for( char i = 0; i < 14; ++i )
     519         112 :             buffer.SkipBITSHORT();
     520             : 
     521           8 :         buffer.Seek(2);
     522             : 
     523          40 :         for( char i = 0; i < 4; ++i )
     524          32 :             buffer.SkipBITSHORT();
     525             : 
     526           8 :         buffer.Seek(1);
     527           8 :         buffer.SkipBITSHORT();
     528             : 
     529          48 :         for( char i = 0; i < 5; ++i )
     530          40 :             buffer.SkipHANDLE();
     531             : 
     532           8 :         buffer.SkipBITSHORT();
     533           8 :         buffer.SkipBITSHORT();
     534             :     }
     535             : 
     536          16 :     CADHandle stBlocksTable = buffer.ReadHANDLE();
     537           8 :     oTables.AddTable( CADTables::BlocksTable, stBlocksTable );
     538             : 
     539          16 :     CADHandle stLayersTable = buffer.ReadHANDLE();
     540           8 :     oTables.AddTable( CADTables::LayersTable, stLayersTable );
     541             : 
     542          16 :     CADHandle stStyleTable = buffer.ReadHANDLE();
     543           8 :     oTables.AddTable( CADTables::StyleTable, stStyleTable );
     544             : 
     545          16 :     CADHandle stLineTypesTable = buffer.ReadHANDLE();
     546           8 :     oTables.AddTable( CADTables::LineTypesTable, stLineTypesTable );
     547             : 
     548          16 :     CADHandle stViewTable = buffer.ReadHANDLE();
     549           8 :     oTables.AddTable( CADTables::ViewTable, stViewTable );
     550             : 
     551          16 :     CADHandle stUCSTable = buffer.ReadHANDLE();
     552           8 :     oTables.AddTable( CADTables::UCSTable, stUCSTable );
     553             : 
     554          16 :     CADHandle stViewportTable = buffer.ReadHANDLE();
     555           8 :     oTables.AddTable( CADTables::ViewportTable, stViewportTable );
     556             : 
     557          16 :     CADHandle stAPPIDTable = buffer.ReadHANDLE();
     558           8 :     oTables.AddTable( CADTables::APPIDTable, stAPPIDTable );
     559             : 
     560           8 :     if( eOptions == OpenOptions::READ_ALL )
     561             :     {
     562           0 :         oHeader.addValue( CADHeader::DIMSTYLE, buffer.ReadHANDLE() );
     563             :     }
     564             :     else
     565             :     {
     566           8 :         buffer.SkipHANDLE();
     567             :     }
     568             : 
     569          16 :     CADHandle stEntityTable = buffer.ReadHANDLE();
     570           8 :     oTables.AddTable( CADTables::EntityTable, stEntityTable );
     571             : 
     572          16 :     CADHandle stACADGroupDict = buffer.ReadHANDLE();
     573           8 :     oTables.AddTable( CADTables::ACADGroupDict, stACADGroupDict );
     574             : 
     575          16 :     CADHandle stACADMLineStyleDict = buffer.ReadHANDLE();
     576           8 :     oTables.AddTable( CADTables::ACADMLineStyleDict, stACADMLineStyleDict );
     577             : 
     578          16 :     CADHandle stNamedObjectsDict = buffer.ReadHANDLE();
     579           8 :     oTables.AddTable( CADTables::NamedObjectsDict, stNamedObjectsDict );
     580             : 
     581           8 :     if( eOptions == OpenOptions::READ_ALL )
     582             :     {
     583           0 :         oHeader.addValue( CADHeader::TSTACKALIGN, buffer.ReadBITSHORT() );
     584           0 :         oHeader.addValue( CADHeader::TSTACKSIZE,  buffer.ReadBITSHORT() );
     585             :     } else
     586             :     {
     587           8 :         buffer.SkipBITSHORT();
     588           8 :         buffer.SkipBITSHORT();
     589             :     }
     590             : 
     591           8 :     oHeader.addValue( CADHeader::HYPERLINKBASE, buffer.ReadTV() );
     592           8 :     oHeader.addValue( CADHeader::STYLESHEET, buffer.ReadTV() );
     593             : 
     594          16 :     CADHandle stLayoutsDict = buffer.ReadHANDLE();
     595           8 :     oTables.AddTable( CADTables::LayoutsDict, stLayoutsDict );
     596             : 
     597          16 :     CADHandle stPlotSettingsDict = buffer.ReadHANDLE();
     598           8 :     oTables.AddTable( CADTables::PlotSettingsDict, stPlotSettingsDict );
     599             : 
     600          16 :     CADHandle stPlotStylesDict = buffer.ReadHANDLE();
     601           8 :     oTables.AddTable( CADTables::PlotStylesDict, stPlotStylesDict );
     602             : 
     603           8 :     if( eOptions == OpenOptions::READ_ALL )
     604             :     {
     605           0 :         int Flags = buffer.ReadBITLONG();
     606           0 :         oHeader.addValue( CADHeader::CELWEIGHT, Flags & 0x001F );
     607           0 :         oHeader.addValue( CADHeader::ENDCAPS, ( Flags & 0x0060 ) != 0 );
     608           0 :         oHeader.addValue( CADHeader::JOINSTYLE, (Flags & 0x0180) != 0);
     609           0 :         oHeader.addValue( CADHeader::LWDISPLAY, ( Flags & 0x0200 ) == 0);
     610           0 :         oHeader.addValue( CADHeader::XEDIT, ( Flags & 0x0400 ) == 0);
     611           0 :         oHeader.addValue( CADHeader::EXTNAMES, ( Flags & 0x0800 ) != 0 );
     612           0 :         oHeader.addValue( CADHeader::PSTYLEMODE, ( Flags & 0x2000 ) != 0 );
     613           0 :         oHeader.addValue( CADHeader::OLESTARTUP, ( Flags & 0x4000 ) != 0);
     614             :     }
     615             :     else
     616             :     {
     617           8 :         buffer.SkipBITLONG();
     618             :     }
     619             : 
     620           8 :     oHeader.addValue( CADHeader::INSUNITS, buffer.ReadBITSHORT() );
     621           8 :     short nCEPSNTYPE = buffer.ReadBITSHORT();
     622           8 :     oHeader.addValue( CADHeader::CEPSNTYPE, nCEPSNTYPE );
     623             : 
     624           8 :     if( nCEPSNTYPE == 3 )
     625           0 :         oHeader.addValue( CADHeader::CEPSNID, buffer.ReadHANDLE() );
     626             : 
     627           8 :     oHeader.addValue( CADHeader::FINGERPRINTGUID, buffer.ReadTV() );
     628           8 :     oHeader.addValue( CADHeader::VERSIONGUID, buffer.ReadTV() );
     629             : 
     630          16 :     CADHandle stBlockRecordPaperSpace = buffer.ReadHANDLE();
     631           8 :     oTables.AddTable( CADTables::BlockRecordPaperSpace, stBlockRecordPaperSpace );
     632             :     // TODO: is this part of the header?
     633          16 :     CADHandle stBlockRecordModelSpace = buffer.ReadHANDLE();
     634           8 :     oTables.AddTable( CADTables::BlockRecordModelSpace, stBlockRecordModelSpace );
     635             : 
     636           8 :     if( eOptions == OpenOptions::READ_ALL )
     637             :     {
     638             :         // Is this part of the header?
     639             : 
     640           0 :         /*CADHandle LTYPE_BYLAYER = */buffer.ReadHANDLE();
     641           0 :         /*CADHandle LTYPE_BYBLOCK = */buffer.ReadHANDLE();
     642           0 :         /*CADHandle LTYPE_CONTINUOUS = */buffer.ReadHANDLE();
     643             : 
     644           0 :         oHeader.addValue( UNKNOWN11, buffer.ReadBITSHORT() );
     645           0 :         oHeader.addValue( UNKNOWN12, buffer.ReadBITSHORT() );
     646           0 :         oHeader.addValue( UNKNOWN13, buffer.ReadBITSHORT() );
     647           0 :         oHeader.addValue( UNKNOWN14, buffer.ReadBITSHORT() );
     648             :     } else
     649             :     {
     650           8 :         buffer.SkipHANDLE();
     651           8 :         buffer.SkipHANDLE();
     652           8 :         buffer.SkipHANDLE();
     653           8 :         buffer.SkipBITSHORT();
     654           8 :         buffer.SkipBITSHORT();
     655           8 :         buffer.SkipBITSHORT();
     656           8 :         buffer.SkipBITSHORT();
     657             :     }
     658             : 
     659           8 :     int returnCode = CADErrorCodes::SUCCESS;
     660           8 :     unsigned short dSectionCRC = validateEntityCRC( buffer,
     661             :         static_cast<unsigned int>(dHeaderVarsSectionLength + dSizeOfSectionSize), "HEADERVARS" );
     662             : #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     663             :     (void)dSectionCRC;
     664             : #else
     665           8 :     if(dSectionCRC == 0)
     666             :     {
     667           0 :         std::cerr << "File is corrupted (HEADERVARS section CRC doesn't match.)\n";
     668           0 :         return CADErrorCodes::HEADER_SECTION_READ_FAILED;
     669             :     }
     670             : #endif
     671           8 :     pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
     672             : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     673           8 :     if( memcmp( bufferPre, DWGConstants::HeaderVariablesEnd,
     674             :                          DWGConstants::SentinelLength ) )
     675             :     {
     676             :         std::cerr << "File is corrupted (HEADERVARS section ending sentinel "
     677           0 :                           "doesn't match.)\n";
     678           0 :         returnCode = CADErrorCodes::HEADER_SECTION_READ_FAILED;
     679             :     }
     680             : #endif
     681           8 :     return returnCode;
     682             : }
     683             : 
     684           8 : int DWGFileR2000::ReadClasses( enum OpenOptions eOptions )
     685             : {
     686           8 :     if( eOptions == OpenOptions::READ_ALL || eOptions == OpenOptions::READ_FAST )
     687             :     {
     688             :         char   bufferPre[255];
     689           8 :         unsigned dSectionSize = 0;
     690           8 :         constexpr size_t dSizeOfSectionSize = sizeof(dSectionSize);
     691             : 
     692           8 :         pFileIO->Seek( sectionLocatorRecords[1].dSeeker, CADFileIO::SeekOrigin::BEG );
     693             : 
     694           8 :         pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
     695             : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     696           8 :         if( memcmp( bufferPre, DWGConstants::DSClassesStart,
     697             :                                DWGConstants::SentinelLength ) )
     698             :         {
     699             :             std::cerr << "File is corrupted (wrong pointer to CLASSES section,"
     700           0 :                     "or CLASSES starting sentinel corrupted.)\n";
     701             : 
     702           0 :             return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
     703             :         }
     704             : #endif
     705             : 
     706           8 :         pFileIO->Read( &dSectionSize, dSizeOfSectionSize );
     707           8 :         const auto dSectionSizeOriginal = dSectionSize;
     708           8 :         FromLSB(dSectionSize);
     709           8 :         DebugMsg("Classes section length: %d\n",
     710             :                   static_cast<int>(dSectionSize) );
     711           8 :         if(dSectionSize > 65535) {
     712           0 :             DebugMsg("File is corrupted (CLASSES section is too large: %d\n",
     713             :                      static_cast<int>(dSectionSize));
     714             : 
     715           0 :             return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
     716             :         }
     717             : 
     718           8 :         CADBuffer buffer(dSectionSize + dSizeOfSectionSize + 10);
     719           8 :         buffer.WriteRAW(&dSectionSizeOriginal, dSizeOfSectionSize);
     720           8 :         size_t readSize = pFileIO->Read( buffer.GetRawBuffer(), dSectionSize + 2 );
     721           8 :         if(readSize != dSectionSize + 2)
     722             :         {
     723           0 :             DebugMsg( "Failed to read %d byte of file. Read only %d",
     724           0 :                       static_cast<int>(dSectionSize + 2),
     725             :                       static_cast<int>(readSize) );
     726           0 :             return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
     727             :         }
     728             : 
     729           8 :         const size_t dSectionBitSize = (dSectionSize + dSizeOfSectionSize) * 8;
     730         129 :         while( buffer.PositionBit() < dSectionBitSize - 8)
     731             :         {
     732         121 :             CADClass stClass;
     733         121 :             stClass.dClassNum        = buffer.ReadBITSHORT();
     734         121 :             stClass.dProxyCapFlag    = buffer.ReadBITSHORT();
     735         121 :             stClass.sApplicationName = buffer.ReadTV();
     736         121 :             stClass.sCppClassName    = buffer.ReadTV();
     737         121 :             stClass.sDXFRecordName   = buffer.ReadTV();
     738         121 :             stClass.bWasZombie       = buffer.ReadBIT();
     739         121 :             stClass.bIsEntity        = buffer.ReadBITSHORT() == 0x1F2;
     740             : 
     741         121 :             oClasses.addClass( std::move(stClass) );
     742             :         }
     743             : 
     744           8 :         buffer.Seek(dSectionBitSize, CADBuffer::BEG);
     745           8 :         unsigned short dSectionCRC = validateEntityCRC( buffer,
     746             :                     static_cast<unsigned int>(dSectionSize + dSizeOfSectionSize),
     747             :                                                         "CLASSES" );
     748             : #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     749             :         (void)dSectionCRC;
     750             : #else
     751           8 :         if(dSectionCRC == 0)
     752             :         {
     753           0 :             std::cerr << "File is corrupted (CLASSES section CRC doesn't match.)\n";
     754           0 :             return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
     755             :         }
     756             : #endif
     757             : 
     758           8 :         pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
     759             : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     760           8 :         if( memcmp( bufferPre, DWGConstants::DSClassesEnd,
     761             :                                DWGConstants::SentinelLength ) )
     762             :         {
     763             :             std::cerr << "File is corrupted (CLASSES section ending sentinel "
     764           0 :                     "doesn't match.)\n";
     765           0 :             return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
     766             :         }
     767             : #endif
     768             :     }
     769           8 :     return CADErrorCodes::SUCCESS;
     770             : }
     771             : 
     772           8 : int DWGFileR2000::CreateFileMap()
     773             : {
     774           8 :     size_t nSection = 0;
     775             : 
     776             :     typedef pair<long, long> ObjHandleOffset;
     777           8 :     ObjHandleOffset          previousObjHandleOffset;
     778           8 :     ObjHandleOffset          tmpOffset;
     779             : 
     780           8 :     mapObjects.clear();
     781             : 
     782             :     // Seek to the beginning of the objects map
     783           8 :     pFileIO->Seek( sectionLocatorRecords[2].dSeeker, CADFileIO::SeekOrigin::BEG );
     784             : 
     785             :     while( true )
     786             :     {
     787          16 :         unsigned short dSectionSize = 0;
     788          16 :         constexpr size_t dSizeOfSectionSize = sizeof(dSectionSize);
     789             : 
     790             :         // Read section size
     791             : 
     792          16 :         pFileIO->Read( &dSectionSize, dSizeOfSectionSize );
     793          16 :         const unsigned short dSectionSizeOriginal = dSectionSize;
     794             : #if !defined(CAD_MSB)
     795          16 :         SwapEndianness( dSectionSize, sizeof( dSectionSize ) );
     796             : #endif
     797             : 
     798          16 :         DebugMsg( "Object map section #%d size: %d\n",
     799             :                   static_cast<int>(++nSection), dSectionSize );
     800             : 
     801          16 :         if( dSectionSize <= dSizeOfSectionSize )
     802           8 :             break; // Last section is empty.
     803             : 
     804           8 :         CADBuffer buffer(dSectionSize + dSizeOfSectionSize + 10);
     805           8 :         buffer.WriteRAW(&dSectionSizeOriginal, dSizeOfSectionSize);
     806           8 :         size_t nRecordsInSection   = 0;
     807             : 
     808             :         // Read section datsa
     809           8 :         size_t readSize = pFileIO->Read( buffer.GetRawBuffer(), dSectionSize );
     810           8 :         if(readSize != dSectionSize)
     811             :         {
     812           0 :             DebugMsg( "Failed to read %d byte of file. Read only %d",
     813             :                       static_cast<int>(dSectionSize),
     814             :                       static_cast<int>(readSize) );
     815           0 :             return CADErrorCodes::OBJECTS_SECTION_READ_FAILED;
     816             :         }
     817           8 :         unsigned int dSectionBitSize = dSectionSize * 8;
     818             : 
     819        1801 :         while( buffer.PositionBit() < dSectionBitSize )
     820             :         {
     821        1793 :             tmpOffset.first  = buffer.ReadUMCHAR(); // 8 + 8*8
     822        1793 :             tmpOffset.second = buffer.ReadMCHAR(); // 8 + 8*8
     823             : 
     824        1793 :             if( 0 == nRecordsInSection )
     825             :             {
     826           8 :                 previousObjHandleOffset = tmpOffset;
     827             :             }
     828             :             else
     829             :             {
     830        5355 :                 if( (tmpOffset.first >= 0 &&
     831        1785 :                      std::numeric_limits<long>::max() - tmpOffset.first > previousObjHandleOffset.first) ||
     832           0 :                     (tmpOffset.first < 0 &&
     833           0 :                      std::numeric_limits<long>::min() - tmpOffset.first <= previousObjHandleOffset.first) )
     834             :                 {
     835        1785 :                     previousObjHandleOffset.first += tmpOffset.first;
     836             :                 }
     837        4632 :                 if( (tmpOffset.second >= 0 &&
     838        2508 :                      std::numeric_limits<long>::max() - tmpOffset.second > previousObjHandleOffset.second) ||
     839         723 :                     (tmpOffset.second < 0 &&
     840         723 :                      std::numeric_limits<long>::min() - tmpOffset.second <= previousObjHandleOffset.second) )
     841             :                 {
     842        1785 :                     previousObjHandleOffset.second += tmpOffset.second;
     843             :                 }
     844             :             }
     845             : #ifdef _DEBUG
     846             :             assert( mapObjects.find( previousObjHandleOffset.first ) ==
     847             :                                                                 mapObjects.end() );
     848             : #endif //_DEBUG
     849        1793 :             mapObjects.insert( previousObjHandleOffset );
     850        1793 :             ++nRecordsInSection;
     851             :         }
     852             : 
     853           8 :         unsigned short dSectionCRC = validateEntityCRC( buffer,
     854             :                     static_cast<unsigned int>(dSectionSize), "OBJECTMAP", true );
     855             : #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     856             :         (void)dSectionCRC;
     857             : #else
     858           8 :         if(dSectionCRC == 0)
     859             :         {
     860           0 :             std::cerr << "File is corrupted (OBJECTMAP section CRC doesn't match.)\n";
     861           0 :             return CADErrorCodes::OBJECTS_SECTION_READ_FAILED;
     862             :         }
     863             : #endif
     864           8 :     }
     865             : 
     866           8 :     return CADErrorCodes::SUCCESS;
     867             : }
     868             : 
     869         213 : CADObject * DWGFileR2000::GetObject( long dHandle, bool bHandlesOnly )
     870             : {
     871         426 :     CADBuffer buffer(8);
     872             : 
     873         213 :     pFileIO->Seek( mapObjects[dHandle], CADFileIO::SeekOrigin::BEG );
     874         213 :     pFileIO->Read( buffer.GetRawBuffer(), 8 );
     875         213 :     unsigned int dObjectSize = buffer.ReadMSHORT();
     876             : 
     877             :     // FIXME: Limit object size to 64kB
     878         213 :     if( dObjectSize > 65536 )
     879           0 :         return nullptr;
     880             : 
     881             :     // And read whole data chunk into memory for future parsing.
     882             :     // + nBitOffsetFromStart/8 + 2 is because dObjectSize doesn't cover CRC and itself.
     883         213 :     dObjectSize += static_cast<unsigned int>(buffer.PositionBit() / 8 + 2);
     884             : 
     885         426 :     CADBuffer objectBuffer(dObjectSize + 64);
     886             : 
     887         213 :     pFileIO->Seek( mapObjects[dHandle], CADFileIO::SeekOrigin::BEG );
     888         213 :     size_t readSize = pFileIO->Read( objectBuffer.GetRawBuffer(),
     889         213 :                                      static_cast<size_t>(dObjectSize) );
     890         213 :     if(readSize != static_cast<size_t>(dObjectSize))
     891             :     {
     892           0 :         DebugMsg( "Failed to read %d byte of file. Read only %d",
     893             :                   static_cast<int>(dObjectSize),
     894             :                   static_cast<int>(readSize) );
     895           0 :         return nullptr;
     896             :     }
     897             : 
     898         213 :     /* Unused dObjectSize = */ objectBuffer.ReadMSHORT();
     899         213 :     short dObjectType = objectBuffer.ReadBITSHORT();
     900         213 :     if( dObjectType >= 500 )
     901             :     {
     902          16 :         CADClass cadClass = oClasses.getClassByNum( dObjectType );
     903             :         // FIXME: replace strcmp() with C++ analog
     904           8 :         if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbRasterImage" ) )
     905             :         {
     906           0 :             dObjectType = CADObject::IMAGE;
     907             :         }
     908           8 :         else if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbRasterImageDef" ) )
     909             :         {
     910           0 :             dObjectType = CADObject::IMAGEDEF;
     911             :         }
     912           8 :         else if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbRasterImageDefReactor" ) )
     913             :         {
     914           0 :             dObjectType = CADObject::IMAGEDEFREACTOR;
     915             :         }
     916           8 :         else if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbWipeout" ) )
     917             :         {
     918           0 :             dObjectType = CADObject::WIPEOUT;
     919             :         }
     920             :     }
     921             : 
     922             :     // Entities handling
     923         213 :     if( isCommonEntityType( dObjectType ) )
     924             :     {
     925          70 :         struct CADCommonED stCommonEntityData; // Common for all entities
     926             : 
     927          35 :         stCommonEntityData.nObjectSizeInBits = objectBuffer.ReadRAWLONG();
     928          35 :         stCommonEntityData.hObjectHandle     = objectBuffer.ReadHANDLE();
     929             : 
     930             :         short  dEEDSize;
     931          70 :         CADEed dwgEed;
     932          50 :         while( ( dEEDSize = objectBuffer.ReadBITSHORT() ) != 0 )
     933             :         {
     934          15 :             dwgEed.dLength      = dEEDSize;
     935          15 :             dwgEed.hApplication = objectBuffer.ReadHANDLE();
     936             : 
     937          15 :             if(dEEDSize < 0)
     938             :             {
     939           0 :                 return nullptr;
     940             :             }
     941             : 
     942        1119 :             for( short i = 0; i < dEEDSize; ++i )
     943             :             {
     944        1104 :                 dwgEed.acData.push_back( objectBuffer.ReadCHAR() );
     945             :             }
     946             : 
     947          15 :             stCommonEntityData.aEED.push_back( dwgEed );
     948             :         }
     949             : 
     950          35 :         stCommonEntityData.bGraphicsPresented = objectBuffer.ReadBIT();
     951          35 :         if( stCommonEntityData.bGraphicsPresented )
     952             :         {
     953           0 :             const auto rawLong = objectBuffer.ReadRAWLONG();
     954           0 :             if( rawLong < 0 )
     955           0 :                 return nullptr;
     956           0 :             size_t nGraphicsDataSize = static_cast<size_t>(rawLong);
     957           0 :             if( nGraphicsDataSize > std::numeric_limits<size_t>::max() / 8 )
     958           0 :                 return nullptr;
     959             :             // Skip read graphics data
     960           0 :             buffer.Seek(nGraphicsDataSize * 8);
     961             :         }
     962          35 :         stCommonEntityData.bbEntMode        = objectBuffer.Read2B();
     963          35 :         stCommonEntityData.nNumReactors     = objectBuffer.ReadBITLONG();
     964          35 :         if(stCommonEntityData.nNumReactors < 0 ||
     965          35 :            stCommonEntityData.nNumReactors > 5000)
     966             :         {
     967           0 :             return nullptr;
     968             :         }
     969          35 :         stCommonEntityData.bNoLinks         = objectBuffer.ReadBIT();
     970          35 :         stCommonEntityData.nCMColor         = objectBuffer.ReadBITSHORT();
     971          35 :         stCommonEntityData.dfLTypeScale     = objectBuffer.ReadBITDOUBLE();
     972          35 :         stCommonEntityData.bbLTypeFlags     = objectBuffer.Read2B();
     973          35 :         stCommonEntityData.bbPlotStyleFlags = objectBuffer.Read2B();
     974          35 :         stCommonEntityData.nInvisibility    = objectBuffer.ReadBITSHORT();
     975          35 :         stCommonEntityData.nLineWeight      = objectBuffer.ReadCHAR();
     976             : 
     977             :         // Skip entitity-specific data, we don't need it if bHandlesOnly == true
     978          35 :         if( bHandlesOnly == true )
     979             :         {
     980          18 :             return getEntity( dObjectType, dObjectSize, stCommonEntityData, objectBuffer);
     981             :         }
     982             : 
     983          17 :         switch( dObjectType )
     984             :         {
     985           0 :             case CADObject::BLOCK:
     986           0 :                 return getBlock( dObjectSize, stCommonEntityData, objectBuffer);
     987             : 
     988           1 :             case CADObject::ELLIPSE:
     989           1 :                 return getEllipse( dObjectSize, stCommonEntityData, objectBuffer);
     990             : 
     991           0 :             case CADObject::MLINE:
     992           0 :                 return getMLine( dObjectSize, stCommonEntityData, objectBuffer);
     993             : 
     994           0 :             case CADObject::SOLID:
     995           0 :                 return getSolid( dObjectSize, stCommonEntityData, objectBuffer);
     996             : 
     997           1 :             case CADObject::POINT:
     998           1 :                 return getPoint( dObjectSize, stCommonEntityData, objectBuffer);
     999             : 
    1000           0 :             case CADObject::POLYLINE3D:
    1001           0 :                 return getPolyLine3D( dObjectSize, stCommonEntityData, objectBuffer);
    1002             : 
    1003           0 :             case CADObject::RAY:
    1004           0 :                 return getRay( dObjectSize, stCommonEntityData, objectBuffer);
    1005             : 
    1006           0 :             case CADObject::XLINE:
    1007           0 :                 return getXLine( dObjectSize, stCommonEntityData, objectBuffer);
    1008             : 
    1009           1 :             case CADObject::LINE:
    1010           1 :                 return getLine( dObjectSize, stCommonEntityData, objectBuffer);
    1011             : 
    1012           4 :             case CADObject::TEXT:
    1013           4 :                 return getText( dObjectSize, stCommonEntityData, objectBuffer);
    1014             : 
    1015           0 :             case CADObject::VERTEX3D:
    1016           0 :                 return getVertex3D( dObjectSize, stCommonEntityData, objectBuffer);
    1017             : 
    1018           3 :             case CADObject::CIRCLE:
    1019           3 :                 return getCircle( dObjectSize, stCommonEntityData, objectBuffer);
    1020             : 
    1021           0 :             case CADObject::ENDBLK:
    1022           0 :                 return getEndBlock( dObjectSize, stCommonEntityData, objectBuffer);
    1023             : 
    1024           0 :             case CADObject::POLYLINE2D:
    1025           0 :                 return getPolyline2D( dObjectSize, stCommonEntityData, objectBuffer);
    1026             : 
    1027           0 :             case CADObject::ATTRIB:
    1028           0 :                 return getAttributes( dObjectSize, stCommonEntityData, objectBuffer);
    1029             : 
    1030           5 :             case CADObject::ATTDEF:
    1031           5 :                 return getAttributesDefn( dObjectSize, stCommonEntityData, objectBuffer);
    1032             : 
    1033           0 :             case CADObject::LWPOLYLINE:
    1034           0 :                 return getLWPolyLine( dObjectSize, stCommonEntityData, objectBuffer);
    1035             : 
    1036           0 :             case CADObject::ARC:
    1037           0 :                 return getArc( dObjectSize, stCommonEntityData, objectBuffer);
    1038             : 
    1039           0 :             case CADObject::SPLINE:
    1040           0 :                 return getSpline( dObjectSize, stCommonEntityData, objectBuffer);
    1041             : 
    1042           0 :             case CADObject::POLYLINE_PFACE:
    1043           0 :                 return getPolylinePFace( dObjectSize, stCommonEntityData, objectBuffer);
    1044             : 
    1045           0 :             case CADObject::IMAGE:
    1046           0 :                 return getImage( dObjectSize, stCommonEntityData, objectBuffer);
    1047             : 
    1048           0 :             case CADObject::FACE3D:
    1049           0 :                 return get3DFace( dObjectSize, stCommonEntityData, objectBuffer);
    1050             : 
    1051           0 :             case CADObject::VERTEX_MESH:
    1052           0 :                 return getVertexMesh( dObjectSize, stCommonEntityData, objectBuffer);
    1053             : 
    1054           0 :             case CADObject::VERTEX_PFACE:
    1055           0 :                 return getVertexPFace( dObjectSize, stCommonEntityData,
    1056           0 :                                        objectBuffer);
    1057             : 
    1058           2 :             case CADObject::MTEXT:
    1059           2 :                 return getMText( dObjectSize, stCommonEntityData,
    1060           2 :                                  objectBuffer);
    1061             : 
    1062           0 :             case CADObject::DIMENSION_RADIUS:
    1063             :             case CADObject::DIMENSION_DIAMETER:
    1064             :             case CADObject::DIMENSION_ALIGNED:
    1065             :             case CADObject::DIMENSION_ANG_3PT:
    1066             :             case CADObject::DIMENSION_ANG_2LN:
    1067             :             case CADObject::DIMENSION_ORDINATE:
    1068             :             case CADObject::DIMENSION_LINEAR:
    1069           0 :                 return getDimension( dObjectType, dObjectSize, stCommonEntityData,
    1070           0 :                                      objectBuffer);
    1071             : 
    1072           0 :             case CADObject::INSERT:
    1073           0 :                 return getInsert( dObjectType, dObjectSize, stCommonEntityData,
    1074           0 :                                   objectBuffer);
    1075             : 
    1076           0 :             default:
    1077           0 :                 return getEntity( dObjectType, dObjectSize, stCommonEntityData,
    1078           0 :                                   objectBuffer);
    1079             :         }
    1080             :     }
    1081             :     else
    1082             :     {
    1083         178 :         switch( dObjectType )
    1084             :         {
    1085         120 :             case CADObject::DICTIONARY:
    1086         120 :                 return getDictionary( dObjectSize, objectBuffer);
    1087             : 
    1088          10 :             case CADObject::LAYER:
    1089          10 :                 return getLayerObject( dObjectSize, objectBuffer);
    1090             : 
    1091           8 :             case CADObject::LAYER_CONTROL_OBJ:
    1092           8 :                 return getLayerControl( dObjectSize, objectBuffer);
    1093             : 
    1094           0 :             case CADObject::BLOCK_CONTROL_OBJ:
    1095           0 :                 return getBlockControl( dObjectSize, objectBuffer);
    1096             : 
    1097           8 :             case CADObject::BLOCK_HEADER:
    1098           8 :                 return getBlockHeader( dObjectSize, objectBuffer);
    1099             : 
    1100           0 :             case CADObject::LTYPE_CONTROL_OBJ:
    1101           0 :                 return getLineTypeControl( dObjectSize, objectBuffer);
    1102             : 
    1103           0 :             case CADObject::LTYPE1:
    1104           0 :                 return getLineType1( dObjectSize, objectBuffer);
    1105             : 
    1106           0 :             case CADObject::IMAGEDEF:
    1107           0 :                 return getImageDef( dObjectSize, objectBuffer);
    1108             : 
    1109           0 :             case CADObject::IMAGEDEFREACTOR:
    1110           0 :                 return getImageDefReactor( dObjectSize, objectBuffer);
    1111             : 
    1112          24 :             case CADObject::XRECORD:
    1113          24 :                 return getXRecord( dObjectSize, objectBuffer);
    1114             :         }
    1115             :     }
    1116             : 
    1117           8 :     return nullptr;
    1118             : }
    1119             : 
    1120          17 : CADGeometry * DWGFileR2000::GetGeometry( size_t iLayerIndex, long dHandle, long dBlockRefHandle )
    1121             : {
    1122          17 :     CADGeometry * poGeometry = nullptr;
    1123          34 :     unique_ptr<CADObject> pCADEntityObject( GetObject( dHandle ) );
    1124             :     CADEntityObject* readObject =
    1125          17 :                 dynamic_cast<CADEntityObject *>( pCADEntityObject.get() );
    1126             : 
    1127          17 :     if( !readObject )
    1128             :     {
    1129           0 :         return nullptr;
    1130             :     }
    1131             : 
    1132          17 :     switch( readObject->getType() )
    1133             :     {
    1134           0 :         case CADObject::ARC:
    1135             :         {
    1136           0 :             CADArc * arc = new CADArc();
    1137           0 :             CADArcObject * cadArc = static_cast<CADArcObject *>(
    1138             :                     readObject);
    1139             : 
    1140           0 :             arc->setPosition( cadArc->vertPosition );
    1141           0 :             arc->setExtrusion( cadArc->vectExtrusion );
    1142           0 :             arc->setRadius( cadArc->dfRadius );
    1143           0 :             arc->setThickness( cadArc->dfThickness );
    1144           0 :             arc->setStartingAngle( cadArc->dfStartAngle );
    1145           0 :             arc->setEndingAngle( cadArc->dfEndAngle );
    1146             : 
    1147           0 :             poGeometry = arc;
    1148           0 :             break;
    1149             :         }
    1150             : 
    1151           1 :         case CADObject::POINT:
    1152             :         {
    1153           1 :             CADPoint3D * point = new CADPoint3D();
    1154           1 :             CADPointObject * cadPoint = static_cast<CADPointObject *>(
    1155             :                     readObject);
    1156             : 
    1157           1 :             point->setPosition( cadPoint->vertPosition );
    1158           1 :             point->setExtrusion( cadPoint->vectExtrusion );
    1159           1 :             point->setXAxisAng( cadPoint->dfXAxisAng );
    1160           1 :             point->setThickness( cadPoint->dfThickness );
    1161             : 
    1162           1 :             poGeometry = point;
    1163           1 :             break;
    1164             :         }
    1165             : 
    1166           0 :         case CADObject::POLYLINE3D:
    1167             :         {
    1168           0 :             CADPolyline3D * polyline = new CADPolyline3D();
    1169           0 :             CADPolyline3DObject * cadPolyline3D = static_cast<CADPolyline3DObject *>(
    1170             :                     readObject);
    1171             : 
    1172             :             // TODO: code can be much simplified if CADHandle will be used.
    1173             :             // to do so, == and ++ operators should be implemented.
    1174           0 :             unique_ptr<CADVertex3DObject> vertex;
    1175           0 :             long currentVertexH = cadPolyline3D->hVertices[0].getAsLong();
    1176           0 :             while( currentVertexH != 0 )
    1177             :             {
    1178           0 :                 CADObject *poCADVertexObject = GetObject( currentVertexH );
    1179           0 :                 vertex.reset( dynamic_cast<CADVertex3DObject *>( poCADVertexObject ) );
    1180             : 
    1181           0 :                 if( !vertex )
    1182             :                 {
    1183           0 :                     delete poCADVertexObject;
    1184           0 :                     break;
    1185             :                 }
    1186             : 
    1187           0 :                 currentVertexH = vertex->stCed.hObjectHandle.getAsLong();
    1188           0 :                 polyline->addVertex( vertex->vertPosition );
    1189           0 :                 if( vertex->stCed.bNoLinks == true )
    1190             :                 {
    1191           0 :                     ++currentVertexH;
    1192             :                 }
    1193             :                 else
    1194             :                 {
    1195           0 :                     currentVertexH = vertex->stChed.hNextEntity.getAsLong(
    1196           0 :                                 vertex->stCed.hObjectHandle );
    1197             :                 }
    1198             : 
    1199             :                 // Last vertex is reached. Read it and break reading.
    1200           0 :                 if( currentVertexH == cadPolyline3D->hVertices[1].getAsLong() )
    1201             :                 {
    1202           0 :                     CADObject *poCADVertex3DObject = GetObject( currentVertexH );
    1203           0 :                     vertex.reset( dynamic_cast<CADVertex3DObject *>(
    1204           0 :                                           poCADVertex3DObject) );
    1205           0 :                     if( vertex)
    1206             :                     {
    1207           0 :                         polyline->addVertex( vertex->vertPosition );
    1208             :                     }
    1209             :                     else
    1210             :                     {
    1211           0 :                         delete poCADVertex3DObject;
    1212             :                     }
    1213           0 :                     break;
    1214             :                 }
    1215             :             }
    1216             : 
    1217           0 :             poGeometry = polyline;
    1218           0 :             break;
    1219             :         }
    1220             : 
    1221           0 :         case CADObject::LWPOLYLINE:
    1222             :         {
    1223           0 :             CADLWPolyline * lwPolyline = new CADLWPolyline();
    1224           0 :             CADLWPolylineObject * cadlwPolyline = static_cast<CADLWPolylineObject *>(
    1225             :                     readObject);
    1226             : 
    1227           0 :             lwPolyline->setBulges( cadlwPolyline->adfBulges );
    1228           0 :             lwPolyline->setClosed( cadlwPolyline->bClosed );
    1229           0 :             lwPolyline->setConstWidth( cadlwPolyline->dfConstWidth );
    1230           0 :             lwPolyline->setElevation( cadlwPolyline->dfElevation );
    1231           0 :             for( const CADVector& vertex : cadlwPolyline->avertVertices )
    1232           0 :                 lwPolyline->addVertex( vertex );
    1233           0 :             lwPolyline->setVectExtrusion( cadlwPolyline->vectExtrusion );
    1234           0 :             lwPolyline->setWidths( cadlwPolyline->astWidths );
    1235             : 
    1236           0 :             poGeometry = lwPolyline;
    1237           0 :             break;
    1238             :         }
    1239             : 
    1240           3 :         case CADObject::CIRCLE:
    1241             :         {
    1242           3 :             CADCircle * circle = new CADCircle();
    1243           3 :             CADCircleObject * cadCircle = static_cast<CADCircleObject *>(
    1244             :                     readObject);
    1245             : 
    1246           3 :             circle->setPosition( cadCircle->vertPosition );
    1247           3 :             circle->setExtrusion( cadCircle->vectExtrusion );
    1248           3 :             circle->setRadius( cadCircle->dfRadius );
    1249           3 :             circle->setThickness( cadCircle->dfThickness );
    1250             : 
    1251           3 :             poGeometry = circle;
    1252           3 :             break;
    1253             :         }
    1254             : 
    1255           0 :         case CADObject::ATTRIB:
    1256             :         {
    1257           0 :             CADAttrib * attrib = new CADAttrib();
    1258           0 :             CADAttribObject * cadAttrib = static_cast<CADAttribObject *>(
    1259             :                     readObject );
    1260             : 
    1261           0 :             attrib->setPosition( cadAttrib->vertInsetionPoint );
    1262           0 :             attrib->setExtrusion( cadAttrib->vectExtrusion );
    1263           0 :             attrib->setRotationAngle( cadAttrib->dfRotationAng );
    1264           0 :             attrib->setAlignmentPoint( cadAttrib->vertAlignmentPoint );
    1265           0 :             attrib->setElevation( cadAttrib->dfElevation );
    1266           0 :             attrib->setHeight( cadAttrib->dfHeight );
    1267           0 :             attrib->setObliqueAngle( cadAttrib->dfObliqueAng );
    1268           0 :             attrib->setPositionLocked( cadAttrib->bLockPosition );
    1269           0 :             attrib->setTag( cadAttrib->sTag );
    1270           0 :             attrib->setTextValue( cadAttrib->sTextValue );
    1271           0 :             attrib->setThickness( cadAttrib->dfThickness );
    1272             : 
    1273           0 :             poGeometry = attrib;
    1274           0 :             break;
    1275             :         }
    1276             : 
    1277           5 :         case CADObject::ATTDEF:
    1278             :         {
    1279           5 :             CADAttdef * attdef = new CADAttdef();
    1280           5 :             CADAttdefObject * cadAttrib = static_cast<CADAttdefObject*>(
    1281             :                     readObject );
    1282             : 
    1283           5 :             attdef->setPosition( cadAttrib->vertInsetionPoint );
    1284           5 :             attdef->setExtrusion( cadAttrib->vectExtrusion );
    1285           5 :             attdef->setRotationAngle( cadAttrib->dfRotationAng );
    1286           5 :             attdef->setAlignmentPoint( cadAttrib->vertAlignmentPoint );
    1287           5 :             attdef->setElevation( cadAttrib->dfElevation );
    1288           5 :             attdef->setHeight( cadAttrib->dfHeight );
    1289           5 :             attdef->setObliqueAngle( cadAttrib->dfObliqueAng );
    1290           5 :             attdef->setPositionLocked( cadAttrib->bLockPosition );
    1291           5 :             attdef->setTag( cadAttrib->sTag );
    1292           5 :             attdef->setTextValue( cadAttrib->sTextValue );
    1293           5 :             attdef->setThickness( cadAttrib->dfThickness );
    1294           5 :             attdef->setPrompt( cadAttrib->sPrompt );
    1295             : 
    1296           5 :             poGeometry = attdef;
    1297           5 :             break;
    1298             :         }
    1299             : 
    1300           1 :         case CADObject::ELLIPSE:
    1301             :         {
    1302           1 :             CADEllipse * ellipse = new CADEllipse();
    1303           1 :             CADEllipseObject * cadEllipse = static_cast<CADEllipseObject *>(
    1304             :                     readObject);
    1305             : 
    1306           1 :             ellipse->setPosition( cadEllipse->vertPosition );
    1307           1 :             ellipse->setSMAxis( cadEllipse->vectSMAxis );
    1308           1 :             ellipse->setAxisRatio( cadEllipse->dfAxisRatio );
    1309           1 :             ellipse->setEndingAngle( cadEllipse->dfEndAngle );
    1310           1 :             ellipse->setStartingAngle( cadEllipse->dfBegAngle );
    1311             : 
    1312           1 :             poGeometry = ellipse;
    1313           1 :             break;
    1314             :         }
    1315             : 
    1316           1 :         case CADObject::LINE:
    1317             :         {
    1318           1 :             CADLineObject * cadLine = static_cast<CADLineObject *>(
    1319             :                     readObject);
    1320             : 
    1321           2 :             CADPoint3D ptBeg( cadLine->vertStart, cadLine->dfThickness );
    1322           2 :             CADPoint3D ptEnd( cadLine->vertEnd, cadLine->dfThickness );
    1323             : 
    1324           1 :             CADLine * line = new CADLine( ptBeg, ptEnd );
    1325             : 
    1326           1 :             poGeometry = line;
    1327           1 :             break;
    1328             :         }
    1329             : 
    1330           0 :         case CADObject::RAY:
    1331             :         {
    1332           0 :             CADRay * ray = new CADRay();
    1333           0 :             CADRayObject * cadRay = static_cast<CADRayObject *>(
    1334             :                     readObject);
    1335             : 
    1336           0 :             ray->setVectVector( cadRay->vectVector );
    1337           0 :             ray->setPosition( cadRay->vertPosition );
    1338             : 
    1339           0 :             poGeometry = ray;
    1340           0 :             break;
    1341             :         }
    1342             : 
    1343           0 :         case CADObject::SPLINE:
    1344             :         {
    1345           0 :             CADSpline * spline = new CADSpline();
    1346           0 :             CADSplineObject * cadSpline = static_cast<CADSplineObject *>(
    1347             :                     readObject);
    1348             : 
    1349           0 :             spline->setScenario( cadSpline->dScenario );
    1350           0 :             spline->setDegree( cadSpline->dDegree );
    1351           0 :             if( spline->getScenario() == 2 )
    1352             :             {
    1353           0 :                 spline->setFitTolerance( cadSpline->dfFitTol );
    1354             :             }
    1355           0 :             else if( spline->getScenario() == 1 )
    1356             :             {
    1357           0 :                 spline->setRational( cadSpline->bRational );
    1358           0 :                 spline->setClosed( cadSpline->bClosed );
    1359           0 :                 spline->setWeight( cadSpline->bWeight );
    1360             :             }
    1361           0 :             for( double weight : cadSpline->adfCtrlPointsWeight )
    1362           0 :                 spline->addControlPointsWeight( weight );
    1363             : 
    1364           0 :             for( const CADVector& pt : cadSpline->averFitPoints )
    1365           0 :                 spline->addFitPoint( pt );
    1366             : 
    1367           0 :             for( const CADVector& pt : cadSpline->avertCtrlPoints )
    1368           0 :                 spline->addControlPoint( pt );
    1369             : 
    1370           0 :             poGeometry = spline;
    1371           0 :             break;
    1372             :         }
    1373             : 
    1374           4 :         case CADObject::TEXT:
    1375             :         {
    1376           4 :             CADText * text = new CADText();
    1377           4 :             CADTextObject * cadText = static_cast<CADTextObject *>(
    1378             :                     readObject);
    1379             : 
    1380           4 :             text->setPosition( cadText->vertInsetionPoint );
    1381           4 :             text->setTextValue( cadText->sTextValue );
    1382           4 :             text->setRotationAngle( cadText->dfRotationAng );
    1383           4 :             text->setObliqueAngle( cadText->dfObliqueAng );
    1384           4 :             text->setThickness( cadText->dfThickness );
    1385           4 :             text->setHeight( cadText->dfElevation );
    1386             : 
    1387           4 :             poGeometry = text;
    1388           4 :             break;
    1389             :         }
    1390             : 
    1391           0 :         case CADObject::SOLID:
    1392             :         {
    1393           0 :             CADSolid * solid = new CADSolid();
    1394           0 :             CADSolidObject * cadSolid = static_cast<CADSolidObject *>(
    1395             :                     readObject);
    1396             : 
    1397           0 :             solid->setElevation( cadSolid->dfElevation );
    1398           0 :             solid->setThickness( cadSolid->dfThickness );
    1399           0 :             for( const CADVector& corner : cadSolid->avertCorners )
    1400           0 :                 solid->addCorner( corner );
    1401           0 :             solid->setExtrusion( cadSolid->vectExtrusion );
    1402             : 
    1403           0 :             poGeometry = solid;
    1404           0 :             break;
    1405             :         }
    1406             : 
    1407           0 :         case CADObject::IMAGE:
    1408             :         {
    1409           0 :             CADImageObject * cadImage = static_cast<CADImageObject *>(
    1410             :                     readObject);
    1411             : 
    1412           0 :             CADObject *pCADImageDefObject = GetObject( cadImage->hImageDef.getAsLong() );
    1413             :             unique_ptr<CADImageDefObject> cadImageDef(
    1414           0 :                 dynamic_cast<CADImageDefObject *>( pCADImageDefObject ) );
    1415             : 
    1416           0 :             if(cadImageDef)
    1417             :             {
    1418           0 :                 CADImage * image = new CADImage();
    1419           0 :                 image->setClippingBoundaryType( cadImage->dClipBoundaryType );
    1420           0 :                 image->setFilePath( cadImageDef->sFilePath );
    1421           0 :                 image->setVertInsertionPoint( cadImage->vertInsertion );
    1422           0 :                 CADVector imageSize( cadImage->dfSizeX, cadImage->dfSizeY );
    1423           0 :                 image->setImageSize( imageSize );
    1424           0 :                 CADVector imageSizeInPx( cadImageDef->dfXImageSizeInPx, cadImageDef->dfYImageSizeInPx );
    1425           0 :                 image->setImageSizeInPx( imageSizeInPx );
    1426           0 :                 CADVector pixelSizeInACADUnits( cadImageDef->dfXPixelSize, cadImageDef->dfYPixelSize );
    1427           0 :                 image->setPixelSizeInACADUnits( pixelSizeInACADUnits );
    1428           0 :                 if( CADImage::IsValidResolutionUnit( cadImageDef->dResUnits ) )
    1429             :                 {
    1430           0 :                     image->setResolutionUnits(
    1431           0 :                         static_cast<CADImage::ResolutionUnit>( cadImageDef->dResUnits ) );
    1432             :                 }
    1433           0 :                 bool bTransparency = (cadImage->dDisplayProps & 0x08) != 0;
    1434           0 :                 image->setOptions( bTransparency,
    1435           0 :                                    cadImage->bClipping,
    1436           0 :                                    cadImage->dBrightness,
    1437           0 :                                    cadImage->dContrast );
    1438           0 :                 for( const CADVector& clipPt : cadImage->avertClippingPolygonVertices )
    1439             :                 {
    1440           0 :                     image->addClippingPoint( clipPt );
    1441             :                 }
    1442             : 
    1443           0 :                 poGeometry = image;
    1444             :             }
    1445             :             else
    1446             :             {
    1447           0 :                 delete pCADImageDefObject;
    1448             :             }
    1449           0 :             break;
    1450             :         }
    1451             : 
    1452           0 :         case CADObject::MLINE:
    1453             :         {
    1454           0 :             CADMLine * mline = new CADMLine();
    1455           0 :             CADMLineObject * cadmLine = static_cast<CADMLineObject *>(
    1456             :                     readObject);
    1457             : 
    1458           0 :             mline->setScale( cadmLine->dfScale );
    1459           0 :             mline->setOpened( cadmLine->dOpenClosed == 1 ? true : false );
    1460           0 :             for( const CADMLineVertex& vertex : cadmLine->avertVertices )
    1461           0 :                 mline->addVertex( vertex.vertPosition );
    1462             : 
    1463           0 :             poGeometry = mline;
    1464           0 :             break;
    1465             :         }
    1466             : 
    1467           2 :         case CADObject::MTEXT:
    1468             :         {
    1469           2 :             CADMText * mtext = new CADMText();
    1470           2 :             CADMTextObject * cadmText = static_cast<CADMTextObject *>(
    1471             :                     readObject);
    1472             : 
    1473           2 :             mtext->setTextValue( cadmText->sTextValue );
    1474           2 :             mtext->setXAxisAng( cadmText->vectXAxisDir.getX() ); //TODO: is this needed?
    1475             : 
    1476           2 :             mtext->setPosition( cadmText->vertInsertionPoint );
    1477           2 :             mtext->setExtrusion( cadmText->vectExtrusion );
    1478             : 
    1479           2 :             mtext->setHeight( cadmText->dfTextHeight );
    1480           2 :             mtext->setRectWidth( cadmText->dfRectWidth );
    1481           2 :             mtext->setExtents( cadmText->dfExtents );
    1482           2 :             mtext->setExtentsWidth( cadmText->dfExtentsWidth );
    1483             : 
    1484           2 :             poGeometry = mtext;
    1485           2 :             break;
    1486             :         }
    1487             : 
    1488           0 :         case CADObject::POLYLINE_PFACE:
    1489             :         {
    1490           0 :             CADPolylinePFace * polyline = new CADPolylinePFace();
    1491           0 :             CADPolylinePFaceObject * cadpolyPface = static_cast<CADPolylinePFaceObject *>(
    1492             :                     readObject);
    1493             : 
    1494             :             // TODO: code can be much simplified if CADHandle will be used.
    1495             :             // to do so, == and ++ operators should be implemented.
    1496           0 :             unique_ptr<CADVertexPFaceObject> vertex;
    1497           0 :             auto dCurrentEntHandle = cadpolyPface->hVertices[0].getAsLong();
    1498           0 :             auto dLastEntHandle = cadpolyPface->hVertices[1].getAsLong();
    1499             :             while( true )
    1500             :             {
    1501           0 :                 CADObject *pCADVertexPFaceObject = GetObject( dCurrentEntHandle );
    1502           0 :                 vertex.reset( dynamic_cast<CADVertexPFaceObject *>(
    1503           0 :                                       pCADVertexPFaceObject ) );
    1504             :                 /* TODO: this check is excessive, but if something goes wrong way -
    1505             :              * some part of geometries will be parsed. */
    1506           0 :                 if( !vertex )
    1507             :                 {
    1508           0 :                     delete pCADVertexPFaceObject;
    1509           0 :                     break;
    1510             :                 }
    1511             : 
    1512           0 :                 polyline->addVertex( vertex->vertPosition );
    1513             : 
    1514             :                 /* FIXME: somehow one more vertex which isnot presented is read.
    1515             :              * so, checking the number of added vertices */
    1516             :                 /*TODO: is this needed - check on real data
    1517             :             if ( polyline->hVertices.size() == cadpolyPface->nNumVertices )
    1518             :             {
    1519             :                 delete( vertex );
    1520             :                 break;
    1521             :             }*/
    1522             : 
    1523           0 :                 if( vertex->stCed.bNoLinks )
    1524           0 :                     ++dCurrentEntHandle;
    1525             :                 else
    1526           0 :                     dCurrentEntHandle = vertex->stChed.hNextEntity.getAsLong( vertex->stCed.hObjectHandle );
    1527             : 
    1528           0 :                 if( dCurrentEntHandle == dLastEntHandle )
    1529             :                 {
    1530           0 :                     CADObject *pCADVertexPFaceObjectV = GetObject( dCurrentEntHandle );
    1531           0 :                     vertex.reset( dynamic_cast<CADVertexPFaceObject *>(
    1532           0 :                                           pCADVertexPFaceObjectV) );
    1533           0 :                     if(vertex)
    1534             :                     {
    1535           0 :                         polyline->addVertex( vertex->vertPosition );
    1536             :                     }
    1537             :                     else
    1538             :                     {
    1539           0 :                         delete pCADVertexPFaceObjectV;
    1540             :                     }
    1541           0 :                     break;
    1542             :                 }
    1543           0 :             }
    1544             : 
    1545           0 :             poGeometry = polyline;
    1546           0 :             break;
    1547             :         }
    1548             : 
    1549           0 :         case CADObject::XLINE:
    1550             :         {
    1551           0 :             CADXLine * xline = new CADXLine();
    1552           0 :             CADXLineObject * cadxLine = static_cast<CADXLineObject *>(
    1553             :                     readObject);
    1554             : 
    1555           0 :             xline->setVectVector( cadxLine->vectVector );
    1556           0 :             xline->setPosition( cadxLine->vertPosition );
    1557             : 
    1558           0 :             poGeometry = xline;
    1559           0 :             break;
    1560             :         }
    1561             : 
    1562           0 :         case CADObject::FACE3D:
    1563             :         {
    1564           0 :             CADFace3D * face = new CADFace3D();
    1565           0 :             CAD3DFaceObject * cad3DFace = static_cast<CAD3DFaceObject *>(
    1566             :                     readObject);
    1567             : 
    1568           0 :             for( const CADVector& corner : cad3DFace->avertCorners )
    1569           0 :                 face->addCorner( corner );
    1570           0 :             face->setInvisFlags( cad3DFace->dInvisFlags );
    1571             : 
    1572           0 :             poGeometry = face;
    1573           0 :             break;
    1574             :         }
    1575             : 
    1576           0 :         case CADObject::POLYLINE_MESH:
    1577             :         case CADObject::VERTEX_MESH:
    1578             :         case CADObject::VERTEX_PFACE_FACE:
    1579             :         default:
    1580           0 :             std::cerr << "Asked geometry has unsupported type.\n";
    1581           0 :             poGeometry = new CADUnknown();
    1582           0 :             break;
    1583             :     }
    1584             : 
    1585          17 :     if( poGeometry == nullptr )
    1586           0 :         return nullptr;
    1587             : 
    1588             :     // Applying color
    1589          17 :     if( readObject->stCed.nCMColor == 256 ) // BYLAYER CASE
    1590             :     {
    1591          17 :         CADLayer& oCurrentLayer = this->GetLayer( iLayerIndex );
    1592          17 :         poGeometry->setColor( getCADACIColor( oCurrentLayer.getColor() ) );
    1593             :     }
    1594           0 :     else if( readObject->stCed.nCMColor <= 255 &&
    1595           0 :              readObject->stCed.nCMColor >= 0 ) // Excessive check until BYBLOCK case will not be implemented
    1596             :     {
    1597           0 :         poGeometry->setColor( getCADACIColor( readObject->stCed.nCMColor ) );
    1598             :     }
    1599             : 
    1600             :     // Applying EED
    1601             :     // Casting object's EED to a vector of strings
    1602          17 :     vector<string> asEED;
    1603          24 :     for( auto citer = readObject->stCed.aEED.cbegin();
    1604          31 :          citer != readObject->stCed.aEED.cend(); ++citer )
    1605             :     {
    1606          14 :         string sEED = "";
    1607             :         // Detect the type of EED entity
    1608           7 :         switch( citer->acData[0] )
    1609             :         {
    1610           2 :             case 0: // String
    1611             :             {
    1612           2 :                 if( citer->acData.size() > 1 )
    1613             :                 {
    1614           2 :                     unsigned char nStrSize = citer->acData[1];
    1615             :                     // +2 = skip CodePage, no idea how to use it anyway
    1616             : 
    1617           2 :                     if(nStrSize > 0)
    1618             :                     {
    1619         114 :                         for( size_t i = 0; i < nStrSize &&
    1620          56 :                             i + 4 < citer->acData.size(); ++i )
    1621             :                         {
    1622          56 :                             sEED += citer->acData[i + 4];
    1623             :                         }
    1624             :                     }
    1625             :                 }
    1626           2 :                 break;
    1627             :             }
    1628           0 :             case 1: // Invalid
    1629             :             {
    1630           0 :                 DebugMsg( "Error: EED obj type is 1, error in R2000::getGeometry()" );
    1631           0 :                 break;
    1632             :             }
    1633           0 :             case 2: // { or }
    1634             :             {
    1635           0 :                 if( citer->acData.size() > 1 )
    1636             :                 {
    1637           0 :                     sEED += citer->acData[1] == 0 ? '{' : '}';
    1638             :                 }
    1639           0 :                 break;
    1640             :             }
    1641           0 :             case 3: // Layer table ref
    1642             :             {
    1643             :                 // FIXME: get CADHandle and return getAsLong() result.
    1644           0 :                 sEED += "Layer table ref (handle):";
    1645           0 :                 for( size_t i = 0; i < 8 && i + 1 < citer->acData.size(); ++i )
    1646             :                 {
    1647           0 :                     sEED += citer->acData[i + 1];
    1648             :                 }
    1649           0 :                 break;
    1650             :             }
    1651           0 :             case 4: // Binary chunk
    1652             :             {
    1653           0 :                 if( citer->acData.size() > 1 )
    1654             :                 {
    1655           0 :                     unsigned char nChunkSize = citer->acData[1];
    1656           0 :                     sEED += "Binary chunk (chars):";
    1657           0 :                     if(nChunkSize > 0)
    1658             :                     {
    1659           0 :                         for( size_t i = 0; i < nChunkSize &&
    1660           0 :                             i + 2 < citer->acData.size(); ++i )
    1661             :                         {
    1662           0 :                             sEED += citer->acData[i + 2];
    1663             :                         }
    1664             :                     }
    1665             :                     else
    1666             :                     {
    1667           0 :                         sEED += "?";
    1668             :                     }
    1669             :                 }
    1670           0 :                 break;
    1671             :             }
    1672           0 :             case 5: // Entity handle ref
    1673             :             {
    1674             :                 // FIXME: Get CADHandle and return getAsLong() result.
    1675           0 :                 sEED += "Entity handle ref (handle):";
    1676           0 :                 for( size_t i = 0; i < 8 && i + 1 < citer->acData.size(); ++i )
    1677             :                 {
    1678           0 :                     sEED += citer->acData[i + 1];
    1679             :                 }
    1680           0 :                 break;
    1681             :             }
    1682           0 :             case 10:
    1683             :             case 11:
    1684             :             case 12:
    1685             :             case 13:
    1686             :             {
    1687           0 :                 sEED += "Point: {";
    1688           0 :                 double dfX = 0, dfY = 0, dfZ = 0;
    1689           0 :                 if(citer->acData.size() > 24)
    1690             :                 {
    1691           0 :                     memcpy( & dfX, citer->acData.data() + 1, 8 );
    1692           0 :                     memcpy( & dfY, citer->acData.data() + 9, 8 );
    1693           0 :                     memcpy( & dfZ, citer->acData.data() + 17, 8 );
    1694             :                 }
    1695           0 :                 sEED += std::to_string( dfX );
    1696           0 :                 sEED += ';';
    1697           0 :                 sEED += std::to_string( dfY );
    1698           0 :                 sEED += ';';
    1699           0 :                 sEED += std::to_string( dfZ );
    1700           0 :                 sEED += '}';
    1701           0 :                 break;
    1702             :             }
    1703           0 :             case 40:
    1704             :             case 41:
    1705             :             case 42:
    1706             :             {
    1707           0 :                 sEED += "Double:";
    1708           0 :                 double dfVal = 0;
    1709           0 :                 if(citer->acData.size() > 8)
    1710           0 :                     memcpy( & dfVal, citer->acData.data() + 1, 8 );
    1711           0 :                 sEED += std::to_string( dfVal );
    1712           0 :                 break;
    1713             :             }
    1714           5 :             case 70:
    1715             :             {
    1716           5 :                 sEED += "Short:";
    1717           5 :                 int16_t dVal = 0;
    1718           5 :                 if(citer->acData.size() > 2)
    1719           5 :                     memcpy( & dVal, citer->acData.data() + 1, 2 );
    1720           5 :                 sEED += std::to_string( dVal );
    1721           5 :                 break;
    1722             :             }
    1723           0 :             case 71:
    1724             :             {
    1725           0 :                 sEED += "Long Int:";
    1726           0 :                 int32_t dVal = 0;
    1727           0 :                 if(citer->acData.size() > 4)
    1728           0 :                     memcpy( & dVal, citer->acData.data() + 1, 4 );
    1729           0 :                 sEED += std::to_string( dVal );
    1730           0 :                 break;
    1731             :             }
    1732           0 :             default:
    1733             :             {
    1734           0 :                 DebugMsg( "Error in parsing geometry EED: undefined typecode: %d",
    1735           0 :                           static_cast<int>(citer->acData[0]) );
    1736             :             }
    1737             :         }
    1738           7 :         asEED.emplace_back( sEED );
    1739             :     }
    1740             : 
    1741             :     // Getting block reference attributes.
    1742          17 :     if( dBlockRefHandle != 0 )
    1743             :     {
    1744           0 :         vector<CADAttrib>           blockRefAttributes;
    1745           0 :         CADObject *pCADInsertObject = GetObject( dBlockRefHandle );
    1746             :         unique_ptr<CADInsertObject> spoBlockRef(
    1747           0 :                     dynamic_cast<CADInsertObject *>( pCADInsertObject ) );
    1748             : 
    1749           0 :         if( spoBlockRef )
    1750             :         {
    1751           0 :             if( !spoBlockRef->hAttribs.empty() )
    1752             :             {
    1753           0 :                 long dCurrentEntHandle = spoBlockRef->hAttribs[0].getAsLong();
    1754           0 :                 long dLastEntHandle    = spoBlockRef->hAttribs[0].getAsLong();
    1755             : 
    1756           0 :                 while( spoBlockRef->bHasAttribs )
    1757             :                 {
    1758           0 :                     CADObject *pCADAttDefObj = GetObject( dCurrentEntHandle, true );
    1759             : 
    1760             :                     CADEntityObject * attDefObj =
    1761           0 :                             dynamic_cast<CADEntityObject *>( pCADAttDefObj );
    1762             : 
    1763           0 :                     if( dCurrentEntHandle == dLastEntHandle )
    1764             :                     {
    1765           0 :                         if( attDefObj == nullptr )
    1766             :                         {
    1767           0 :                             delete pCADAttDefObj;
    1768           0 :                             break;
    1769             :                         }
    1770             : 
    1771           0 :                         auto geometry = GetGeometry( iLayerIndex, dCurrentEntHandle );
    1772           0 :                         CADAttrib * attrib = dynamic_cast<CADAttrib *>(geometry);
    1773           0 :                         if( attrib )
    1774             :                         {
    1775           0 :                             blockRefAttributes.push_back( CADAttrib( * attrib ) );
    1776             :                         }
    1777           0 :                         delete geometry;
    1778           0 :                         delete attDefObj;
    1779           0 :                         break;
    1780             :                     }
    1781             : 
    1782           0 :                     if( attDefObj != nullptr )
    1783             :                     {
    1784           0 :                         if( attDefObj->stCed.bNoLinks )
    1785           0 :                             ++dCurrentEntHandle;
    1786             :                         else
    1787           0 :                             dCurrentEntHandle = attDefObj->stChed.hNextEntity.getAsLong( attDefObj->stCed.hObjectHandle );
    1788             : 
    1789           0 :                         auto geometry = GetGeometry( iLayerIndex, dCurrentEntHandle );
    1790           0 :                         CADAttrib * attrib = dynamic_cast<CADAttrib *>(geometry);
    1791           0 :                         if( attrib )
    1792             :                         {
    1793           0 :                             blockRefAttributes.push_back( CADAttrib( * attrib ) );
    1794             :                         }
    1795           0 :                         delete geometry;
    1796           0 :                         delete attDefObj;
    1797             :                     }
    1798             :                     else
    1799             :                     {
    1800           0 :                         delete pCADAttDefObj;
    1801             :                     }
    1802             :                 }
    1803           0 :                 poGeometry->setBlockAttributes( blockRefAttributes );
    1804             :             }
    1805             :         }
    1806             :         else
    1807             :         {
    1808           0 :             delete pCADInsertObject;
    1809             :         }
    1810             :     }
    1811             : 
    1812          17 :     poGeometry->setEED( asEED );
    1813          17 :     return poGeometry;
    1814             : }
    1815             : 
    1816           0 : CADBlockObject * DWGFileR2000::getBlock(unsigned int dObjectSize,
    1817             :                                         const CADCommonED& stCommonEntityData,
    1818             :                                         CADBuffer &buffer)
    1819             : {
    1820           0 :     CADBlockObject * pBlock = new CADBlockObject();
    1821             : 
    1822           0 :     pBlock->setSize( dObjectSize );
    1823           0 :     pBlock->stCed = stCommonEntityData;
    1824             : 
    1825           0 :     pBlock->sBlockName = buffer.ReadTV();
    1826             : 
    1827           0 :     fillCommonEntityHandleData( pBlock, buffer);
    1828             : 
    1829           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    1830           0 :     pBlock->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "BLOCK" ) );
    1831             : 
    1832           0 :     return pBlock;
    1833             : }
    1834             : 
    1835           1 : CADEllipseObject * DWGFileR2000::getEllipse(unsigned int dObjectSize,
    1836             :                                             const CADCommonED& stCommonEntityData,
    1837             :                                             CADBuffer& buffer)
    1838             : {
    1839           1 :     CADEllipseObject * ellipse = new CADEllipseObject();
    1840             : 
    1841           1 :     ellipse->setSize( dObjectSize );
    1842           1 :     ellipse->stCed = stCommonEntityData;
    1843             : 
    1844           1 :     CADVector vertPosition = buffer.ReadVector();
    1845             : 
    1846           1 :     ellipse->vertPosition = vertPosition;
    1847             : 
    1848           1 :     CADVector vectSMAxis = buffer.ReadVector();
    1849             : 
    1850           1 :     ellipse->vectSMAxis = vectSMAxis;
    1851             : 
    1852           1 :     CADVector vectExtrusion = buffer.ReadVector();
    1853             : 
    1854           1 :     ellipse->vectExtrusion = vectExtrusion;
    1855             : 
    1856           1 :     ellipse->dfAxisRatio = buffer.ReadBITDOUBLE();
    1857           1 :     ellipse->dfBegAngle  = buffer.ReadBITDOUBLE();
    1858           1 :     ellipse->dfEndAngle  = buffer.ReadBITDOUBLE();
    1859             : 
    1860           1 :     fillCommonEntityHandleData(ellipse, buffer);
    1861             : 
    1862           1 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    1863           1 :     ellipse->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ELLIPSE" ) );
    1864             : 
    1865           1 :     return ellipse;
    1866             : }
    1867             : 
    1868           0 : CADSolidObject * DWGFileR2000::getSolid(unsigned int dObjectSize,
    1869             :                                         const CADCommonED& stCommonEntityData,
    1870             :                                         CADBuffer &buffer)
    1871             : {
    1872           0 :     CADSolidObject * solid = new CADSolidObject();
    1873             : 
    1874           0 :     solid->setSize( dObjectSize );
    1875           0 :     solid->stCed = stCommonEntityData;
    1876             : 
    1877           0 :     solid->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    1878             : 
    1879           0 :     solid->dfElevation = buffer.ReadBITDOUBLE();
    1880             : 
    1881           0 :     CADVector   oCorner;
    1882           0 :     for( size_t i = 0; i < 4; ++i )
    1883             :     {
    1884           0 :         oCorner.setX( buffer.ReadRAWDOUBLE() );
    1885           0 :         oCorner.setY( buffer.ReadRAWDOUBLE() );
    1886           0 :         solid->avertCorners.push_back( oCorner );
    1887             :     }
    1888             : 
    1889           0 :     if( buffer.ReadBIT() )
    1890             :     {
    1891           0 :         solid->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    1892             :     }
    1893             :     else
    1894             :     {
    1895           0 :         CADVector vectExtrusion = buffer.ReadVector();
    1896           0 :         solid->vectExtrusion = vectExtrusion;
    1897             :     }
    1898             : 
    1899             : 
    1900           0 :     fillCommonEntityHandleData( solid, buffer);
    1901             : 
    1902           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    1903           0 :     solid->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "SOLID" ) );
    1904             : 
    1905           0 :     return solid;
    1906             : }
    1907             : 
    1908           1 : CADPointObject * DWGFileR2000::getPoint(unsigned int dObjectSize,
    1909             :                                         const CADCommonED& stCommonEntityData,
    1910             :                                         CADBuffer& buffer)
    1911             : {
    1912           1 :     CADPointObject * point = new CADPointObject();
    1913             : 
    1914           1 :     point->setSize( dObjectSize );
    1915           1 :     point->stCed = stCommonEntityData;
    1916             : 
    1917           1 :     CADVector vertPosition = buffer.ReadVector();
    1918             : 
    1919           1 :     point->vertPosition = vertPosition;
    1920             : 
    1921           1 :     point->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    1922             : 
    1923           1 :     if( buffer.ReadBIT() )
    1924             :     {
    1925           1 :         point->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    1926             :     }
    1927             :     else
    1928             :     {
    1929           0 :         CADVector vectExtrusion = buffer.ReadVector();
    1930           0 :         point->vectExtrusion = vectExtrusion;
    1931             :     }
    1932             : 
    1933           1 :     point->dfXAxisAng = buffer.ReadBITDOUBLE();
    1934             : 
    1935           1 :     fillCommonEntityHandleData( point, buffer);
    1936             : 
    1937           1 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    1938           1 :     point->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POINT" ) );
    1939             : 
    1940           1 :     return point;
    1941             : }
    1942             : 
    1943           0 : CADPolyline3DObject * DWGFileR2000::getPolyLine3D(unsigned int dObjectSize,
    1944             :                                                   const CADCommonED& stCommonEntityData,
    1945             :                                                   CADBuffer &buffer)
    1946             : {
    1947           0 :     CADPolyline3DObject * polyline = new CADPolyline3DObject();
    1948             : 
    1949           0 :     polyline->setSize( dObjectSize );
    1950           0 :     polyline->stCed = stCommonEntityData;
    1951             : 
    1952           0 :     polyline->SplinedFlags = buffer.ReadCHAR();
    1953           0 :     polyline->ClosedFlags  = buffer.ReadCHAR();
    1954             : 
    1955           0 :     fillCommonEntityHandleData( polyline, buffer );
    1956             : 
    1957           0 :     polyline->hVertices.push_back( buffer.ReadHANDLE() ); // 1st vertex
    1958           0 :     polyline->hVertices.push_back( buffer.ReadHANDLE() ); // last vertex
    1959             : 
    1960           0 :     polyline->hSeqend = buffer.ReadHANDLE();
    1961             : 
    1962           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    1963           0 :     polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POLYLINE" ) );
    1964             : 
    1965           0 :     return polyline;
    1966             : }
    1967             : 
    1968           0 : CADRayObject * DWGFileR2000::getRay(unsigned int dObjectSize,
    1969             :                                     const CADCommonED& stCommonEntityData,
    1970             :                                     CADBuffer &buffer)
    1971             : {
    1972           0 :     CADRayObject * ray = new CADRayObject();
    1973             : 
    1974           0 :     ray->setSize( dObjectSize );
    1975           0 :     ray->stCed = stCommonEntityData;
    1976             : 
    1977           0 :     CADVector vertPosition = buffer.ReadVector();
    1978             : 
    1979           0 :     ray->vertPosition = vertPosition;
    1980             : 
    1981           0 :     CADVector vectVector = buffer.ReadVector();
    1982           0 :     ray->vectVector = vectVector;
    1983             : 
    1984           0 :     fillCommonEntityHandleData( ray, buffer);
    1985             : 
    1986           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    1987           0 :     ray->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "RAY" ) );
    1988             : 
    1989           0 :     return ray;
    1990             : }
    1991             : 
    1992           0 : CADXLineObject * DWGFileR2000::getXLine(unsigned int dObjectSize,
    1993             :                                         const CADCommonED& stCommonEntityData,
    1994             :                                         CADBuffer &buffer)
    1995             : {
    1996           0 :     CADXLineObject * xline = new CADXLineObject();
    1997             : 
    1998           0 :     xline->setSize( dObjectSize );
    1999           0 :     xline->stCed = stCommonEntityData;
    2000             : 
    2001           0 :     CADVector vertPosition = buffer.ReadVector();
    2002             : 
    2003           0 :     xline->vertPosition = vertPosition;
    2004             : 
    2005           0 :     CADVector vectVector = buffer.ReadVector();
    2006           0 :     xline->vectVector = vectVector;
    2007             : 
    2008           0 :     fillCommonEntityHandleData( xline, buffer);
    2009             : 
    2010           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2011           0 :     xline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "XLINE" ) );
    2012             : 
    2013           0 :     return xline;
    2014             : }
    2015             : 
    2016           1 : CADLineObject * DWGFileR2000::getLine(unsigned int dObjectSize,
    2017             :                                       const CADCommonED& stCommonEntityData,
    2018             :                                       CADBuffer &buffer)
    2019             : {
    2020           1 :     CADLineObject * line = new CADLineObject();
    2021             : 
    2022           1 :     line->setSize( dObjectSize );
    2023           1 :     line->stCed = stCommonEntityData;
    2024             : 
    2025           1 :     bool bZsAreZeros = buffer.ReadBIT();
    2026             : 
    2027           1 :     CADVector vertStart, vertEnd;
    2028           1 :     vertStart.setX( buffer.ReadRAWDOUBLE() );
    2029           1 :     vertEnd.setX( buffer.ReadBITDOUBLEWD(vertStart.getX() ) );
    2030           1 :     vertStart.setY( buffer.ReadRAWDOUBLE() );
    2031           1 :     vertEnd.setY( buffer.ReadBITDOUBLEWD(vertStart.getY() ) );
    2032             : 
    2033           1 :     if( !bZsAreZeros )
    2034             :     {
    2035           0 :         vertStart.setZ( buffer.ReadBITDOUBLE() );
    2036           0 :         vertEnd.setZ( buffer.ReadBITDOUBLEWD(vertStart.getZ() ) );
    2037             :     }
    2038             : 
    2039           1 :     line->vertStart = vertStart;
    2040           1 :     line->vertEnd   = vertEnd;
    2041             : 
    2042           1 :     line->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    2043             : 
    2044           1 :     if( buffer.ReadBIT() )
    2045             :     {
    2046           1 :         line->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    2047             :     } else
    2048             :     {
    2049           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2050           0 :         line->vectExtrusion = vectExtrusion;
    2051             :     }
    2052             : 
    2053           1 :     fillCommonEntityHandleData( line, buffer);
    2054             : 
    2055           1 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2056           1 :     line->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LINE" ) );
    2057           1 :     return line;
    2058             : }
    2059             : 
    2060           4 : CADTextObject * DWGFileR2000::getText(unsigned int dObjectSize,
    2061             :                                       const CADCommonED& stCommonEntityData,
    2062             :                                       CADBuffer &buffer)
    2063             : {
    2064           4 :     CADTextObject * text = new CADTextObject();
    2065             : 
    2066           4 :     text->setSize( dObjectSize );
    2067           4 :     text->stCed = stCommonEntityData;
    2068             : 
    2069           4 :     text->DataFlags = buffer.ReadCHAR();
    2070             : 
    2071           4 :     if( !( text->DataFlags & 0x01 ) )
    2072             :     {
    2073           0 :         text->dfElevation = buffer.ReadRAWDOUBLE();
    2074             :     }
    2075             : 
    2076           4 :     CADVector vertInsetionPoint = buffer.ReadRAWVector();
    2077             : 
    2078           4 :     text->vertInsetionPoint = vertInsetionPoint;
    2079             : 
    2080           4 :     if( !( text->DataFlags & 0x02 ) )
    2081             :     {
    2082             :         double x, y;
    2083           0 :         x = buffer.ReadBITDOUBLEWD(vertInsetionPoint.getX() );
    2084           0 :         y = buffer.ReadBITDOUBLEWD(vertInsetionPoint.getY() );
    2085           0 :         CADVector vertAlignmentPoint( x, y );
    2086           0 :         text->vertAlignmentPoint = vertAlignmentPoint;
    2087             :     }
    2088             : 
    2089           4 :     if( buffer.ReadBIT() )
    2090             :     {
    2091           4 :         text->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    2092             :     }
    2093             :     else
    2094             :     {
    2095           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2096           0 :         text->vectExtrusion = vectExtrusion;
    2097             :     }
    2098             : 
    2099           4 :     text->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    2100             : 
    2101           4 :     if( !( text->DataFlags & 0x04 ) )
    2102           0 :         text->dfObliqueAng  = buffer.ReadRAWDOUBLE();
    2103           4 :     if( !( text->DataFlags & 0x08 ) )
    2104           0 :         text->dfRotationAng = buffer.ReadRAWDOUBLE();
    2105             : 
    2106           4 :     text->dfHeight = buffer.ReadRAWDOUBLE();
    2107             : 
    2108           4 :     if( !( text->DataFlags & 0x10 ) )
    2109           0 :         text->dfWidthFactor = buffer.ReadRAWDOUBLE();
    2110             : 
    2111           4 :     text->sTextValue = buffer.ReadTV();
    2112             : 
    2113           4 :     if( !( text->DataFlags & 0x20 ) )
    2114           0 :         text->dGeneration = buffer.ReadBITSHORT();
    2115           4 :     if( !( text->DataFlags & 0x40 ) )
    2116           0 :         text->dHorizAlign = buffer.ReadBITSHORT();
    2117           4 :     if( !( text->DataFlags & 0x80 ) )
    2118           0 :         text->dVertAlign  = buffer.ReadBITSHORT();
    2119             : 
    2120           4 :     fillCommonEntityHandleData( text, buffer);
    2121             : 
    2122           4 :     text->hStyle = buffer.ReadHANDLE();
    2123             : 
    2124           4 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2125           4 :     text->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "TEXT" ) );
    2126             : 
    2127           4 :     return text;
    2128             : }
    2129             : 
    2130           0 : CADVertex3DObject * DWGFileR2000::getVertex3D(unsigned int dObjectSize,
    2131             :                                               const CADCommonED& stCommonEntityData,
    2132             :                                               CADBuffer &buffer)
    2133             : {
    2134           0 :     CADVertex3DObject * vertex = new CADVertex3DObject();
    2135             : 
    2136           0 :     vertex->setSize( dObjectSize );
    2137           0 :     vertex->stCed = stCommonEntityData;
    2138             : 
    2139           0 :     /*unsigned char Flags = */buffer.ReadCHAR();
    2140             : 
    2141           0 :     CADVector vertPosition = buffer.ReadVector();
    2142           0 :     vertex->vertPosition = vertPosition;
    2143             : 
    2144           0 :     fillCommonEntityHandleData( vertex, buffer);
    2145             : 
    2146           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2147           0 :     vertex->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "VERTEX" ) );
    2148           0 :     return vertex;
    2149             : }
    2150             : 
    2151           3 : CADCircleObject * DWGFileR2000::getCircle(unsigned int dObjectSize,
    2152             :                                           const CADCommonED& stCommonEntityData,
    2153             :                                           CADBuffer &buffer)
    2154             : {
    2155           3 :     CADCircleObject * circle = new CADCircleObject();
    2156             : 
    2157           3 :     circle->setSize( dObjectSize );
    2158           3 :     circle->stCed = stCommonEntityData;
    2159             : 
    2160           3 :     CADVector vertPosition = buffer.ReadVector();
    2161           3 :     circle->vertPosition = vertPosition;
    2162           3 :     circle->dfRadius     = buffer.ReadBITDOUBLE();
    2163           3 :     circle->dfThickness  = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    2164             : 
    2165           3 :     if( buffer.ReadBIT() )
    2166             :     {
    2167           3 :         circle->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    2168             :     }
    2169             :     else
    2170             :     {
    2171           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2172           0 :         circle->vectExtrusion = vectExtrusion;
    2173             :     }
    2174             : 
    2175           3 :     fillCommonEntityHandleData( circle, buffer);
    2176             : 
    2177           3 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2178           3 :     circle->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "CIRCLE" ) );
    2179           3 :     return circle;
    2180             : }
    2181             : 
    2182           0 : CADEndblkObject * DWGFileR2000::getEndBlock(unsigned int dObjectSize,
    2183             :                                             const CADCommonED& stCommonEntityData,
    2184             :                                             CADBuffer &buffer)
    2185             : {
    2186           0 :     CADEndblkObject * endblk = new CADEndblkObject();
    2187             : 
    2188           0 :     endblk->setSize( dObjectSize );
    2189           0 :     endblk->stCed = stCommonEntityData;
    2190             : 
    2191           0 :     fillCommonEntityHandleData( endblk, buffer);
    2192             : 
    2193           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2194           0 :     endblk->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ENDBLK" ) );
    2195           0 :     return endblk;
    2196             : }
    2197             : 
    2198           0 : CADPolyline2DObject * DWGFileR2000::getPolyline2D(unsigned int dObjectSize,
    2199             :                                                   const CADCommonED& stCommonEntityData,
    2200             :                                                   CADBuffer &buffer)
    2201             : {
    2202           0 :     CADPolyline2DObject * polyline = new CADPolyline2DObject();
    2203             : 
    2204           0 :     polyline->setSize( dObjectSize );
    2205           0 :     polyline->stCed = stCommonEntityData;
    2206             : 
    2207           0 :     polyline->dFlags                = buffer.ReadBITSHORT();
    2208           0 :     polyline->dCurveNSmoothSurfType = buffer.ReadBITSHORT();
    2209             : 
    2210           0 :     polyline->dfStartWidth = buffer.ReadBITDOUBLE();
    2211           0 :     polyline->dfEndWidth   = buffer.ReadBITDOUBLE();
    2212             : 
    2213           0 :     polyline->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    2214             : 
    2215           0 :     polyline->dfElevation = buffer.ReadBITDOUBLE();
    2216             : 
    2217           0 :     if( buffer.ReadBIT() )
    2218             :     {
    2219           0 :         polyline->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    2220             :     }
    2221             :     else
    2222             :     {
    2223           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2224           0 :         polyline->vectExtrusion = vectExtrusion;
    2225             :     }
    2226             : 
    2227           0 :     fillCommonEntityHandleData( polyline, buffer);
    2228             : 
    2229           0 :     polyline->hVertices.push_back( buffer.ReadHANDLE() ); // 1st vertex
    2230           0 :     polyline->hVertices.push_back( buffer.ReadHANDLE() ); // last vertex
    2231             : 
    2232           0 :     polyline->hSeqend = buffer.ReadHANDLE();
    2233             : 
    2234           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2235           0 :     polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POLYLINE" ) );
    2236           0 :     return polyline;
    2237             : }
    2238             : 
    2239           0 : CADAttribObject * DWGFileR2000::getAttributes(unsigned int dObjectSize,
    2240             :                                               const CADCommonED& stCommonEntityData,
    2241             :                                               CADBuffer &buffer)
    2242             : {
    2243           0 :     CADAttribObject * attrib = new CADAttribObject();
    2244             : 
    2245           0 :     attrib->setSize( dObjectSize );
    2246           0 :     attrib->stCed     = stCommonEntityData;
    2247           0 :     attrib->DataFlags = buffer.ReadCHAR();
    2248             : 
    2249           0 :     if( !( attrib->DataFlags & 0x01 ) )
    2250           0 :         attrib->dfElevation = buffer.ReadRAWDOUBLE();
    2251             : 
    2252             :     double x, y;
    2253             : 
    2254           0 :     CADVector vertInsetionPoint = buffer.ReadRAWVector();
    2255           0 :     attrib->vertInsetionPoint = vertInsetionPoint;
    2256             : 
    2257           0 :     if( !( attrib->DataFlags & 0x02 ) )
    2258             :     {
    2259           0 :         x = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getX() );
    2260           0 :         y = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getY() );
    2261           0 :         CADVector vertAlignmentPoint( x, y );
    2262           0 :         attrib->vertAlignmentPoint = vertAlignmentPoint;
    2263             :     }
    2264             : 
    2265           0 :     if( buffer.ReadBIT() )
    2266             :     {
    2267           0 :         attrib->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    2268             :     }
    2269             :     else
    2270             :     {
    2271           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2272           0 :         attrib->vectExtrusion = vectExtrusion;
    2273             :     }
    2274             : 
    2275           0 :     attrib->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    2276             : 
    2277           0 :     if( !( attrib->DataFlags & 0x04 ) )
    2278           0 :         attrib->dfObliqueAng  = buffer.ReadRAWDOUBLE();
    2279           0 :     if( !( attrib->DataFlags & 0x08 ) )
    2280           0 :         attrib->dfRotationAng = buffer.ReadRAWDOUBLE();
    2281           0 :     attrib->dfHeight          = buffer.ReadRAWDOUBLE();
    2282           0 :     if( !( attrib->DataFlags & 0x10 ) )
    2283           0 :         attrib->dfWidthFactor = buffer.ReadRAWDOUBLE();
    2284           0 :     attrib->sTextValue        = buffer.ReadTV();
    2285           0 :     if( !( attrib->DataFlags & 0x20 ) )
    2286           0 :         attrib->dGeneration   = buffer.ReadBITSHORT();
    2287           0 :     if( !( attrib->DataFlags & 0x40 ) )
    2288           0 :         attrib->dHorizAlign   = buffer.ReadBITSHORT();
    2289           0 :     if( !( attrib->DataFlags & 0x80 ) )
    2290           0 :         attrib->dVertAlign    = buffer.ReadBITSHORT();
    2291             : 
    2292           0 :     attrib->sTag         = buffer.ReadTV();
    2293           0 :     attrib->nFieldLength = buffer.ReadBITSHORT();
    2294           0 :     attrib->nFlags       = buffer.ReadCHAR();
    2295             : 
    2296           0 :     fillCommonEntityHandleData( attrib, buffer);
    2297             : 
    2298           0 :     attrib->hStyle = buffer.ReadHANDLE();
    2299             : 
    2300           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2301           0 :     attrib->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ATTRIB" ) );
    2302           0 :     return attrib;
    2303             : }
    2304             : 
    2305           5 : CADAttdefObject * DWGFileR2000::getAttributesDefn(unsigned int dObjectSize,
    2306             :                                                   const CADCommonED& stCommonEntityData,
    2307             :                                                   CADBuffer &buffer)
    2308             : {
    2309           5 :     CADAttdefObject * attdef = new CADAttdefObject();
    2310             : 
    2311           5 :     attdef->setSize( dObjectSize );
    2312           5 :     attdef->stCed     = stCommonEntityData;
    2313           5 :     attdef->DataFlags = buffer.ReadCHAR();
    2314             : 
    2315           5 :     if( ( attdef->DataFlags & 0x01 ) == 0 )
    2316           0 :         attdef->dfElevation = buffer.ReadRAWDOUBLE();
    2317             : 
    2318           5 :     CADVector vertInsetionPoint = buffer.ReadRAWVector();
    2319           5 :     attdef->vertInsetionPoint = vertInsetionPoint;
    2320             : 
    2321           5 :     if( ( attdef->DataFlags & 0x02 ) == 0 )
    2322             :     {
    2323           0 :         double x = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getX() );
    2324           0 :         double y = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getY() );
    2325           0 :         CADVector vertAlignmentPoint( x, y );
    2326           0 :         attdef->vertAlignmentPoint = vertAlignmentPoint;
    2327             :     }
    2328             : 
    2329           5 :     if( buffer.ReadBIT() )
    2330             :     {
    2331           5 :         attdef->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    2332             :     }
    2333             :     else
    2334             :     {
    2335           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2336           0 :         attdef->vectExtrusion = vectExtrusion;
    2337             :     }
    2338             : 
    2339           5 :     attdef->dfThickness = buffer.ReadBIT() ? 0.0f :
    2340           0 :                           buffer.ReadBITDOUBLE();
    2341             : 
    2342           5 :     if( ( attdef->DataFlags & 0x04 ) == 0 )
    2343           0 :         attdef->dfObliqueAng  = buffer.ReadRAWDOUBLE();
    2344           5 :     if( ( attdef->DataFlags & 0x08 ) == 0 )
    2345           0 :         attdef->dfRotationAng = buffer.ReadRAWDOUBLE();
    2346           5 :     attdef->dfHeight          = buffer.ReadRAWDOUBLE();
    2347           5 :     if( ( attdef->DataFlags & 0x10 ) == 0 )
    2348           0 :         attdef->dfWidthFactor = buffer.ReadRAWDOUBLE();
    2349           5 :     attdef->sTextValue        = buffer.ReadTV();
    2350           5 :     if( ( attdef->DataFlags & 0x20 ) == 0 )
    2351           0 :         attdef->dGeneration   = buffer.ReadBITSHORT();
    2352           5 :     if( ( attdef->DataFlags & 0x40 ) == 0 )
    2353           0 :         attdef->dHorizAlign   = buffer.ReadBITSHORT();
    2354           5 :     if( ( attdef->DataFlags & 0x80 ) == 0 )
    2355           0 :         attdef->dVertAlign    = buffer.ReadBITSHORT();
    2356             : 
    2357           5 :     attdef->sTag         = buffer.ReadTV();
    2358           5 :     attdef->nFieldLength = buffer.ReadBITSHORT();
    2359           5 :     attdef->nFlags       = buffer.ReadCHAR();
    2360             : 
    2361           5 :     attdef->sPrompt = buffer.ReadTV();
    2362             : 
    2363           5 :     fillCommonEntityHandleData( attdef, buffer);
    2364             : 
    2365           5 :     attdef->hStyle = buffer.ReadHANDLE();
    2366             : 
    2367           5 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2368           5 :     attdef->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ATTRDEF" ) );
    2369           5 :     return attdef;
    2370             : }
    2371             : 
    2372           0 : CADLWPolylineObject * DWGFileR2000::getLWPolyLine(unsigned int dObjectSize,
    2373             :                                                   const CADCommonED& stCommonEntityData,
    2374             :                                                   CADBuffer &buffer)
    2375             : {
    2376           0 :     CADLWPolylineObject * polyline = new CADLWPolylineObject();
    2377           0 :     polyline->setSize( dObjectSize );
    2378           0 :     polyline->stCed = stCommonEntityData;
    2379             : 
    2380           0 :     int    verticesCount = 0, nBulges = 0, nNumWidths = 0;
    2381           0 :     short  dataFlag      = buffer.ReadBITSHORT();
    2382           0 :     if( dataFlag & 4 )
    2383           0 :         polyline->dfConstWidth = buffer.ReadBITDOUBLE();
    2384           0 :     if( dataFlag & 8 )
    2385           0 :         polyline->dfElevation  = buffer.ReadBITDOUBLE();
    2386           0 :     if( dataFlag & 2 )
    2387           0 :         polyline->dfThickness  = buffer.ReadBITDOUBLE();
    2388           0 :     if( dataFlag & 1 )
    2389             :     {
    2390           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2391           0 :         polyline->vectExtrusion = vectExtrusion;
    2392             :     }
    2393             : 
    2394           0 :     verticesCount = buffer.ReadBITLONG();
    2395           0 :     if(verticesCount < 1)
    2396             :     {
    2397           0 :         delete polyline;
    2398           0 :         return nullptr;
    2399             :     }
    2400           0 :     if( verticesCount < 100000 )
    2401             :     {
    2402             :         // For some reason reserving huge amounts cause later segfaults
    2403             :         // whereas an exception would have been expected
    2404           0 :         polyline->avertVertices.reserve( static_cast<size_t>(verticesCount) );
    2405             :     }
    2406             : 
    2407           0 :     if( dataFlag & 16 )
    2408             :     {
    2409           0 :         nBulges = buffer.ReadBITLONG();
    2410           0 :         if(nBulges < 0)
    2411             :         {
    2412           0 :             delete polyline;
    2413           0 :             return nullptr;
    2414             :         }
    2415           0 :         if( nBulges < 100000 )
    2416             :         {
    2417           0 :             polyline->adfBulges.reserve( static_cast<size_t>(nBulges) );
    2418             :         }
    2419             :     }
    2420             : 
    2421             :     // TODO: tell ODA that R2000 contains nNumWidths flag
    2422           0 :     if( dataFlag & 32 )
    2423             :     {
    2424           0 :         nNumWidths = buffer.ReadBITLONG();
    2425           0 :         if(nNumWidths < 0)
    2426             :         {
    2427           0 :             delete polyline;
    2428           0 :             return nullptr;
    2429             :         }
    2430           0 :         if( nNumWidths < 100000 )
    2431             :         {
    2432           0 :             polyline->astWidths.reserve( static_cast<size_t>(nNumWidths) );
    2433             :         }
    2434             :     }
    2435             : 
    2436           0 :     if( dataFlag & 512 )
    2437             :     {
    2438           0 :         polyline->bClosed = true;
    2439             :     }
    2440             :     else
    2441             :     {
    2442           0 :         polyline->bClosed = false;
    2443             :     }
    2444             : 
    2445             :     // First of all, read first vertex.
    2446           0 :     CADVector vertex = buffer.ReadRAWVector();
    2447           0 :     polyline->avertVertices.push_back( vertex );
    2448             : 
    2449             :     // All the others are not raw doubles; bitdoubles with default instead,
    2450             :     // where default is previous point coords.
    2451             :     size_t prev;
    2452           0 :     for( int i = 1; i < verticesCount; ++i )
    2453             :     {
    2454           0 :         prev = size_t( i - 1 );
    2455           0 :         double x = buffer.ReadBITDOUBLEWD( polyline->avertVertices[prev].getX() );
    2456           0 :         double y = buffer.ReadBITDOUBLEWD( polyline->avertVertices[prev].getY() );
    2457           0 :         if( buffer.IsEOB() )
    2458             :         {
    2459           0 :             delete polyline;
    2460           0 :             return nullptr;
    2461             :         }
    2462           0 :         vertex.setX( x );
    2463           0 :         vertex.setY( y );
    2464           0 :         polyline->avertVertices.push_back( vertex );
    2465             :     }
    2466             : 
    2467           0 :     for( int i = 0; i < nBulges; ++i )
    2468             :     {
    2469           0 :         double dfBulgeValue = buffer.ReadBITDOUBLE();
    2470           0 :         polyline->adfBulges.push_back( dfBulgeValue );
    2471           0 :         if( buffer.IsEOB() )
    2472             :         {
    2473           0 :             delete polyline;
    2474           0 :             return nullptr;
    2475             :         }
    2476             :     }
    2477             : 
    2478           0 :     for( int i = 0; i < nNumWidths; ++i )
    2479             :     {
    2480           0 :         double dfStartWidth = buffer.ReadBITDOUBLE();
    2481           0 :         double dfEndWidth   = buffer.ReadBITDOUBLE();
    2482           0 :         if( buffer.IsEOB() )
    2483             :         {
    2484           0 :             delete polyline;
    2485           0 :             return nullptr;
    2486             :         }
    2487           0 :         polyline->astWidths.push_back( make_pair( dfStartWidth, dfEndWidth ) );
    2488             :     }
    2489             : 
    2490           0 :     fillCommonEntityHandleData( polyline, buffer);
    2491             : 
    2492           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2493           0 :     polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "WPOLYLINE" ) );
    2494           0 :     return polyline;
    2495             : }
    2496             : 
    2497           0 : CADArcObject * DWGFileR2000::getArc(unsigned int dObjectSize,
    2498             :                                     const CADCommonED& stCommonEntityData,
    2499             :                                     CADBuffer &buffer)
    2500             : {
    2501           0 :     CADArcObject * arc = new CADArcObject();
    2502             : 
    2503           0 :     arc->setSize( dObjectSize );
    2504           0 :     arc->stCed = stCommonEntityData;
    2505             : 
    2506           0 :     CADVector vertPosition = buffer.ReadVector();
    2507           0 :     arc->vertPosition = vertPosition;
    2508           0 :     arc->dfRadius     = buffer.ReadBITDOUBLE();
    2509           0 :     arc->dfThickness  = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
    2510             : 
    2511           0 :     if( buffer.ReadBIT() )
    2512             :     {
    2513           0 :         arc->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
    2514             :     }
    2515             :     else
    2516             :     {
    2517           0 :         CADVector vectExtrusion = buffer.ReadVector();
    2518           0 :         arc->vectExtrusion = vectExtrusion;
    2519             :     }
    2520             : 
    2521           0 :     arc->dfStartAngle = buffer.ReadBITDOUBLE();
    2522           0 :     arc->dfEndAngle   = buffer.ReadBITDOUBLE();
    2523             : 
    2524           0 :     fillCommonEntityHandleData( arc, buffer);
    2525             : 
    2526           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2527           0 :     arc->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ARC" ) );
    2528           0 :     return arc;
    2529             : }
    2530             : 
    2531           0 : CADSplineObject * DWGFileR2000::getSpline(unsigned int dObjectSize,
    2532             :                                           const CADCommonED& stCommonEntityData,
    2533             :                                           CADBuffer &buffer)
    2534             : {
    2535           0 :     CADSplineObject * spline = new CADSplineObject();
    2536           0 :     spline->setSize( dObjectSize );
    2537           0 :     spline->stCed     = stCommonEntityData;
    2538           0 :     spline->dScenario = buffer.ReadBITLONG();
    2539           0 :     spline->dDegree   = buffer.ReadBITLONG();
    2540             : 
    2541           0 :     if( spline->dScenario == 2 )
    2542             :     {
    2543           0 :         spline->dfFitTol = buffer.ReadBITDOUBLE();
    2544           0 :         CADVector vectBegTangDir = buffer.ReadVector();
    2545           0 :         spline->vectBegTangDir = vectBegTangDir;
    2546           0 :         CADVector vectEndTangDir = buffer.ReadVector();
    2547           0 :         spline->vectEndTangDir = vectEndTangDir;
    2548             : 
    2549           0 :         spline->nNumFitPts = buffer.ReadBITLONG();
    2550           0 :         if(spline->nNumFitPts < 0 || spline->nNumFitPts > 10 * 1024 * 1024)
    2551             :         {
    2552           0 :             delete spline;
    2553           0 :             return nullptr;
    2554             :         }
    2555           0 :         spline->averFitPoints.reserve( static_cast<size_t>(spline->nNumFitPts) );
    2556             :     }
    2557           0 :     else if( spline->dScenario == 1 )
    2558             :     {
    2559           0 :         spline->bRational = buffer.ReadBIT();
    2560           0 :         spline->bClosed   = buffer.ReadBIT();
    2561           0 :         spline->bPeriodic = buffer.ReadBIT();
    2562           0 :         spline->dfKnotTol = buffer.ReadBITDOUBLE();
    2563           0 :         spline->dfCtrlTol = buffer.ReadBITDOUBLE();
    2564             : 
    2565           0 :         spline->nNumKnots = buffer.ReadBITLONG();
    2566           0 :         if(spline->nNumKnots < 0 || spline->nNumKnots > 10 * 1024 * 1024)
    2567             :         {
    2568           0 :             delete spline;
    2569           0 :             return nullptr;
    2570             :         }
    2571           0 :         spline->adfKnots.reserve( static_cast<size_t>(spline->nNumKnots) );
    2572             : 
    2573           0 :         spline->nNumCtrlPts = buffer.ReadBITLONG();
    2574           0 :         if(spline->nNumCtrlPts < 0 || spline->nNumCtrlPts > 10 * 1024 * 1024)
    2575             :         {
    2576           0 :             delete spline;
    2577           0 :             return nullptr;
    2578             :         }
    2579           0 :         spline->avertCtrlPoints.reserve( static_cast<size_t>(spline->nNumCtrlPts) );
    2580           0 :         if( spline->bWeight )
    2581           0 :             spline->adfCtrlPointsWeight.reserve( static_cast<size_t>(spline->nNumCtrlPts) );
    2582           0 :         spline->bWeight = buffer.ReadBIT();
    2583             :     }
    2584             : #ifdef _DEBUG
    2585             :     else
    2586             :     {
    2587             :         DebugMsg( "Spline scenario != {1,2} read: error." );
    2588             :     }
    2589             : #endif
    2590           0 :     for( long i = 0; i < spline->nNumKnots; ++i )
    2591             :     {
    2592           0 :         spline->adfKnots.push_back( buffer.ReadBITDOUBLE() );
    2593           0 :         if( buffer.IsEOB() )
    2594             :         {
    2595           0 :             delete spline;
    2596           0 :             return nullptr;
    2597             :         }
    2598             :     }
    2599             : 
    2600           0 :     for( long i = 0; i < spline->nNumCtrlPts; ++i )
    2601             :     {
    2602           0 :         CADVector vertex = buffer.ReadVector();
    2603           0 :         spline->avertCtrlPoints.push_back( vertex );
    2604           0 :         if( spline->bWeight )
    2605           0 :             spline->adfCtrlPointsWeight.push_back( buffer.ReadBITDOUBLE() );
    2606           0 :         if( buffer.IsEOB() )
    2607             :         {
    2608           0 :             delete spline;
    2609           0 :             return nullptr;
    2610             :         }
    2611             :     }
    2612             : 
    2613           0 :     for( long i = 0; i < spline->nNumFitPts; ++i )
    2614             :     {
    2615           0 :         CADVector vertex = buffer.ReadVector();
    2616           0 :         if( buffer.IsEOB() )
    2617             :         {
    2618           0 :             delete spline;
    2619           0 :             return nullptr;
    2620             :         }
    2621           0 :         spline->averFitPoints.push_back( vertex );
    2622             :     }
    2623             : 
    2624           0 :     fillCommonEntityHandleData( spline, buffer);
    2625             : 
    2626           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2627           0 :     spline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "SPLINE" ) );
    2628           0 :     return spline;
    2629             : }
    2630             : 
    2631          18 : CADEntityObject * DWGFileR2000::getEntity(int dObjectType,
    2632             :                                           unsigned int dObjectSize,
    2633             :                                           const CADCommonED& stCommonEntityData,
    2634             :                                           CADBuffer &buffer)
    2635             : {
    2636             :     CADEntityObject * entity = new CADEntityObject(
    2637          18 :                     static_cast<CADObject::ObjectType>(dObjectType) );
    2638             : 
    2639          18 :     entity->setSize( dObjectSize );
    2640          18 :     entity->stCed = stCommonEntityData;
    2641             : 
    2642          18 :     buffer.Seek(static_cast<size_t>(
    2643          18 :                     entity->stCed.nObjectSizeInBits + 16), CADBuffer::BEG);
    2644             : 
    2645          18 :     fillCommonEntityHandleData( entity, buffer );
    2646             : 
    2647          18 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2648          18 :     entity->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ENTITY" ) );
    2649          18 :     return entity;
    2650             : }
    2651             : 
    2652           0 : CADInsertObject * DWGFileR2000::getInsert(int dObjectType,
    2653             :                                           unsigned int dObjectSize,
    2654             :                                           const CADCommonED& stCommonEntityData,
    2655             :                                           CADBuffer &buffer)
    2656             : {
    2657             :     CADInsertObject * insert = new CADInsertObject(
    2658           0 :                             static_cast<CADObject::ObjectType>(dObjectType) );
    2659           0 :     insert->setSize( dObjectSize );
    2660           0 :     insert->stCed = stCommonEntityData;
    2661             : 
    2662           0 :     insert->vertInsertionPoint = buffer.ReadVector();
    2663           0 :     unsigned char dataFlags = buffer.Read2B();
    2664           0 :     double        val41     = 1.0;
    2665           0 :     double        val42     = 1.0;
    2666           0 :     double        val43     = 1.0;
    2667           0 :     if( dataFlags == 0 )
    2668             :     {
    2669           0 :         val41 = buffer.ReadRAWDOUBLE();
    2670           0 :         val42 = buffer.ReadBITDOUBLEWD( val41 );
    2671           0 :         val43 = buffer.ReadBITDOUBLEWD( val41 );
    2672             :     }
    2673           0 :     else if( dataFlags == 1 )
    2674             :     {
    2675           0 :         val41 = 1.0;
    2676           0 :         val42 = buffer.ReadBITDOUBLEWD( val41 );
    2677           0 :         val43 = buffer.ReadBITDOUBLEWD( val41 );
    2678             :     }
    2679           0 :     else if( dataFlags == 2 )
    2680             :     {
    2681           0 :         val41 = buffer.ReadRAWDOUBLE();
    2682           0 :         val42 = val41;
    2683           0 :         val43 = val41;
    2684             :     }
    2685           0 :     insert->vertScales    = CADVector( val41, val42, val43 );
    2686           0 :     insert->dfRotation    = buffer.ReadBITDOUBLE();
    2687           0 :     insert->vectExtrusion = buffer.ReadVector();
    2688           0 :     insert->bHasAttribs   = buffer.ReadBIT();
    2689             : 
    2690           0 :     fillCommonEntityHandleData( insert, buffer);
    2691             : 
    2692           0 :     insert->hBlockHeader = buffer.ReadHANDLE();
    2693           0 :     if( insert->bHasAttribs )
    2694             :     {
    2695           0 :         insert->hAttribs.push_back( buffer.ReadHANDLE() );
    2696           0 :         insert->hAttribs.push_back( buffer.ReadHANDLE() );
    2697           0 :         insert->hSeqend = buffer.ReadHANDLE();
    2698             :     }
    2699             : 
    2700           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2701           0 :     insert->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "INSERT" ) );
    2702             : 
    2703           0 :     return insert;
    2704             : }
    2705             : 
    2706         120 : CADDictionaryObject * DWGFileR2000::getDictionary(unsigned int dObjectSize,
    2707             :                                                   CADBuffer &buffer)
    2708             : {
    2709             :     /*
    2710             :      * FIXME: ODA has a lot of mistypes in spec. for this objects,
    2711             :      * it doesn't work for now (error begins in handles stream).
    2712             :      * Nonetheless, dictionary->sItemNames is 100% array,
    2713             :      * not a single obj as pointer by their docs.
    2714             :      */
    2715         120 :     CADDictionaryObject * dictionary = new CADDictionaryObject();
    2716             : 
    2717         120 :     if(!readBasicData(dictionary, dObjectSize, buffer))
    2718             :     {
    2719           0 :         delete dictionary;
    2720           0 :         return nullptr;
    2721             :     }
    2722             : 
    2723         120 :     dictionary->nNumItems      = buffer.ReadBITLONG();
    2724         120 :     if(dictionary->nNumItems < 0)
    2725             :     {
    2726           0 :         delete dictionary;
    2727           0 :         return nullptr;
    2728             :     }
    2729         120 :     dictionary->dCloningFlag   = buffer.ReadBITSHORT();
    2730         120 :     dictionary->dHardOwnerFlag = buffer.ReadCHAR();
    2731             : 
    2732         890 :     for( long i = 0; i < dictionary->nNumItems; ++i )
    2733             :     {
    2734         770 :         dictionary->sItemNames.push_back( buffer.ReadTV() );
    2735         770 :         if( buffer.IsEOB() )
    2736             :         {
    2737           0 :             delete dictionary;
    2738           0 :             return nullptr;
    2739             :         }
    2740             :     }
    2741             : 
    2742         120 :     dictionary->hParentHandle = buffer.ReadHANDLE();
    2743             : 
    2744         232 :     for( long i = 0; i < dictionary->nNumReactors; ++i )
    2745             :     {
    2746         112 :         dictionary->hReactors.push_back( buffer.ReadHANDLE() );
    2747         112 :         if( buffer.IsEOB() )
    2748             :         {
    2749           0 :             delete dictionary;
    2750           0 :             return nullptr;
    2751             :         }
    2752             :     }
    2753         120 :     dictionary->hXDictionary = buffer.ReadHANDLE();
    2754         890 :     for( long i = 0; i < dictionary->nNumItems; ++i )
    2755             :     {
    2756         770 :         dictionary->hItemHandles.push_back( buffer.ReadHANDLE() );
    2757         770 :         if( buffer.IsEOB() )
    2758             :         {
    2759           0 :             delete dictionary;
    2760           0 :             return nullptr;
    2761             :         }
    2762             :     }
    2763             : 
    2764         120 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2765         120 :     dictionary->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DICT" ) );
    2766             : 
    2767         120 :     return dictionary;
    2768             : }
    2769             : 
    2770          10 : CADLayerObject * DWGFileR2000::getLayerObject(unsigned int dObjectSize,
    2771             :                                               CADBuffer &buffer)
    2772             : {
    2773          10 :     CADLayerObject * layer = new CADLayerObject();
    2774             : 
    2775          10 :     if(!readBasicData(layer, dObjectSize, buffer))
    2776             :     {
    2777           0 :         delete layer;
    2778           0 :         return nullptr;
    2779             :     }
    2780             : 
    2781          10 :     layer->sLayerName   = buffer.ReadTV();
    2782          10 :     layer->b64Flag      = buffer.ReadBIT() != 0;
    2783          10 :     layer->dXRefIndex   = buffer.ReadBITSHORT();
    2784          10 :     layer->bXDep        = buffer.ReadBIT() != 0;
    2785             : 
    2786          10 :     short dFlags = buffer.ReadBITSHORT();
    2787          10 :     layer->bFrozen           = (dFlags & 0x01) != 0;
    2788          10 :     layer->bOn               = (dFlags & 0x02) != 0;
    2789          10 :     layer->bFrozenInNewVPORT = (dFlags & 0x04) != 0;
    2790          10 :     layer->bLocked           = (dFlags & 0x08) != 0;
    2791          10 :     layer->bPlottingFlag     = (dFlags & 0x10) != 0;
    2792          10 :     layer->dLineWeight       = dFlags & 0x03E0;
    2793          10 :     layer->dCMColor          = buffer.ReadBITSHORT();
    2794          10 :     layer->hLayerControl     = buffer.ReadHANDLE();
    2795          10 :     for( long i = 0; i < layer->nNumReactors; ++i )
    2796             :     {
    2797           0 :         layer->hReactors.push_back( buffer.ReadHANDLE() );
    2798           0 :         if( buffer.IsEOB() )
    2799             :         {
    2800           0 :             delete layer;
    2801           0 :             return nullptr;
    2802             :         }
    2803             :     }
    2804          10 :     layer->hXDictionary            = buffer.ReadHANDLE();
    2805          10 :     layer->hExternalRefBlockHandle = buffer.ReadHANDLE();
    2806          10 :     layer->hPlotStyle              = buffer.ReadHANDLE();
    2807          10 :     layer->hLType                  = buffer.ReadHANDLE();
    2808             : 
    2809             :     /*
    2810             :      * FIXME: ODA says that this handle should be null hard pointer. It is not.
    2811             :      * Also, after reading it dObjectSize is != actual read structure's size.
    2812             :      * Not used anyway, so no point to read it for now.
    2813             :      * It also means that CRC cannot be computed correctly.
    2814             :      */
    2815             : // layer->hUnknownHandle = ReadHANDLE (pabySectionContent, nBitOffsetFromStart);
    2816             : 
    2817          10 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2818          10 :     layer->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LAYER" ) );
    2819          10 :     return layer;
    2820             : }
    2821             : 
    2822           8 : CADLayerControlObject * DWGFileR2000::getLayerControl(unsigned int dObjectSize,
    2823             :                                                       CADBuffer &buffer)
    2824             : {
    2825           8 :     CADLayerControlObject * layerControl = new CADLayerControlObject();
    2826             : 
    2827           8 :     if(!readBasicData(layerControl, dObjectSize, buffer))
    2828             :     {
    2829           0 :         delete layerControl;
    2830           0 :         return nullptr;
    2831             :     }
    2832             : 
    2833           8 :     layerControl->nNumEntries  = buffer.ReadBITLONG();
    2834           8 :     if(layerControl->nNumEntries < 0)
    2835             :     {
    2836           0 :         delete layerControl;
    2837           0 :         return nullptr;
    2838             :     }
    2839           8 :     layerControl->hNull        = buffer.ReadHANDLE();
    2840           8 :     layerControl->hXDictionary = buffer.ReadHANDLE();
    2841          18 :     for( long i = 0; i < layerControl->nNumEntries; ++i )
    2842             :     {
    2843          10 :         layerControl->hLayers.push_back( buffer.ReadHANDLE() );
    2844          10 :         if( buffer.IsEOB() )
    2845             :         {
    2846           0 :             delete layerControl;
    2847           0 :             return nullptr;
    2848             :         }
    2849             :     }
    2850             : 
    2851           8 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2852           8 :     layerControl->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LAYERCONTROL" ) );
    2853           8 :     return layerControl;
    2854             : }
    2855             : 
    2856           0 : CADBlockControlObject * DWGFileR2000::getBlockControl(unsigned int dObjectSize,
    2857             :                                                       CADBuffer &buffer)
    2858             : {
    2859           0 :     CADBlockControlObject * blockControl = new CADBlockControlObject();
    2860             : 
    2861           0 :     if(!readBasicData(blockControl, dObjectSize, buffer))
    2862             :     {
    2863           0 :         delete blockControl;
    2864           0 :         return nullptr;
    2865             :     }
    2866             : 
    2867           0 :     blockControl->nNumEntries  = buffer.ReadBITLONG();
    2868           0 :     if(blockControl->nNumEntries < 0)
    2869             :     {
    2870           0 :         delete blockControl;
    2871           0 :         return nullptr;
    2872             :     }
    2873             : 
    2874           0 :     blockControl->hNull        = buffer.ReadHANDLE();
    2875           0 :     blockControl->hXDictionary = buffer.ReadHANDLE();
    2876             : 
    2877           0 :     for( long i = 0; i < blockControl->nNumEntries + 2; ++i )
    2878             :     {
    2879           0 :         blockControl->hBlocks.push_back( buffer.ReadHANDLE() );
    2880           0 :         if( buffer.IsEOB() )
    2881             :         {
    2882           0 :             delete blockControl;
    2883           0 :             return nullptr;
    2884             :         }
    2885             :     }
    2886             : 
    2887           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2888           0 :     blockControl->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "BLOCKCONTROL" ) );
    2889           0 :     return blockControl;
    2890             : }
    2891             : 
    2892           8 : CADBlockHeaderObject * DWGFileR2000::getBlockHeader(unsigned int dObjectSize,
    2893             :                                                     CADBuffer &buffer)
    2894             : {
    2895           8 :     CADBlockHeaderObject * blockHeader = new CADBlockHeaderObject();
    2896             : 
    2897           8 :     if(!readBasicData(blockHeader, dObjectSize, buffer))
    2898             :     {
    2899           0 :         delete blockHeader;
    2900           0 :         return nullptr;
    2901             :     }
    2902             : 
    2903           8 :     blockHeader->sEntryName    = buffer.ReadTV();
    2904           8 :     blockHeader->b64Flag       = buffer.ReadBIT();
    2905           8 :     blockHeader->dXRefIndex    = buffer.ReadBITSHORT();
    2906           8 :     blockHeader->bXDep         = buffer.ReadBIT();
    2907           8 :     blockHeader->bAnonymous    = buffer.ReadBIT();
    2908           8 :     blockHeader->bHasAtts      = buffer.ReadBIT();
    2909           8 :     blockHeader->bBlkisXRef    = buffer.ReadBIT();
    2910           8 :     blockHeader->bXRefOverlaid = buffer.ReadBIT();
    2911           8 :     blockHeader->bLoadedBit    = buffer.ReadBIT();
    2912             : 
    2913           8 :     CADVector vertBasePoint = buffer.ReadVector();
    2914           8 :     blockHeader->vertBasePoint = vertBasePoint;
    2915           8 :     blockHeader->sXRefPName    = buffer.ReadTV();
    2916             :     unsigned char Tmp;
    2917           0 :     do
    2918             :     {
    2919           8 :         Tmp = buffer.ReadCHAR();
    2920           8 :         blockHeader->adInsertCount.push_back( Tmp );
    2921           8 :     } while( Tmp != 0 );
    2922             : 
    2923           8 :     blockHeader->sBlockDescription  = buffer.ReadTV();
    2924           8 :     blockHeader->nSizeOfPreviewData = buffer.ReadBITLONG();
    2925           8 :     if(blockHeader->nSizeOfPreviewData < 0)
    2926             :     {
    2927           0 :         delete blockHeader;
    2928           0 :         return nullptr;
    2929             :     }
    2930           8 :     for( long i = 0; i < blockHeader->nSizeOfPreviewData; ++i )
    2931             :     {
    2932           0 :         blockHeader->abyBinaryPreviewData.push_back( buffer.ReadCHAR() );
    2933           0 :         if( buffer.IsEOB() )
    2934             :         {
    2935           0 :             delete blockHeader;
    2936           0 :             return nullptr;
    2937             :         }
    2938             :     }
    2939             : 
    2940           8 :     blockHeader->hBlockControl = buffer.ReadHANDLE();
    2941           8 :     for( long i = 0; i < blockHeader->nNumReactors; ++i )
    2942             :     {
    2943           0 :         blockHeader->hReactors.push_back( buffer.ReadHANDLE() );
    2944           0 :         if( buffer.IsEOB() )
    2945             :         {
    2946           0 :             delete blockHeader;
    2947           0 :             return nullptr;
    2948             :         }
    2949             :     }
    2950           8 :     blockHeader->hXDictionary = buffer.ReadHANDLE();
    2951           8 :     blockHeader->hNull        = buffer.ReadHANDLE();
    2952           8 :     blockHeader->hBlockEntity = buffer.ReadHANDLE();
    2953           8 :     if( !blockHeader->bBlkisXRef && !blockHeader->bXRefOverlaid )
    2954             :     {
    2955           8 :         blockHeader->hEntities.push_back( buffer.ReadHANDLE() ); // first
    2956           8 :         blockHeader->hEntities.push_back( buffer.ReadHANDLE() ); // last
    2957             :     }
    2958             : 
    2959           8 :     blockHeader->hEndBlk = buffer.ReadHANDLE();
    2960           8 :     for( size_t i = 0; i < blockHeader->adInsertCount.size() - 1; ++i )
    2961           0 :         blockHeader->hInsertHandles.push_back( buffer.ReadHANDLE() );
    2962           8 :     blockHeader->hLayout = buffer.ReadHANDLE();
    2963             : 
    2964           8 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    2965           8 :     blockHeader->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "BLOCKHEADER" ) );
    2966           8 :     return blockHeader;
    2967             : }
    2968             : 
    2969           0 : CADLineTypeControlObject * DWGFileR2000::getLineTypeControl(unsigned int dObjectSize,
    2970             :                                                             CADBuffer &buffer)
    2971             : {
    2972           0 :     CADLineTypeControlObject * ltypeControl = new CADLineTypeControlObject();
    2973             : 
    2974           0 :     if(!readBasicData(ltypeControl, dObjectSize, buffer))
    2975             :     {
    2976           0 :         delete ltypeControl;
    2977           0 :         return nullptr;
    2978             :     }
    2979             : 
    2980           0 :     ltypeControl->nNumEntries  = buffer.ReadBITLONG();
    2981           0 :     if(ltypeControl->nNumEntries < 0)
    2982             :     {
    2983           0 :         delete ltypeControl;
    2984           0 :         return nullptr;
    2985             :     }
    2986             : 
    2987           0 :     ltypeControl->hNull        = buffer.ReadHANDLE();
    2988           0 :     ltypeControl->hXDictionary = buffer.ReadHANDLE();
    2989             : 
    2990             :     // hLTypes ends with BYLAYER and BYBLOCK
    2991           0 :     for( long i = 0; i < ltypeControl->nNumEntries + 2; ++i )
    2992             :     {
    2993           0 :         ltypeControl->hLTypes.push_back( buffer.ReadHANDLE() );
    2994           0 :         if( buffer.IsEOB() )
    2995             :         {
    2996           0 :             delete ltypeControl;
    2997           0 :             return nullptr;
    2998             :         }
    2999             :     }
    3000             : 
    3001           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3002           0 :     ltypeControl->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LINETYPECTRL" ) );
    3003           0 :     return ltypeControl;
    3004             : }
    3005             : 
    3006           0 : CADLineTypeObject * DWGFileR2000::getLineType1(unsigned int dObjectSize, CADBuffer &buffer)
    3007             : {
    3008           0 :     CADLineTypeObject * ltype = new CADLineTypeObject();
    3009             : 
    3010           0 :     if(!readBasicData(ltype, dObjectSize, buffer))
    3011             :     {
    3012           0 :         delete ltype;
    3013           0 :         return nullptr;
    3014             :     }
    3015             : 
    3016           0 :     ltype->sEntryName   = buffer.ReadTV();
    3017           0 :     ltype->b64Flag      = buffer.ReadBIT();
    3018           0 :     ltype->dXRefIndex   = buffer.ReadBITSHORT();
    3019           0 :     ltype->bXDep        = buffer.ReadBIT();
    3020           0 :     ltype->sDescription = buffer.ReadTV();
    3021           0 :     ltype->dfPatternLen = buffer.ReadBITDOUBLE();
    3022           0 :     ltype->dAlignment   = buffer.ReadCHAR();
    3023           0 :     ltype->nNumDashes   = buffer.ReadCHAR();
    3024             : 
    3025             :     CADDash     dash;
    3026           0 :     for( size_t i = 0; i < ltype->nNumDashes; ++i )
    3027             :     {
    3028           0 :         dash.dfLength          = buffer.ReadBITDOUBLE();
    3029           0 :         dash.dComplexShapecode = buffer.ReadBITSHORT();
    3030           0 :         dash.dfXOffset         = buffer.ReadRAWDOUBLE();
    3031           0 :         dash.dfYOffset         = buffer.ReadRAWDOUBLE();
    3032           0 :         dash.dfScale           = buffer.ReadBITDOUBLE();
    3033           0 :         dash.dfRotation        = buffer.ReadBITDOUBLE();
    3034           0 :         dash.dShapeflag        = buffer.ReadBITSHORT(); // TODO: what to do with it?
    3035             : 
    3036           0 :         ltype->astDashes.push_back( dash );
    3037             :     }
    3038             : 
    3039           0 :     for( short i = 0; i < 256; ++i )
    3040           0 :         ltype->abyTextArea.push_back( buffer.ReadCHAR() );
    3041             : 
    3042           0 :     ltype->hLTControl = buffer.ReadHANDLE();
    3043             : 
    3044           0 :     for( long i = 0; i < ltype->nNumReactors; ++i )
    3045             :     {
    3046           0 :         ltype->hReactors.push_back( buffer.ReadHANDLE() );
    3047           0 :         if( buffer.IsEOB() )
    3048             :         {
    3049           0 :             delete ltype;
    3050           0 :             return nullptr;
    3051             :         }
    3052             :     }
    3053             : 
    3054           0 :     ltype->hXDictionary = buffer.ReadHANDLE();
    3055           0 :     ltype->hXRefBlock   = buffer.ReadHANDLE();
    3056             : 
    3057             :     // TODO: shapefile for dash/shape (1 each). Does it mean that we have nNumDashes * 2 handles, or what?
    3058             : 
    3059           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3060           0 :     ltype->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LINETYPE" ) );
    3061           0 :     return ltype;
    3062             : }
    3063             : 
    3064           0 : CADMLineObject * DWGFileR2000::getMLine(unsigned int dObjectSize,
    3065             :                                         const CADCommonED& stCommonEntityData,
    3066             :                                         CADBuffer &buffer)
    3067             : {
    3068           0 :     CADMLineObject * mline = new CADMLineObject();
    3069             : 
    3070           0 :     mline->setSize( dObjectSize );
    3071           0 :     mline->stCed = stCommonEntityData;
    3072             : 
    3073           0 :     mline->dfScale = buffer.ReadBITDOUBLE();
    3074           0 :     mline->dJust   = buffer.ReadCHAR();
    3075             : 
    3076           0 :     CADVector vertBasePoint = buffer.ReadVector();
    3077           0 :     mline->vertBasePoint = vertBasePoint;
    3078             : 
    3079           0 :     CADVector vectExtrusion = buffer.ReadVector();
    3080           0 :     mline->vectExtrusion = vectExtrusion;
    3081           0 :     mline->dOpenClosed   = buffer.ReadBITSHORT();
    3082           0 :     mline->nLinesInStyle = buffer.ReadCHAR();
    3083           0 :     mline->nNumVertices  = buffer.ReadBITSHORT();
    3084           0 :     if(mline->nNumVertices < 0)
    3085             :     {
    3086           0 :         delete mline;
    3087           0 :         return nullptr;
    3088             :     }
    3089             : 
    3090           0 :     for( short i = 0; i < mline->nNumVertices; ++i )
    3091             :     {
    3092           0 :         CADMLineVertex stVertex;
    3093             : 
    3094           0 :         CADVector vertPosition = buffer.ReadVector();
    3095           0 :         stVertex.vertPosition = vertPosition;
    3096             : 
    3097           0 :         CADVector vectDirection = buffer.ReadVector();
    3098           0 :         stVertex.vectDirection = vectDirection;
    3099             : 
    3100           0 :         CADVector vectMIterDirection = buffer.ReadVector();
    3101           0 :         stVertex.vectMIterDirection = vectMIterDirection;
    3102           0 :         if( buffer.IsEOB() )
    3103             :         {
    3104           0 :             delete mline;
    3105           0 :             return nullptr;
    3106             :         }
    3107           0 :         for( unsigned char j = 0; j < mline->nLinesInStyle; ++j )
    3108             :         {
    3109           0 :             CADLineStyle   stLStyle;
    3110           0 :             stLStyle.nNumSegParams = buffer.ReadBITSHORT();
    3111           0 :             if( stLStyle.nNumSegParams > 0 ) // Or return null here?
    3112             :             {
    3113           0 :                 for( short k = 0; k < stLStyle.nNumSegParams; ++k )
    3114           0 :                     stLStyle.adfSegparms.push_back( buffer.ReadBITDOUBLE() );
    3115             :             }
    3116           0 :             stLStyle.nAreaFillParams = buffer.ReadBITSHORT();
    3117           0 :             if( stLStyle.nAreaFillParams > 0 )
    3118             :             {
    3119           0 :                 for( short k = 0; k < stLStyle.nAreaFillParams; ++k )
    3120           0 :                     stLStyle.adfAreaFillParameters.push_back( buffer.ReadBITDOUBLE() );
    3121             :             }
    3122             : 
    3123           0 :             stVertex.astLStyles.push_back( stLStyle );
    3124           0 :             if( buffer.IsEOB() )
    3125             :             {
    3126           0 :                 delete mline;
    3127           0 :                 return nullptr;
    3128             :             }
    3129             :         }
    3130           0 :         mline->avertVertices.push_back( stVertex );
    3131             :     }
    3132             : 
    3133           0 :     if( mline->stCed.bbEntMode == 0 )
    3134           0 :         mline->stChed.hOwner = buffer.ReadHANDLE();
    3135             : 
    3136           0 :     for( long i = 0; i < mline->stCed.nNumReactors; ++i )
    3137           0 :         mline->stChed.hReactors.push_back( buffer.ReadHANDLE() );
    3138             : 
    3139           0 :     mline->stChed.hXDictionary = buffer.ReadHANDLE();
    3140             : 
    3141           0 :     if( !mline->stCed.bNoLinks )
    3142             :     {
    3143           0 :         mline->stChed.hPrevEntity = buffer.ReadHANDLE();
    3144           0 :         mline->stChed.hNextEntity = buffer.ReadHANDLE();
    3145             :     }
    3146             : 
    3147           0 :     mline->stChed.hLayer = buffer.ReadHANDLE();
    3148             : 
    3149           0 :     if( mline->stCed.bbLTypeFlags == 0x03 )
    3150           0 :         mline->stChed.hLType = buffer.ReadHANDLE();
    3151             : 
    3152           0 :     if( mline->stCed.bbPlotStyleFlags == 0x03 )
    3153           0 :         mline->stChed.hPlotStyle = buffer.ReadHANDLE();
    3154             : 
    3155           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3156           0 :     mline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "MLINE" ) );
    3157           0 :     return mline;
    3158             : }
    3159             : 
    3160           0 : CADPolylinePFaceObject * DWGFileR2000::getPolylinePFace(unsigned int dObjectSize,
    3161             :                                                         const CADCommonED& stCommonEntityData,
    3162             :                                                         CADBuffer &buffer)
    3163             : {
    3164           0 :     CADPolylinePFaceObject * polyline = new CADPolylinePFaceObject();
    3165             : 
    3166           0 :     polyline->setSize( dObjectSize );
    3167           0 :     polyline->stCed = stCommonEntityData;
    3168             : 
    3169           0 :     polyline->nNumVertices = buffer.ReadBITSHORT();
    3170           0 :     polyline->nNumFaces    = buffer.ReadBITSHORT();
    3171             : 
    3172           0 :     fillCommonEntityHandleData( polyline, buffer);
    3173             : 
    3174           0 :     polyline->hVertices.push_back( buffer.ReadHANDLE() ); // 1st vertex
    3175           0 :     polyline->hVertices.push_back( buffer.ReadHANDLE() ); // last vertex
    3176             : 
    3177           0 :     polyline->hSeqend = buffer.ReadHANDLE();
    3178             : 
    3179           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3180           0 :     polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POLYLINEPFACE" ) );
    3181           0 :     return polyline;
    3182             : }
    3183             : 
    3184           0 : CADImageObject * DWGFileR2000::getImage(unsigned int dObjectSize,
    3185             :                                         const CADCommonED& stCommonEntityData,
    3186             :                                         CADBuffer &buffer)
    3187             : {
    3188           0 :     CADImageObject * image = new CADImageObject();
    3189             : 
    3190           0 :     image->setSize( dObjectSize );
    3191           0 :     image->stCed = stCommonEntityData;
    3192             : 
    3193           0 :     image->dClassVersion = buffer.ReadBITLONG();
    3194             : 
    3195           0 :     CADVector vertInsertion = buffer.ReadVector();
    3196           0 :     image->vertInsertion = vertInsertion;
    3197             : 
    3198           0 :     CADVector vectUDirection = buffer.ReadVector();
    3199           0 :     image->vectUDirection = vectUDirection;
    3200             : 
    3201           0 :     CADVector vectVDirection = buffer.ReadVector();
    3202           0 :     image->vectVDirection = vectVDirection;
    3203             : 
    3204           0 :     image->dfSizeX       = buffer.ReadRAWDOUBLE();
    3205           0 :     image->dfSizeY       = buffer.ReadRAWDOUBLE();
    3206           0 :     image->dDisplayProps = buffer.ReadBITSHORT();
    3207             : 
    3208           0 :     image->bClipping         = buffer.ReadBIT();
    3209           0 :     image->dBrightness       = buffer.ReadCHAR();
    3210           0 :     image->dContrast         = buffer.ReadCHAR();
    3211           0 :     image->dFade             = buffer.ReadCHAR();
    3212           0 :     image->dClipBoundaryType = buffer.ReadBITSHORT();
    3213             : 
    3214           0 :     if( image->dClipBoundaryType == 1 )
    3215             :     {
    3216           0 :         CADVector vertPoint1 = buffer.ReadRAWVector();
    3217           0 :         image->avertClippingPolygonVertices.push_back( vertPoint1 );
    3218             : 
    3219           0 :         CADVector vertPoint2 = buffer.ReadRAWVector();
    3220           0 :         image->avertClippingPolygonVertices.push_back( vertPoint2 );
    3221             :     }
    3222             :     else
    3223             :     {
    3224           0 :         image->nNumberVerticesInClipPolygon = buffer.ReadBITLONG();
    3225           0 :         if(image->nNumberVerticesInClipPolygon < 0)
    3226             :         {
    3227           0 :             delete image;
    3228           0 :             return nullptr;
    3229             :         }
    3230             : 
    3231           0 :         for( long i = 0; i < image->nNumberVerticesInClipPolygon; ++i )
    3232             :         {
    3233           0 :             CADVector vertPoint = buffer.ReadRAWVector();
    3234           0 :             if( buffer.IsEOB() )
    3235             :             {
    3236           0 :                 delete image;
    3237           0 :                 return nullptr;
    3238             :             }
    3239           0 :             image->avertClippingPolygonVertices.push_back( vertPoint );
    3240             :         }
    3241             :     }
    3242             : 
    3243           0 :     fillCommonEntityHandleData( image, buffer);
    3244             : 
    3245           0 :     image->hImageDef        = buffer.ReadHANDLE();
    3246           0 :     image->hImageDefReactor = buffer.ReadHANDLE();
    3247             : 
    3248           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3249           0 :     image->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "IMAGE" ) );
    3250             : 
    3251           0 :     return image;
    3252             : }
    3253             : 
    3254           0 : CAD3DFaceObject * DWGFileR2000::get3DFace(unsigned int dObjectSize,
    3255             :                                           const CADCommonED& stCommonEntityData,
    3256             :                                           CADBuffer &buffer)
    3257             : {
    3258           0 :     CAD3DFaceObject * face = new CAD3DFaceObject();
    3259             : 
    3260           0 :     face->setSize( dObjectSize );
    3261           0 :     face->stCed = stCommonEntityData;
    3262             : 
    3263           0 :     face->bHasNoFlagInd = buffer.ReadBIT();
    3264           0 :     face->bZZero        = buffer.ReadBIT();
    3265             : 
    3266             :     double x, y, z;
    3267             : 
    3268           0 :     CADVector vertex = buffer.ReadRAWVector();
    3269           0 :     if( !face->bZZero )
    3270             :     {
    3271           0 :         z = buffer.ReadRAWDOUBLE();
    3272           0 :         vertex.setZ( z );
    3273             :     }
    3274           0 :     face->avertCorners.push_back( vertex );
    3275           0 :     for( size_t i = 1; i < 4; ++i )
    3276             :     {
    3277           0 :         x = buffer.ReadBITDOUBLEWD( face->avertCorners[i - 1].getX() );
    3278           0 :         y = buffer.ReadBITDOUBLEWD( face->avertCorners[i - 1].getY() );
    3279           0 :         z = buffer.ReadBITDOUBLEWD( face->avertCorners[i - 1].getZ() );
    3280             : 
    3281           0 :         CADVector corner( x, y, z );
    3282           0 :         face->avertCorners.push_back( corner );
    3283             :     }
    3284             : 
    3285           0 :     if( !face->bHasNoFlagInd )
    3286           0 :         face->dInvisFlags = buffer.ReadBITSHORT();
    3287             : 
    3288           0 :     fillCommonEntityHandleData( face, buffer);
    3289             : 
    3290           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3291           0 :     face->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "3DFACE" ) );
    3292           0 :     return face;
    3293             : }
    3294             : 
    3295           0 : CADVertexMeshObject * DWGFileR2000::getVertexMesh(unsigned int dObjectSize,
    3296             :                                                   const CADCommonED& stCommonEntityData,
    3297             :                                                   CADBuffer &buffer)
    3298             : {
    3299           0 :     CADVertexMeshObject * vertex = new CADVertexMeshObject();
    3300             : 
    3301           0 :     vertex->setSize( dObjectSize );
    3302           0 :     vertex->stCed = stCommonEntityData;
    3303             : 
    3304           0 :     /*unsigned char Flags = */buffer.ReadCHAR();
    3305           0 :     CADVector vertPosition = buffer.ReadVector();
    3306           0 :     vertex->vertPosition = vertPosition;
    3307             : 
    3308           0 :     fillCommonEntityHandleData( vertex, buffer);
    3309             : 
    3310           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3311           0 :     vertex->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "VERTEXMESH" ) );
    3312           0 :     return vertex;
    3313             : }
    3314             : 
    3315           0 : CADVertexPFaceObject * DWGFileR2000::getVertexPFace(unsigned int dObjectSize,
    3316             :                                                     const CADCommonED& stCommonEntityData,
    3317             :                                                     CADBuffer &buffer)
    3318             : {
    3319           0 :     CADVertexPFaceObject * vertex = new CADVertexPFaceObject();
    3320             : 
    3321           0 :     vertex->setSize( dObjectSize );
    3322           0 :     vertex->stCed = stCommonEntityData;
    3323             : 
    3324           0 :     /*unsigned char Flags = */buffer.ReadCHAR();
    3325           0 :     CADVector vertPosition = buffer.ReadVector();
    3326           0 :     vertex->vertPosition = vertPosition;
    3327             : 
    3328           0 :     fillCommonEntityHandleData( vertex, buffer);
    3329             : 
    3330           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3331           0 :     vertex->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "VERTEXPFACE" ) );
    3332           0 :     return vertex;
    3333             : }
    3334             : 
    3335           2 : CADMTextObject * DWGFileR2000::getMText(unsigned int dObjectSize,
    3336             :                                         const CADCommonED& stCommonEntityData,
    3337             :                                         CADBuffer &buffer)
    3338             : {
    3339           2 :     CADMTextObject * text = new CADMTextObject();
    3340             : 
    3341           2 :     text->setSize( dObjectSize );
    3342           2 :     text->stCed = stCommonEntityData;
    3343             : 
    3344           2 :     CADVector vertInsertionPoint = buffer.ReadVector();
    3345           2 :     text->vertInsertionPoint = vertInsertionPoint;
    3346             : 
    3347           2 :     CADVector vectExtrusion = buffer.ReadVector();
    3348           2 :     text->vectExtrusion = vectExtrusion;
    3349             : 
    3350           2 :     CADVector vectXAxisDir = buffer.ReadVector();
    3351           2 :     text->vectXAxisDir = vectXAxisDir;
    3352             : 
    3353           2 :     text->dfRectWidth        = buffer.ReadBITDOUBLE();
    3354           2 :     text->dfTextHeight       = buffer.ReadBITDOUBLE();
    3355           2 :     text->dAttachment        = buffer.ReadBITSHORT();
    3356           2 :     text->dDrawingDir        = buffer.ReadBITSHORT();
    3357           2 :     text->dfExtents          = buffer.ReadBITDOUBLE();
    3358           2 :     text->dfExtentsWidth     = buffer.ReadBITDOUBLE();
    3359           2 :     text->sTextValue         = buffer.ReadTV();
    3360           2 :     text->dLineSpacingStyle  = buffer.ReadBITSHORT();
    3361           2 :     text->dLineSpacingFactor = buffer.ReadBITDOUBLE();
    3362           2 :     text->bUnknownBit        = buffer.ReadBIT();
    3363             : 
    3364           2 :     fillCommonEntityHandleData( text, buffer);
    3365             : 
    3366           2 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3367           2 :     text->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "MTEXT" ) );
    3368           2 :     return text;
    3369             : }
    3370             : 
    3371           0 : CADDimensionObject * DWGFileR2000::getDimension(short dObjectType,
    3372             :                                                 unsigned int dObjectSize,
    3373             :                                                 const CADCommonED& stCommonEntityData,
    3374             :                                                 CADBuffer &buffer)
    3375             : {
    3376           0 :     CADCommonDimensionData stCDD;
    3377             : 
    3378           0 :     CADVector vectExtrusion = buffer.ReadVector();
    3379           0 :     stCDD.vectExtrusion = vectExtrusion;
    3380             : 
    3381           0 :     CADVector vertTextMidPt = buffer.ReadRAWVector();
    3382           0 :     stCDD.vertTextMidPt = vertTextMidPt;
    3383             : 
    3384           0 :     stCDD.dfElevation = buffer.ReadBITDOUBLE();
    3385           0 :     stCDD.dFlags      = buffer.ReadCHAR();
    3386             : 
    3387           0 :     stCDD.sUserText      = buffer.ReadTV();
    3388           0 :     stCDD.dfTextRotation = buffer.ReadBITDOUBLE();
    3389           0 :     stCDD.dfHorizDir     = buffer.ReadBITDOUBLE();
    3390             : 
    3391           0 :     stCDD.dfInsXScale   = buffer.ReadBITDOUBLE();
    3392           0 :     stCDD.dfInsYScale   = buffer.ReadBITDOUBLE();
    3393           0 :     stCDD.dfInsZScale   = buffer.ReadBITDOUBLE();
    3394           0 :     stCDD.dfInsRotation = buffer.ReadBITDOUBLE();
    3395             : 
    3396           0 :     stCDD.dAttachmentPoint    = buffer.ReadBITSHORT();
    3397           0 :     stCDD.dLineSpacingStyle   = buffer.ReadBITSHORT();
    3398           0 :     stCDD.dfLineSpacingFactor = buffer.ReadBITDOUBLE();
    3399           0 :     stCDD.dfActualMeasurement = buffer.ReadBITDOUBLE();
    3400             : 
    3401           0 :     CADVector vert12Pt = buffer.ReadRAWVector();
    3402           0 :     stCDD.vert12Pt = vert12Pt;
    3403             : 
    3404           0 :     switch( dObjectType )
    3405             :     {
    3406           0 :         case CADObject::DIMENSION_ORDINATE:
    3407             :         {
    3408           0 :             CADDimensionOrdinateObject * dimension = new CADDimensionOrdinateObject();
    3409             : 
    3410           0 :             dimension->setSize( dObjectSize );
    3411           0 :             dimension->stCed = stCommonEntityData;
    3412           0 :             dimension->cdd   = std::move(stCDD);
    3413             : 
    3414           0 :             CADVector vert10pt = buffer.ReadVector();
    3415           0 :             dimension->vert10pt = vert10pt;
    3416             : 
    3417           0 :             CADVector vert13pt = buffer.ReadVector();
    3418           0 :             dimension->vert13pt = vert13pt;
    3419             : 
    3420           0 :             CADVector vert14pt = buffer.ReadVector();
    3421           0 :             dimension->vert14pt = vert14pt;
    3422             : 
    3423           0 :             dimension->Flags2 = buffer.ReadCHAR();
    3424             : 
    3425           0 :             fillCommonEntityHandleData( dimension, buffer);
    3426             : 
    3427           0 :             dimension->hDimstyle       = buffer.ReadHANDLE();
    3428           0 :             dimension->hAnonymousBlock = buffer.ReadHANDLE();
    3429             : 
    3430           0 :             buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3431           0 :             dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
    3432           0 :             return dimension;
    3433             :         }
    3434             : 
    3435           0 :         case CADObject::DIMENSION_LINEAR:
    3436             :         {
    3437           0 :             CADDimensionLinearObject * dimension = new CADDimensionLinearObject();
    3438             : 
    3439           0 :             dimension->setSize( dObjectSize );
    3440           0 :             dimension->stCed = stCommonEntityData;
    3441           0 :             dimension->cdd   = std::move(stCDD);
    3442             : 
    3443           0 :             CADVector vert13pt = buffer.ReadVector();
    3444           0 :             dimension->vert13pt = vert13pt;
    3445             : 
    3446           0 :             CADVector vert14pt = buffer.ReadVector();
    3447           0 :             dimension->vert14pt = vert14pt;
    3448             : 
    3449           0 :             CADVector vert10pt = buffer.ReadVector();
    3450           0 :             dimension->vert10pt = vert10pt;
    3451             : 
    3452           0 :             dimension->dfExtLnRot = buffer.ReadBITDOUBLE();
    3453           0 :             dimension->dfDimRot   = buffer.ReadBITDOUBLE();
    3454             : 
    3455           0 :             fillCommonEntityHandleData( dimension, buffer);
    3456             : 
    3457           0 :             dimension->hDimstyle       = buffer.ReadHANDLE();
    3458           0 :             dimension->hAnonymousBlock = buffer.ReadHANDLE();
    3459             : 
    3460           0 :             buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3461           0 :             dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
    3462           0 :             return dimension;
    3463             :         }
    3464             : 
    3465           0 :         case CADObject::DIMENSION_ALIGNED:
    3466             :         {
    3467           0 :             CADDimensionAlignedObject * dimension = new CADDimensionAlignedObject();
    3468             : 
    3469           0 :             dimension->setSize( dObjectSize );
    3470           0 :             dimension->stCed = stCommonEntityData;
    3471           0 :             dimension->cdd   = std::move(stCDD);
    3472             : 
    3473           0 :             CADVector vert13pt = buffer.ReadVector();
    3474           0 :             dimension->vert13pt = vert13pt;
    3475             : 
    3476           0 :             CADVector vert14pt = buffer.ReadVector();
    3477           0 :             dimension->vert14pt = vert14pt;
    3478             : 
    3479           0 :             CADVector vert10pt = buffer.ReadVector();
    3480           0 :             dimension->vert10pt = vert10pt;
    3481             : 
    3482           0 :             dimension->dfExtLnRot = buffer.ReadBITDOUBLE();
    3483             : 
    3484           0 :             fillCommonEntityHandleData( dimension, buffer);
    3485             : 
    3486           0 :             dimension->hDimstyle       = buffer.ReadHANDLE();
    3487           0 :             dimension->hAnonymousBlock = buffer.ReadHANDLE();
    3488             : 
    3489           0 :             buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3490           0 :             dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
    3491           0 :             return dimension;
    3492             :         }
    3493             : 
    3494           0 :         case CADObject::DIMENSION_ANG_3PT:
    3495             :         {
    3496           0 :             CADDimensionAngular3PtObject * dimension = new CADDimensionAngular3PtObject();
    3497             : 
    3498           0 :             dimension->setSize( dObjectSize );
    3499           0 :             dimension->stCed = stCommonEntityData;
    3500           0 :             dimension->cdd   = std::move(stCDD);
    3501             : 
    3502           0 :             CADVector vert10pt = buffer.ReadVector();
    3503           0 :             dimension->vert10pt = vert10pt;
    3504             : 
    3505           0 :             CADVector vert13pt = buffer.ReadVector();
    3506           0 :             dimension->vert13pt = vert13pt;
    3507             : 
    3508           0 :             CADVector vert14pt = buffer.ReadVector();
    3509           0 :             dimension->vert14pt = vert14pt;
    3510             : 
    3511           0 :             CADVector vert15pt = buffer.ReadVector();
    3512           0 :             dimension->vert15pt = vert15pt;
    3513             : 
    3514           0 :             fillCommonEntityHandleData( dimension, buffer );
    3515             : 
    3516           0 :             dimension->hDimstyle       = buffer.ReadHANDLE();
    3517           0 :             dimension->hAnonymousBlock = buffer.ReadHANDLE();
    3518             : 
    3519           0 :             buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3520           0 :             dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
    3521           0 :             return dimension;
    3522             :         }
    3523             : 
    3524           0 :         case CADObject::DIMENSION_ANG_2LN:
    3525             :         {
    3526           0 :             CADDimensionAngular2LnObject * dimension = new CADDimensionAngular2LnObject();
    3527             : 
    3528           0 :             dimension->setSize( dObjectSize );
    3529           0 :             dimension->stCed = stCommonEntityData;
    3530           0 :             dimension->cdd   = std::move(stCDD);
    3531             : 
    3532           0 :             CADVector vert16pt = buffer.ReadVector();
    3533           0 :             dimension->vert16pt = vert16pt;
    3534             : 
    3535           0 :             CADVector vert13pt = buffer.ReadVector();
    3536           0 :             dimension->vert13pt = vert13pt;
    3537             : 
    3538           0 :             CADVector vert14pt = buffer.ReadVector();
    3539           0 :             dimension->vert14pt = vert14pt;
    3540             : 
    3541           0 :             CADVector vert15pt = buffer.ReadVector();
    3542           0 :             dimension->vert15pt = vert15pt;
    3543             : 
    3544           0 :             CADVector vert10pt = buffer.ReadVector();
    3545           0 :             dimension->vert10pt = vert10pt;
    3546             : 
    3547           0 :             fillCommonEntityHandleData( dimension, buffer);
    3548             : 
    3549           0 :             dimension->hDimstyle       = buffer.ReadHANDLE();
    3550           0 :             dimension->hAnonymousBlock = buffer.ReadHANDLE();
    3551             : 
    3552           0 :             buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3553           0 :             dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
    3554           0 :             return dimension;
    3555             :         }
    3556             : 
    3557           0 :         case CADObject::DIMENSION_RADIUS:
    3558             :         {
    3559           0 :             CADDimensionRadiusObject * dimension = new CADDimensionRadiusObject();
    3560             : 
    3561           0 :             dimension->setSize( dObjectSize );
    3562           0 :             dimension->stCed = stCommonEntityData;
    3563           0 :             dimension->cdd   = std::move(stCDD);
    3564             : 
    3565           0 :             CADVector vert10pt = buffer.ReadVector();
    3566           0 :             dimension->vert10pt = vert10pt;
    3567             : 
    3568           0 :             CADVector vert15pt = buffer.ReadVector();
    3569           0 :             dimension->vert15pt = vert15pt;
    3570             : 
    3571           0 :             dimension->dfLeaderLen = buffer.ReadBITDOUBLE();
    3572             : 
    3573           0 :             fillCommonEntityHandleData( dimension, buffer);
    3574             : 
    3575           0 :             dimension->hDimstyle       = buffer.ReadHANDLE();
    3576           0 :             dimension->hAnonymousBlock = buffer.ReadHANDLE();
    3577             : 
    3578           0 :             buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3579           0 :             dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
    3580           0 :             return dimension;
    3581             :         }
    3582             : 
    3583           0 :         case CADObject::DIMENSION_DIAMETER:
    3584             :         {
    3585           0 :             CADDimensionDiameterObject * dimension = new CADDimensionDiameterObject();
    3586             : 
    3587           0 :             dimension->setSize( dObjectSize );
    3588           0 :             dimension->stCed = stCommonEntityData;
    3589           0 :             dimension->cdd   = std::move(stCDD);
    3590             : 
    3591           0 :             CADVector vert15pt = buffer.ReadVector();
    3592           0 :             dimension->vert15pt = vert15pt;
    3593             : 
    3594           0 :             CADVector vert10pt = buffer.ReadVector();
    3595           0 :             dimension->vert10pt = vert10pt;
    3596             : 
    3597           0 :             dimension->dfLeaderLen = buffer.ReadBITDOUBLE();
    3598             : 
    3599           0 :             fillCommonEntityHandleData( dimension, buffer);
    3600             : 
    3601           0 :             dimension->hDimstyle       = buffer.ReadHANDLE();
    3602           0 :             dimension->hAnonymousBlock = buffer.ReadHANDLE();
    3603             : 
    3604           0 :             buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3605           0 :             dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
    3606           0 :             return dimension;
    3607             :         }
    3608             :     }
    3609           0 :     return nullptr;
    3610             : }
    3611             : 
    3612           0 : CADImageDefObject * DWGFileR2000::getImageDef(unsigned int dObjectSize,
    3613             :                                               CADBuffer &buffer)
    3614             : {
    3615           0 :     CADImageDefObject * imagedef = new CADImageDefObject();
    3616             : 
    3617           0 :     if(!readBasicData(imagedef, dObjectSize, buffer))
    3618             :     {
    3619           0 :         delete imagedef;
    3620           0 :         return nullptr;
    3621             :     }
    3622             : 
    3623           0 :     imagedef->dClassVersion = buffer.ReadBITLONG();
    3624             : 
    3625           0 :     imagedef->dfXImageSizeInPx = buffer.ReadRAWDOUBLE();
    3626           0 :     imagedef->dfYImageSizeInPx = buffer.ReadRAWDOUBLE();
    3627             : 
    3628           0 :     imagedef->sFilePath = buffer.ReadTV();
    3629           0 :     imagedef->bIsLoaded = buffer.ReadBIT();
    3630             : 
    3631           0 :     imagedef->dResUnits = buffer.ReadCHAR();
    3632             : 
    3633           0 :     imagedef->dfXPixelSize = buffer.ReadRAWDOUBLE();
    3634           0 :     imagedef->dfYPixelSize = buffer.ReadRAWDOUBLE();
    3635             : 
    3636           0 :     imagedef->hParentHandle = buffer.ReadHANDLE();
    3637             : 
    3638           0 :     for( long i = 0; i < imagedef->nNumReactors; ++i )
    3639             :     {
    3640           0 :         imagedef->hReactors.push_back( buffer.ReadHANDLE() );
    3641           0 :         if( buffer.IsEOB() )
    3642             :         {
    3643           0 :             delete imagedef;
    3644           0 :             return nullptr;
    3645             :         }
    3646             :     }
    3647             : 
    3648           0 :     imagedef->hXDictionary = buffer.ReadHANDLE();
    3649             : 
    3650           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3651           0 :     imagedef->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "IMAGEDEF" ) );
    3652             : 
    3653           0 :     return imagedef;
    3654             : }
    3655             : 
    3656           0 : CADImageDefReactorObject * DWGFileR2000::getImageDefReactor(unsigned int dObjectSize, CADBuffer &buffer)
    3657             : {
    3658           0 :     CADImageDefReactorObject * imagedefreactor = new CADImageDefReactorObject();
    3659             : 
    3660           0 :     if(!readBasicData(imagedefreactor, dObjectSize, buffer))
    3661             :     {
    3662           0 :         delete imagedefreactor;
    3663           0 :         return nullptr;
    3664             :     }
    3665             : 
    3666           0 :     imagedefreactor->dClassVersion = buffer.ReadBITLONG();
    3667             : 
    3668           0 :     imagedefreactor->hParentHandle =buffer.ReadHANDLE();
    3669             : 
    3670           0 :     for( long i = 0; i < imagedefreactor->nNumReactors; ++i )
    3671             :     {
    3672           0 :         imagedefreactor->hReactors.push_back( buffer.ReadHANDLE() );
    3673           0 :         if( buffer.IsEOB() )
    3674             :         {
    3675           0 :             delete imagedefreactor;
    3676           0 :             return nullptr;
    3677             :         }
    3678             :     }
    3679             : 
    3680           0 :     imagedefreactor->hXDictionary = buffer.ReadHANDLE();
    3681             : 
    3682           0 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3683           0 :     imagedefreactor->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "IMAGEDEFREFACTOR" ) );
    3684             : 
    3685           0 :     return imagedefreactor;
    3686             : }
    3687             : 
    3688          24 : CADXRecordObject * DWGFileR2000::getXRecord(unsigned int dObjectSize, CADBuffer &buffer)
    3689             : {
    3690          24 :     CADXRecordObject * xrecord = new CADXRecordObject();
    3691             : 
    3692          24 :     if(!readBasicData(xrecord, dObjectSize, buffer))
    3693             :     {
    3694           0 :         delete xrecord;
    3695           0 :         return nullptr;
    3696             :     }
    3697             : 
    3698          24 :     xrecord->nNumDataBytes = buffer.ReadBITLONG();
    3699          24 :     if(xrecord->nNumDataBytes < 0)
    3700             :     {
    3701           0 :         delete xrecord;
    3702           0 :         return nullptr;
    3703             :     }
    3704        1765 :     for( long i = 0; i < xrecord->nNumDataBytes; ++i )
    3705             :     {
    3706        1741 :         xrecord->abyDataBytes.push_back( buffer.ReadCHAR() );
    3707        1741 :         if( buffer.IsEOB() )
    3708             :         {
    3709           0 :             delete xrecord;
    3710           0 :             return nullptr;
    3711             :         }
    3712             :     }
    3713             : 
    3714          24 :     xrecord->dCloningFlag = buffer.ReadBITSHORT();
    3715             : 
    3716          24 :     short dIndicatorNumber = buffer.ReadRAWSHORT();
    3717          24 :     if( dIndicatorNumber == 1 )
    3718             :     {
    3719           0 :         unsigned char nStringSize = buffer.ReadCHAR();
    3720           0 :         /* char dCodePage   =  */ buffer.ReadCHAR();
    3721           0 :         for( unsigned char i = 0; i < nStringSize; ++i )
    3722             :         {
    3723           0 :             buffer.ReadCHAR();
    3724             :         }
    3725             :     }
    3726          24 :     else if( dIndicatorNumber == 70 )
    3727             :     {
    3728           0 :         buffer.ReadRAWSHORT();
    3729             :     }
    3730          24 :     else if( dIndicatorNumber == 10 )
    3731             :     {
    3732           0 :         buffer.ReadRAWDOUBLE();
    3733           0 :         buffer.ReadRAWDOUBLE();
    3734           0 :         buffer.ReadRAWDOUBLE();
    3735             :     }
    3736          24 :     else if( dIndicatorNumber == 40 )
    3737             :     {
    3738           0 :         buffer.ReadRAWDOUBLE();
    3739             :     }
    3740             : 
    3741          24 :     xrecord->hParentHandle = buffer.ReadHANDLE();
    3742             : 
    3743          48 :     for( long i = 0; i < xrecord->nNumReactors; ++i )
    3744             :     {
    3745          24 :         xrecord->hReactors.push_back( buffer.ReadHANDLE() );
    3746          24 :         if( buffer.IsEOB() )
    3747             :         {
    3748           0 :             delete xrecord;
    3749           0 :             return nullptr;
    3750             :         }
    3751             :     }
    3752             : 
    3753          24 :     xrecord->hXDictionary = buffer.ReadHANDLE();
    3754             : 
    3755          24 :     size_t dObjectSizeBit = (dObjectSize + 4) * 8;
    3756          24 :     while( buffer.PositionBit() < dObjectSizeBit )
    3757             :     {
    3758           0 :         xrecord->hObjIdHandles.push_back( buffer.ReadHANDLE() );
    3759             :     }
    3760             : 
    3761          24 :     buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
    3762          24 :     xrecord->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "XRECORD" ) );
    3763             : 
    3764          24 :     return xrecord;
    3765             : }
    3766             : 
    3767          35 : void DWGFileR2000::fillCommonEntityHandleData(CADEntityObject * pEnt,
    3768             :                                               CADBuffer& buffer)
    3769             : {
    3770          35 :     if( pEnt->stCed.bbEntMode == 0 )
    3771           0 :         pEnt->stChed.hOwner = buffer.ReadHANDLE();
    3772             : 
    3773             :     // TODO: Need some reasonable nNumReactors limits.
    3774          35 :     if(pEnt->stCed.nNumReactors < 0 || pEnt->stCed.nNumReactors > 5000)
    3775             :     {
    3776             :         // Something wrong occurred
    3777           0 :         return;
    3778             :     }
    3779          35 :     for( long i = 0; i < pEnt->stCed.nNumReactors; ++i )
    3780           0 :         pEnt->stChed.hReactors.push_back( buffer.ReadHANDLE() );
    3781             : 
    3782          35 :     pEnt->stChed.hXDictionary = buffer.ReadHANDLE();
    3783             : 
    3784          35 :     if( !pEnt->stCed.bNoLinks )
    3785             :     {
    3786          27 :         pEnt->stChed.hPrevEntity = buffer.ReadHANDLE();
    3787          27 :         pEnt->stChed.hNextEntity = buffer.ReadHANDLE();
    3788             :     }
    3789             : 
    3790          35 :     pEnt->stChed.hLayer = buffer.ReadHANDLE();
    3791             : 
    3792          35 :     if( pEnt->stCed.bbLTypeFlags == 0x03 )
    3793           0 :         pEnt->stChed.hLType = buffer.ReadHANDLE();
    3794             : 
    3795          35 :     if( pEnt->stCed.bbPlotStyleFlags == 0x03 )
    3796           0 :         pEnt->stChed.hPlotStyle = buffer.ReadHANDLE();
    3797             : }
    3798             : 
    3799           8 : DWGFileR2000::DWGFileR2000( CADFileIO * poFileIO ) :
    3800             :     CADFile( poFileIO ),
    3801           8 :     imageSeeker(0)
    3802             : {
    3803           8 :     oHeader.addValue( CADHeader::OPENCADVER, CADVersions::DWG_R2000 );
    3804           8 : }
    3805             : 
    3806           8 : int DWGFileR2000::ReadSectionLocators()
    3807             : {
    3808           8 :     char  abyBuf[255] = { 0 };
    3809           8 :     int   dImageSeeker = 0, SLRecordsCount = 0;
    3810           8 :     short dCodePage = 0;
    3811             : 
    3812           8 :     pFileIO->Rewind();
    3813           8 :     memset( abyBuf, 0, DWG_VERSION_STR_SIZE + 1 );
    3814           8 :     pFileIO->Read( abyBuf, DWG_VERSION_STR_SIZE );
    3815           8 :     oHeader.addValue( CADHeader::ACADVER, abyBuf );
    3816           8 :     memset( abyBuf, 0, 8 );
    3817           8 :     pFileIO->Read( abyBuf, 7 );
    3818           8 :     oHeader.addValue( CADHeader::ACADMAINTVER, abyBuf );
    3819             :     // TODO: code can be much simplified if CADHandle will be used.
    3820           8 :     pFileIO->Read( & dImageSeeker, 4 );
    3821           8 :     FromLSB(dImageSeeker);
    3822             :     // to do so, == and ++ operators should be implemented.
    3823           8 :     DebugMsg( "Image seeker read: %d\n", dImageSeeker );
    3824           8 :     imageSeeker = dImageSeeker;
    3825             : 
    3826           8 :     pFileIO->Seek( 2, CADFileIO::SeekOrigin::CUR ); // 19
    3827           8 :     pFileIO->Read( & dCodePage, 2 );
    3828           8 :     FromLSB(dCodePage);
    3829           8 :     oHeader.addValue( CADHeader::DWGCODEPAGE, dCodePage );
    3830             : 
    3831           8 :     DebugMsg( "DWG Code page: %d\n", dCodePage );
    3832             : 
    3833           8 :     pFileIO->Read( & SLRecordsCount, 4 ); // 21
    3834           8 :     FromLSB(SLRecordsCount);
    3835             :     // Last vertex is reached. read it and break reading.
    3836           8 :     DebugMsg( "Section locator records count: %d\n", SLRecordsCount );
    3837             : 
    3838          56 :     for( size_t i = 0; i < static_cast<size_t>(SLRecordsCount); ++i )
    3839             :     {
    3840          48 :         SectionLocatorRecord readRecord;
    3841          48 :         if( pFileIO->Read( & readRecord.byRecordNumber, 1 ) != 1 ||
    3842          96 :             pFileIO->Read( & readRecord.dSeeker, 4 ) != 4 ||
    3843          48 :             pFileIO->Read( & readRecord.dSize, 4 ) != 4 )
    3844             :         {
    3845           0 :             return CADErrorCodes::HEADER_SECTION_READ_FAILED;
    3846             :         }
    3847          48 :         FromLSB(readRecord.dSeeker);
    3848          48 :         FromLSB(readRecord.dSize);
    3849             : 
    3850          48 :         sectionLocatorRecords.push_back( readRecord );
    3851          48 :         DebugMsg( "  Record #%d : %d %d\n", sectionLocatorRecords[i].byRecordNumber, sectionLocatorRecords[i].dSeeker,
    3852          48 :                   sectionLocatorRecords[i].dSize );
    3853             :     }
    3854           8 :     if( sectionLocatorRecords.size() < 3 )
    3855           0 :         return CADErrorCodes::HEADER_SECTION_READ_FAILED;
    3856             : 
    3857           8 :     return CADErrorCodes::SUCCESS;
    3858             : }
    3859             : 
    3860           8 : CADDictionary DWGFileR2000::GetNOD()
    3861             : {
    3862           8 :     CADDictionary stNOD;
    3863           0 :     unique_ptr<CADObject> pCADDictionaryObject( GetObject( oTables.GetTableHandle(
    3864          16 :                                   CADTables::NamedObjectsDict ).getAsLong() ) );
    3865             : 
    3866             :     CADDictionaryObject* spoNamedDictObj =
    3867           8 :             dynamic_cast<CADDictionaryObject*>( pCADDictionaryObject.get() );
    3868           8 :     if( !spoNamedDictObj )
    3869             :     {
    3870           0 :         return stNOD;
    3871             :     }
    3872             : 
    3873         152 :     for( size_t i = 0; i < spoNamedDictObj->sItemNames.size(); ++i )
    3874             :     {
    3875             :         unique_ptr<CADObject> spoDictRecord (
    3876         144 :                     GetObject( spoNamedDictObj->hItemHandles[i].getAsLong() ) );
    3877             : 
    3878         144 :         if( spoDictRecord == nullptr )
    3879           8 :             continue; // Skip unread objects
    3880             : 
    3881         136 :         if( spoDictRecord->getType() == CADObject::DICTIONARY )
    3882             :         {
    3883             :             // TODO: add implementation of DICTIONARY reading
    3884             :         }
    3885          24 :         else if( spoDictRecord->getType() == CADObject::XRECORD )
    3886             :         {
    3887          24 :             CADXRecord * cadxRecord = new CADXRecord();
    3888             :             CADXRecordObject * cadxRecordObject =
    3889          24 :                 static_cast<CADXRecordObject*>(spoDictRecord.get());
    3890             : 
    3891             :             string xRecordData( cadxRecordObject->abyDataBytes.begin(),
    3892          48 :                                 cadxRecordObject->abyDataBytes.end() );
    3893          24 :             cadxRecord->setRecordData( xRecordData );
    3894             : 
    3895          24 :             shared_ptr<CADDictionaryRecord> cadxRecordPtr(static_cast<CADDictionaryRecord*>(cadxRecord));
    3896             : 
    3897          24 :             stNOD.addRecord( make_pair( spoNamedDictObj->sItemNames[i], cadxRecordPtr ) );
    3898             :         }
    3899             :     }
    3900             : 
    3901           8 :     return stNOD;
    3902             : }
    3903             : 
    3904         229 : unsigned short DWGFileR2000::validateEntityCRC(CADBuffer& buffer,
    3905             :                                                unsigned int dObjectSize,
    3906             :                                                const char * entityName,
    3907             :                                                bool bSwapEndianness )
    3908             : {
    3909         229 :     unsigned short CRC = static_cast<unsigned short>(buffer.ReadRAWSHORT());
    3910         229 :     if(bSwapEndianness)
    3911             :     {
    3912           8 :         SwapEndianness(CRC, sizeof (CRC));
    3913             :     }
    3914             : 
    3915         229 :     buffer.Seek(0, CADBuffer::BEG);
    3916         229 :     const unsigned short initial = 0xC0C1;
    3917             :     const unsigned short calculated =
    3918         229 :             CalculateCRC8(initial, static_cast<const char*>(buffer.GetRawBuffer()),
    3919             :                           static_cast<int>(dObjectSize) );
    3920         229 :     if( CRC != calculated )
    3921             :     {
    3922           0 :         DebugMsg( "Invalid CRC for %s object\nCRC read:0x%X calculated:0x%X\n",
    3923             :                                                   entityName, CRC, calculated );
    3924           0 :         return 0; // If CRC equal 0 - this is error
    3925             :     }
    3926         229 :     return CRC;
    3927             : }
    3928             : 
    3929         170 : bool DWGFileR2000::readBasicData(CADBaseControlObject *pBaseControlObject,
    3930             :                            unsigned int dObjectSize,
    3931             :                            CADBuffer &buffer)
    3932             : {
    3933         170 :     pBaseControlObject->setSize( dObjectSize );
    3934         170 :     pBaseControlObject->nObjectSizeInBits = buffer.ReadRAWLONG();
    3935         170 :     pBaseControlObject->hObjectHandle = buffer.ReadHANDLE();
    3936         170 :     short  dEEDSize = 0;
    3937         340 :     CADEed dwgEed;
    3938         179 :     while( ( dEEDSize = buffer.ReadBITSHORT() ) != 0 )
    3939             :     {
    3940           9 :         dwgEed.dLength = dEEDSize;
    3941           9 :         dwgEed.hApplication = buffer.ReadHANDLE();
    3942             : 
    3943           9 :         if(dEEDSize > 0)
    3944             :         {
    3945          50 :             for( short i = 0; i < dEEDSize; ++i )
    3946             :             {
    3947          41 :                 dwgEed.acData.push_back( buffer.ReadCHAR() );
    3948             :             }
    3949             :         }
    3950             : 
    3951           9 :         pBaseControlObject->aEED.push_back( dwgEed );
    3952             :     }
    3953             : 
    3954         170 :     pBaseControlObject->nNumReactors = buffer.ReadBITLONG();
    3955             :     // TODO: Need reasonable nNumReactors limits.
    3956         170 :     if(pBaseControlObject->nNumReactors < 0 ||
    3957         170 :        pBaseControlObject->nNumReactors > 5000)
    3958             :     {
    3959           0 :         return false;
    3960             :     }
    3961         170 :     return true;
    3962             : }

Generated by: LCOV version 1.14