334 lines
7.5 KiB
C++
334 lines
7.5 KiB
C++
/******************************************************************************
|
|
** 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 <http://www.gnu.org/licenses/>. **
|
|
******************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include "dxfreader.h"
|
|
#include "drw_textcodec.h"
|
|
|
|
#ifdef DRW_DBG
|
|
#include <iostream> // 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;
|
|
}
|