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

Generated by: LCOV version 1.14