/****************************************************************************** ** libDXFrw - Library to read/write DXF files (ascii & binary) ** ** ** ** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** ** ** ** This library is free software, licensed under the terms of the GNU ** ** General Public License as published by the Free Software Foundation, ** ** either version 2 of the License, or (at your option) any later version. ** ** You should have received a copy of the GNU General Public License ** ** along with this program. If not, see . ** ******************************************************************************/ #include "libdwgr.h" #include #include #include #include "intern/drw_dbg.h" #include "qgslogger.h" #include "intern/drw_textcodec.h" #include "intern/dwgreader.h" #include "intern/dwgreader15.h" #include "intern/dwgreader18.h" #include "intern/dwgreader21.h" #include "intern/dwgreader24.h" #include "intern/dwgreader27.h" #define FIRSTHANDLE 48 #if 0 enum sections { secUnknown, secHeader, secTables, secBlocks, secEntities, secObjects }; #endif dwgR::dwgR( const char *name ) : version( DRW::UNKNOWNV ) , error( DRW::BAD_NONE ) , fileName( name ) , applyExt( false ) , iface( nullptr ) , reader( nullptr ) #if 0 , writer( nullptr ) #endif { DRW_DBGSL( DRW_dbg::none ); } dwgR::~dwgR() { delete reader; } void dwgR::setDebug( DRW::DBG_LEVEL lvl ) { switch ( lvl ) { case DRW::debug: DRW_DBGSL( DRW_dbg::debug ); break; default: DRW_DBGSL( DRW_dbg::none ); } } /*reads metadata and loads image preview*/ bool dwgR::getPreview() { std::ifstream filestr; bool isOk = openFile( &filestr ); if ( !isOk ) return false; isOk = reader->readMetaData(); if ( isOk ) { isOk = reader->readPreview(); } else error = DRW::BAD_READ_METADATA; filestr.close(); delete reader; reader = nullptr; return isOk; } bool dwgR::testReader() { bool isOk = false; std::ifstream filestr; filestr.open( fileName.c_str(), std::ios_base::in | std::ios::binary ); if ( !filestr.is_open() || !filestr.good() ) { error = DRW::BAD_OPEN; return isOk; } dwgBuffer fileBuf( &filestr ); duint8 *tmpStrData = new duint8[fileBuf.size()]; fileBuf.getBytes( tmpStrData, fileBuf.size() ); dwgBuffer dataBuf( tmpStrData, fileBuf.size() ); fileBuf.setPosition( 0 ); QgsDebugMsg( QString( "filebuf size:%1, dataBuf size:%2, filebuf pos:%3, dataBuf pos:%4, filebuf bitpos:%5, dataBuf bitpos:%6, filebuf first byte:0x%7, databuf first byte:0x%8" ) .arg( fileBuf.size() ).arg( dataBuf.size() ) .arg( fileBuf.getPosition() ).arg( dataBuf.getPosition() ) .arg( fileBuf.getBitPos() ).arg( dataBuf.getBitPos() ) .arg( fileBuf.getRawChar8(), 0, 16 ) .arg( dataBuf.getRawChar8(), 0, 16 ) ); fileBuf.setBitPos( 4 ); dataBuf.setBitPos( 4 ); QgsDebugMsg( QString( "filebuf first byte:0x%1, databuf first byte:0x%2, filebuf pos:%3, databuf pos:%4, filebuf bitpos:%5, databuf bitpos:%6" ) .arg( fileBuf.getRawChar8(), 0, 16 ) .arg( dataBuf.getRawChar8(), 0, 16 ) .arg( fileBuf.getPosition() ).arg( dataBuf.getPosition() ) .arg( fileBuf.getBitPos() ).arg( dataBuf.getBitPos() ) ); fileBuf.setBitPos( 6 ); dataBuf.setBitPos( 6 ); QgsDebugMsg( QString( "filebuf pos:%1, databuf pos:%1, filebuf bitpos:%3, databuf bitpos:%4, filebuf first byte:%5, databuf first byte:%6" ) .arg( fileBuf.getPosition() ).arg( dataBuf.getPosition() ) .arg( fileBuf.getBitPos() ).arg( dataBuf.getBitPos() ) .arg( fileBuf.getRawChar8(), 0, 16 ) .arg( dataBuf.getRawChar8(), 0, 16 ) ); fileBuf.setBitPos( 0 ); dataBuf.setBitPos( 0 ); QgsDebugMsg( QString( "filebuf first byte:0x%1, databuf first byte:0x%2, filebuf pos:%3, databuf pos:%4, filebuf bitpos:%5, databuf bitpos:%6" ) .arg( fileBuf.getRawChar8(), 0, 16 ) .arg( dataBuf.getRawChar8(), 0, 16 ) .arg( fileBuf.getPosition() ).arg( dataBuf.getPosition() ) .arg( fileBuf.getBitPos() ).arg( dataBuf.getBitPos() ) ); delete [] tmpStrData; filestr.close(); return isOk; } /*start reading dwg file header and, if can read it, continue reading all*/ bool dwgR::read( DRW_Interface *interface_, bool ext ) { applyExt = ext; iface = interface_; #if 0 testReader(); return false; #endif std::ifstream filestr; bool isOk = openFile( &filestr ); if ( !isOk ) return false; isOk = reader->readMetaData(); if ( isOk ) { isOk = reader->readFileHeader(); if ( isOk ) { isOk = processDwg(); } else error = DRW::BAD_READ_FILE_HEADER; } else error = DRW::BAD_READ_METADATA; filestr.close(); delete reader; reader = nullptr; return isOk; } /* Open the file and stores it in filestr, install the correct reader version. * If fail opening file, error are set as DRW::BAD_OPEN * If not are DWG or are unsupported version, error are set as DRW::BAD_VERSION * and closes filestr. * Return true on succeed or false on fail */ bool dwgR::openFile( std::ifstream *filestr ) { QgsDebugMsg( "Entering." ); bool isOk = false; filestr->open( fileName.c_str(), std::ios_base::in | std::ios::binary ); if ( !filestr->is_open() || !filestr->good() ) { error = DRW::BAD_OPEN; return isOk; } char line[7]; filestr->read( line, 6 ); line[6] = '\0'; QgsDebugMsg( QString( "line version:%1" ).arg( line ) ); if ( strcmp( line, "AC1006" ) == 0 ) version = DRW::AC1006; else if ( strcmp( line, "AC1009" ) == 0 ) { version = DRW::AC1009; // reader = new dwgReader09(&filestr, this); } else if ( strcmp( line, "AC1012" ) == 0 ) { version = DRW::AC1012; reader = new dwgReader15( filestr, this ); } else if ( strcmp( line, "AC1014" ) == 0 ) { version = DRW::AC1014; reader = new dwgReader15( filestr, this ); } else if ( strcmp( line, "AC1015" ) == 0 ) { version = DRW::AC1015; reader = new dwgReader15( filestr, this ); } else if ( strcmp( line, "AC1018" ) == 0 ) { version = DRW::AC1018; reader = new dwgReader18( filestr, this ); } else if ( strcmp( line, "AC1021" ) == 0 ) { version = DRW::AC1021; reader = new dwgReader21( filestr, this ); } else if ( strcmp( line, "AC1024" ) == 0 ) { version = DRW::AC1024; reader = new dwgReader24( filestr, this ); } else if ( strcmp( line, "AC1027" ) == 0 ) { version = DRW::AC1027; reader = new dwgReader27( filestr, this ); } else version = DRW::UNKNOWNV; if ( !reader ) { error = DRW::BAD_VERSION; filestr->close(); } else isOk = true; return isOk; } /********* Reader Process *********/ bool dwgR::processDwg() { QgsDebugMsg( "Entering." ); bool ret; bool ret2; DRW_Header hdr; ret = reader->readDwgHeader( hdr ); if ( !ret ) { error = DRW::BAD_READ_HEADER; } ret2 = reader->readDwgClasses(); if ( ret && !ret2 ) { error = DRW::BAD_READ_CLASSES; ret = ret2; } ret2 = reader->readDwgHandles(); if ( ret && !ret2 ) { error = DRW::BAD_READ_HANDLES; ret = ret2; } ret2 = reader->readDwgTables( hdr ); if ( ret && !ret2 ) { error = DRW::BAD_READ_TABLES; ret = ret2; } iface->addHeader( &hdr ); for ( std::map::iterator it = reader->ltypemap.begin(); it != reader->ltypemap.end(); ++it ) { DRW_LType *lt = it->second; iface->addLType( const_cast( *lt ) ); } for ( std::map::iterator it = reader->layermap.begin(); it != reader->layermap.end(); ++it ) { DRW_Layer *ly = it->second; iface->addLayer( const_cast( *ly ) ); } for ( std::map::iterator it = reader->stylemap.begin(); it != reader->stylemap.end(); ++it ) { DRW_Textstyle *ly = it->second; iface->addTextStyle( const_cast( *ly ) ); } for ( std::map::iterator it = reader->dimstylemap.begin(); it != reader->dimstylemap.end(); ++it ) { DRW_Dimstyle *ly = it->second; iface->addDimStyle( const_cast( *ly ) ); } for ( std::map::iterator it = reader->vportmap.begin(); it != reader->vportmap.end(); ++it ) { DRW_Vport *ly = it->second; iface->addVport( const_cast( *ly ) ); } for ( std::map::iterator it = reader->appIdmap.begin(); it != reader->appIdmap.end(); ++it ) { DRW_AppId *ly = it->second; iface->addAppId( const_cast( *ly ) ); } ret2 = reader->readDwgBlocks( *iface ); if ( ret && !ret2 ) { error = DRW::BAD_READ_BLOCKS; ret = ret2; } ret2 = reader->readDwgEntities( *iface ); if ( ret && !ret2 ) { error = DRW::BAD_READ_ENTITIES; ret = ret2; } ret2 = reader->readDwgObjects( *iface ); if ( ret && !ret2 ) { error = DRW::BAD_READ_OBJECTS; ret = ret2; } return ret; }