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

Generated by: LCOV version 1.14