dxfreader.cpp 7.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/******************************************************************************
**  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
21 22
#include <iostream>    // for debug
#define DBG( a ) std::cerr << a
23
#else
24
#define DBG( a )
25 26
#endif

27 28 29
bool dxfReader::readRec( int* codeData, bool skip )
{
// std::string text;
30 31 32
    int code;

#ifdef DRW_DBG
33
    count = count + 2;    // DBG
34
/*    if (count > 10250)
35
 *       DBG("line 10256");*/
36 37
#endif

38
    if( !readCode( &code ) )
39
        return false;
40

41 42
    *codeData = code;

43
    if( code < 10 )
44
        readString();
45
    else if( code < 60 )
46
        readDouble();
47
    else if( code < 80 )
48
        readInt();
49
    else if( code > 89 && code < 100 ) // TODO this is an int 32b
50
        readInt32();
51
    else if( code == 100 || code == 102 || code == 105 )
52
        readString();
53
    else if( code > 109 && code < 150 ) // skip not used at the v2012
54
        readDouble();
55
    else if( code > 159 && code < 170 ) // skip not used at the v2012
56
        readInt64();
57
    else if( code < 180 )
58
        readInt();
59
    else if( code > 209 && code < 240 ) // skip not used at the v2012
60
        readDouble();
61
    else if( code > 269 && code < 290 ) // skip not used at the v2012
62
        readInt();
63
    else if( code < 300 )               // TODO this is a boolean indicator, int in Binary?
64
        readBool();
65
    else if( code < 370 )
66
        readString();
67
    else if( code < 390 )
68
        readInt();
69
    else if( code < 400 )
70
        readString();
71
    else if( code < 410 )
72
        readInt();
73
    else if( code < 420 )
74
        readString();
75
    else if( code < 430 ) // TODO this is an int 32b
76
        readInt32();
77
    else if( code < 440 )
78
        readString();
79
    else if( code < 450 )   // TODO this is an int 32b
80
        readInt32();
81
    else if( code < 460 )   // TODO this is long??
82
        readInt();
83
    else if( code < 470 )   // TODO this is a floating point double precision??
84
        readDouble();
85
    else if( code < 481 )
86
        readString();
87
    else if( code > 998 && code < 1009 )    // skip not used at the v2012
88
        readString();
89
    else if( code < 1060 )                  // TODO this is a floating point double precision??
90
        readDouble();
91
    else if( code < 1071 )
92
        readInt();
93
    else if( code == 1071 ) // TODO this is an int 32b
94
        readInt32();
95 96
    else if( skip )
        // skip safely this dxf entry ( ok for ascii dxf)
97 98
        readString();
    else
99
        // break in binary files because the conduct is unpredictable
100 101
        return false;

102
    return filestr->good();
103
}
104 105 106 107


int dxfReader::getHandleString()
{
108
    int res;
109

110
#if defined(__APPLE__)
111 112 113
    int Succeeded = sscanf( strData.c_str(), "%x", &res );

    if( !Succeeded || Succeeded == EOF )
114
        res = 0;
115

116
#else
117 118 119
    std::istringstream Convert( strData );

    if( !(Convert >> std::hex >> res) )
120
        res = 0;
121

122 123 124 125
#endif
    return res;
}

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

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;
142
    }
143

144
    *code = *int16p;
145
    DBG( *code ); DBG( "\n" );
146

147
    return filestr->good();
148 149
}

150 151 152 153 154 155 156

bool dxfReaderBinary::readString()
{
    std::getline( *filestr, strData, '\0' );

    DBG( strData ); DBG( "\n" );
    return filestr->good();
157 158
}

159 160 161 162 163 164 165

bool dxfReaderBinary::readString( std::string* text )
{
    std::getline( *filestr, *text, '\0' );

    DBG( *text ); DBG( "\n" );
    return filestr->good();
166 167
}

168 169 170

bool dxfReaderBinary::readInt()
{
171
    char buffer[2];
172 173 174 175 176

    filestr->read( buffer, 2 );
    intData = (int) ( (buffer[1] << 8) | buffer[0] );
    DBG( intData ); DBG( "\n" );
    return filestr->good();
177 178
}

179 180 181 182 183 184 185 186

bool dxfReaderBinary::readInt32()
{
    unsigned int*   int32p;
    char            buffer[4];

    filestr->read( buffer, 4 );
    int32p  = (unsigned int*) buffer;
187
    intData = *int32p;
188 189
    DBG( intData ); DBG( "\n" );
    return filestr->good();
190 191
}

192 193 194 195

bool dxfReaderBinary::readInt64()
{
    unsigned long long int* int64p;    // 64 bits integer pointer
196
    char buffer[8];
197 198 199 200 201 202

    filestr->read( buffer, 8 );
    int64p  = (unsigned long long int*) buffer;
    int64   = *int64p;
    DBG( int64 ); DBG( " int64\n" );
    return filestr->good();
203 204
}

205 206 207 208 209 210 211 212 213 214 215

bool dxfReaderBinary::readDouble()
{
    double* result;
    char    buffer[8];

    filestr->read( buffer, 8 );
    result      = (double*) buffer;
    doubleData  = *result;
    DBG( doubleData ); DBG( "\n" );
    return filestr->good();
216 217
}

218 219 220 221

// saved as int or add a bool member??
bool dxfReaderBinary::readBool()
{
222
    char buffer[1];
223 224 225 226 227

    filestr->read( buffer, 1 );
    intData = (int) (buffer[0]);
    DBG( intData ); DBG( "\n" );
    return filestr->good();
228 229
}

230 231 232

bool dxfReaderAscii::readCode( int* code )
{
233
    std::string text;
234 235 236 237 238
    std::getline( *filestr, text );

    *code = atoi( text.c_str() );
    DBG( *code ); DBG( "\n" );
    return filestr->good();
239
}
240 241 242 243 244 245 246 247 248 249


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();
250 251
}

252 253 254 255 256 257 258 259 260 261

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();
262 263
}

264 265 266

bool dxfReaderAscii::readInt()
{
267
    std::string text;
268 269 270 271 272

    if( readString( &text ) )
    {
        intData = atoi( text.c_str() );
        DBG( intData ); DBG( "\n" );
273
        return true;
274 275
    }
    else
276 277 278
        return false;
}

279 280 281

bool dxfReaderAscii::readInt32()
{
282 283 284
    return readInt();
}

285 286 287

bool dxfReaderAscii::readInt64()
{
288 289 290
    return readInt();
}

291 292 293

bool dxfReaderAscii::readDouble()
{
294
    std::string text;
295 296 297

    if( readString( &text ) )
    {
298
#if defined(__APPLE__)
299 300 301 302 303 304 305
        int succeeded = sscanf( &(text[0]), "%lg", &doubleData );

        if( succeeded != 1 )
        {
            DBG( "dxfReaderAscii::readDouble(): reading double error: " );
            DBG( text );
            DBG( '\n' );
306
        }
307

308
#else
309
        std::istringstream sd( text );
310
        sd >> doubleData;
311
        DBG( doubleData ); DBG( '\n' );
312 313
#endif
        return true;
314 315
    }
    else
316 317 318
        return false;
}

319 320 321 322

// saved as int or add a bool member??
bool dxfReaderAscii::readBool()
{
323
    std::string text;
324 325 326 327 328

    if( readString( &text ) )
    {
        intData = atoi( text.c_str() );
        DBG( intData ); DBG( "\n" );
329
        return true;
330 331
    }
    else
332 333
        return false;
}