/****************************************************************************** ** libDXFrw - Library to read/write DXF files (ascii & binary) ** ** ** ** Copyright (C) 2011 Rallaz, 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 #include #include #include #include "dxfreader.h" #include "drw_textcodec.h" #ifdef DRW_DBG #include // for debug #define DBG( a ) std::cerr << a #else #define DBG( a ) #endif bool dxfReader::readRec( int* codeData, bool skip ) { // std::string text; int code; #ifdef DRW_DBG count = count + 2; // DBG /* if (count > 10250) * DBG("line 10256");*/ #endif if( !readCode( &code ) ) return false; *codeData = code; if( code < 10 ) readString(); else if( code < 60 ) readDouble(); else if( code < 80 ) readInt(); else if( code > 89 && code < 100 ) // TODO this is an int 32b readInt32(); else if( code == 100 || code == 102 || code == 105 ) readString(); else if( code > 109 && code < 150 ) // skip not used at the v2012 readDouble(); else if( code > 159 && code < 170 ) // skip not used at the v2012 readInt64(); else if( code < 180 ) readInt(); else if( code > 209 && code < 240 ) // skip not used at the v2012 readDouble(); else if( code > 269 && code < 290 ) // skip not used at the v2012 readInt(); else if( code < 300 ) // TODO this is a boolean indicator, int in Binary? readBool(); else if( code < 370 ) readString(); else if( code < 390 ) readInt(); else if( code < 400 ) readString(); else if( code < 410 ) readInt(); else if( code < 420 ) readString(); else if( code < 430 ) // TODO this is an int 32b readInt32(); else if( code < 440 ) readString(); else if( code < 450 ) // TODO this is an int 32b readInt32(); else if( code < 460 ) // TODO this is long?? readInt(); else if( code < 470 ) // TODO this is a floating point double precision?? readDouble(); else if( code < 481 ) readString(); else if( code > 998 && code < 1009 ) // skip not used at the v2012 readString(); else if( code < 1060 ) // TODO this is a floating point double precision?? readDouble(); else if( code < 1071 ) readInt(); else if( code == 1071 ) // TODO this is an int 32b readInt32(); else if( skip ) // skip safely this dxf entry ( ok for ascii dxf) readString(); else // break in binary files because the conduct is unpredictable return false; return filestr->good(); } int dxfReader::getHandleString() { int res; #if defined(__APPLE__) int Succeeded = sscanf( strData.c_str(), "%x", &res ); if( !Succeeded || Succeeded == EOF ) res = 0; #else std::istringstream Convert( strData ); if( !(Convert >> std::hex >> res) ) res = 0; #endif return res; } bool dxfReaderBinary::readCode( int* code ) { unsigned short* int16p; char buffer[2]; filestr->read( buffer, 2 ); int16p = (unsigned short*) buffer; // exist a 32bits int (code 90) with 2 bytes??? if( (*code == 90) && (*int16p>2000) ) { DBG( *code ); DBG( " de 16bits\n" ); filestr->seekg( -4, std::ios_base::cur ); filestr->read( buffer, 2 ); int16p = (unsigned short*) buffer; } *code = *int16p; DBG( *code ); DBG( "\n" ); return filestr->good(); } bool dxfReaderBinary::readString() { std::getline( *filestr, strData, '\0' ); DBG( strData ); DBG( "\n" ); return filestr->good(); } bool dxfReaderBinary::readString( std::string* text ) { std::getline( *filestr, *text, '\0' ); DBG( *text ); DBG( "\n" ); return filestr->good(); } bool dxfReaderBinary::readInt() { char buffer[2]; filestr->read( buffer, 2 ); intData = (int) ( (buffer[1] << 8) | buffer[0] ); DBG( intData ); DBG( "\n" ); return filestr->good(); } bool dxfReaderBinary::readInt32() { unsigned int* int32p; char buffer[4]; filestr->read( buffer, 4 ); int32p = (unsigned int*) buffer; intData = *int32p; DBG( intData ); DBG( "\n" ); return filestr->good(); } bool dxfReaderBinary::readInt64() { unsigned long long int* int64p; // 64 bits integer pointer char buffer[8]; filestr->read( buffer, 8 ); int64p = (unsigned long long int*) buffer; int64 = *int64p; DBG( int64 ); DBG( " int64\n" ); return filestr->good(); } bool dxfReaderBinary::readDouble() { double* result; char buffer[8]; filestr->read( buffer, 8 ); result = (double*) buffer; doubleData = *result; DBG( doubleData ); DBG( "\n" ); return filestr->good(); } // saved as int or add a bool member?? bool dxfReaderBinary::readBool() { char buffer[1]; filestr->read( buffer, 1 ); intData = (int) (buffer[0]); DBG( intData ); DBG( "\n" ); return filestr->good(); } bool dxfReaderAscii::readCode( int* code ) { std::string text; std::getline( *filestr, text ); *code = atoi( text.c_str() ); DBG( *code ); DBG( "\n" ); return filestr->good(); } bool dxfReaderAscii::readString( std::string* text ) { std::getline( *filestr, *text ); if( !text->empty() && text->at( text->size() - 1 ) == '\r' ) text->erase( text->size() - 1 ); return filestr->good(); } bool dxfReaderAscii::readString() { std::getline( *filestr, strData ); if( !strData.empty() && strData.at( strData.size() - 1 ) == '\r' ) strData.erase( strData.size() - 1 ); DBG( strData ); DBG( "\n" ); return filestr->good(); } bool dxfReaderAscii::readInt() { std::string text; if( readString( &text ) ) { intData = atoi( text.c_str() ); DBG( intData ); DBG( "\n" ); return true; } else return false; } bool dxfReaderAscii::readInt32() { return readInt(); } bool dxfReaderAscii::readInt64() { return readInt(); } bool dxfReaderAscii::readDouble() { std::string text; if( readString( &text ) ) { #if defined(__APPLE__) int succeeded = sscanf( &(text[0]), "%lg", &doubleData ); if( succeeded != 1 ) { DBG( "dxfReaderAscii::readDouble(): reading double error: " ); DBG( text ); DBG( '\n' ); } #else std::istringstream sd( text ); sd >> doubleData; DBG( doubleData ); DBG( '\n' ); #endif return true; } else return false; } // saved as int or add a bool member?? bool dxfReaderAscii::readBool() { std::string text; if( readString( &text ) ) { intData = atoi( text.c_str() ); DBG( intData ); DBG( "\n" ); return true; } else return false; }