1 /******************************************************************************
2 **  libDXFrw - Library to read/write DXF files (ascii & binary)              **
3 **                                                                           **
4 **  Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com               **
5 **                                                                           **
6 **  This library is free software, licensed under the terms of the GNU       **
7 **  General Public License as published by the Free Software Foundation,     **
8 **  either version 2 of the License, or (at your option) any later version.  **
9 **  You should have received a copy of the GNU General Public License        **
10 **  along with this program.  If not, see <http://www.gnu.org/licenses/>.    **
11 ******************************************************************************/
12 
13 #include <cstdlib>
14 #include <fstream>
15 #include <string>
16 #include <sstream>
17 #include "dxfreader.h"
18 #include "drw_textcodec.h"
19 #include "drw_dbg.h"
20 
readRec(int * codeData)21 bool dxfReader::readRec(int *codeData) {
22 //    std::string text;
23     int code;
24 
25     if (!readCode(&code))
26         return false;
27     *codeData = code;
28 
29     if (code < 10)
30         readString();
31     else if (code < 60)
32         readDouble();
33     else if (code < 80)
34         readInt16();
35     else if (code > 89 && code < 100) //TODO this is an int 32b
36         readInt32();
37     else if (code == 100 || code == 102 || code == 105)
38         readString();
39     else if (code > 109 && code < 150) //skip not used at the v2012
40         readDouble();
41     else if (code > 159 && code < 170) //skip not used at the v2012
42         readInt64();
43     else if (code < 180)
44         readInt16();
45     else if (code > 209 && code < 240) //skip not used at the v2012
46         readDouble();
47     else if (code > 269 && code < 290) //skip not used at the v2012
48         readInt16();
49     else if (code < 300) //TODO this is a boolean indicator, int in Binary?
50         readBool();
51     else if (code < 370)
52         readString();
53     else if (code < 390)
54         readInt16();
55     else if (code < 400)
56         readString();
57     else if (code < 410)
58         readInt16();
59     else if (code < 420)
60         readString();
61     else if (code < 430) //TODO this is an int 32b
62         readInt32();
63     else if (code < 440)
64         readString();
65     else if (code < 450) //TODO this is an int 32b
66         readInt32();
67     else if (code < 460) //TODO this is long??
68         readInt32();
69     else if (code < 470) //TODO this is a floating point double precision??
70         readDouble();
71     else if (code < 481)
72         readString();
73     else if( 999 == code && m_bIgnoreComments) {
74         readString();
75         return readRec( codeData);
76     }
77     else if (code > 998 && code < 1009) //skip not used at the v2012
78         readString();
79     else if (code < 1060) //TODO this is a floating point double precision??
80         readDouble();
81     else if (code < 1071)
82         readInt16();
83     else if (code == 1071) //TODO this is an int 32b
84         readInt32();
85     else if (skip)
86         //skip safely this dxf entry ( ok for ascii dxf)
87         readString();
88     else
89         //break in binary files because the conduct is unpredictable
90         return false;
91 
92     return (filestr->good());
93 }
getHandleString()94 int dxfReader::getHandleString(){
95     int res;
96 #if defined(__APPLE__)
97     int Succeeded = sscanf ( strData.c_str(), "%x", &res );
98     if ( !Succeeded || Succeeded == EOF )
99         res = 0;
100 #else
101     std::istringstream Convert(strData);
102     if ( !(Convert >> std::hex >>res) )
103         res = 0;
104 #endif
105     return res;
106 }
107 
readCode(int * code)108 bool dxfReaderBinary::readCode(int *code) {
109     unsigned short *int16p;
110     char buffer[2];
111     filestr->read(buffer,2);
112     int16p = (unsigned short *) buffer;
113 //exist a 32bits int (code 90) with 2 bytes???
114     if ((*code == 90) && (*int16p>2000)){
115         DRW_DBG(*code); DRW_DBG(" de 16bits\n");
116         filestr->seekg(-4, std::ios_base::cur);
117         filestr->read(buffer,2);
118         int16p = (unsigned short *) buffer;
119     }
120     *code = *int16p;
121     DRW_DBG(*code); DRW_DBG("\n");
122 
123     return (filestr->good());
124 }
125 
readString()126 bool dxfReaderBinary::readString() {
127     type = STRING;
128     std::getline(*filestr, strData, '\0');
129     DRW_DBG(strData); DRW_DBG("\n");
130     return (filestr->good());
131 }
132 
readString(std::string * text)133 bool dxfReaderBinary::readString(std::string *text) {
134     type = STRING;
135     std::getline(*filestr, *text, '\0');
136     DRW_DBG(*text); DRW_DBG("\n");
137     return (filestr->good());
138 }
139 
readInt16()140 bool dxfReaderBinary::readInt16() {
141     type = INT32;
142     char buffer[2];
143     filestr->read(buffer,2);
144     intData = (int)((buffer[1] << 8) | buffer[0]);
145     DRW_DBG(intData); DRW_DBG("\n");
146     return (filestr->good());
147 }
148 
readInt32()149 bool dxfReaderBinary::readInt32() {
150     type = INT32;
151     unsigned int *int32p;
152     char buffer[4];
153     filestr->read(buffer,4);
154     int32p = (unsigned int *) buffer;
155     intData = *int32p;
156     DRW_DBG(intData); DRW_DBG("\n");
157     return (filestr->good());
158 }
159 
readInt64()160 bool dxfReaderBinary::readInt64() {
161     type = INT64;
162     unsigned long long int *int64p; //64 bits integer pointer
163     char buffer[8];
164     filestr->read(buffer,8);
165     int64p = (unsigned long long int *) buffer;
166     int64 = *int64p;
167     DRW_DBG(int64); DRW_DBG(" int64\n");
168     return (filestr->good());
169 }
170 
readDouble()171 bool dxfReaderBinary::readDouble() {
172     type = DOUBLE;
173     double *result;
174     char buffer[8];
175     filestr->read(buffer,8);
176     result = (double *) buffer;
177     doubleData = *result;
178     DRW_DBG(doubleData); DRW_DBG("\n");
179     return (filestr->good());
180 }
181 
182 //saved as int or add a bool member??
readBool()183 bool dxfReaderBinary::readBool() {
184     char buffer[1];
185     filestr->read(buffer,1);
186     intData = (int)(buffer[0]);
187     DRW_DBG(intData); DRW_DBG("\n");
188     return (filestr->good());
189 }
190 
readCode(int * code)191 bool dxfReaderAscii::readCode(int *code) {
192     std::string text;
193     std::getline(*filestr, text);
194     *code = atoi(text.c_str());
195     DRW_DBG(*code); DRW_DBG("\n");
196     return (filestr->good());
197 }
readString(std::string * text)198 bool dxfReaderAscii::readString(std::string *text) {
199     type = STRING;
200     std::getline(*filestr, *text);
201     if (!text->empty() && text->at(text->size()-1) == '\r')
202         text->erase(text->size()-1);
203     return (filestr->good());
204 }
205 
readString()206 bool dxfReaderAscii::readString() {
207     type = STRING;
208     std::getline(*filestr, strData);
209     if (!strData.empty() && strData.at(strData.size()-1) == '\r')
210         strData.erase(strData.size()-1);
211     DRW_DBG(strData); DRW_DBG("\n");
212     return (filestr->good());
213 }
214 
readInt16()215 bool dxfReaderAscii::readInt16() {
216     type = INT32;
217     std::string text;
218     if (readString(&text)){
219         intData = atoi(text.c_str());
220         DRW_DBG(intData); DRW_DBG("\n");
221         return true;
222     } else
223         return false;
224 }
225 
readInt32()226 bool dxfReaderAscii::readInt32() {
227     type = INT32;
228     return readInt16();
229 }
230 
readInt64()231 bool dxfReaderAscii::readInt64() {
232     type = INT64;
233     return readInt16();
234 }
235 
readDouble()236 bool dxfReaderAscii::readDouble() {
237     type = DOUBLE;
238     std::string text;
239     if (readString(&text)){
240 #if defined(__APPLE__)
241         int succeeded=sscanf( & (text[0]), "%lg", &doubleData);
242         if(succeeded != 1) {
243             DRW_DBG("dxfReaderAscii::readDouble(): reading double error: ");
244             DRW_DBG(text);
245             DRW_DBG('\n');
246         }
247 #else
248         std::istringstream sd(text);
249         sd >> doubleData;
250         DRW_DBG(doubleData); DRW_DBG('\n');
251 #endif
252         return true;
253     } else
254         return false;
255 }
256 
257 //saved as int or add a bool member??
readBool()258 bool dxfReaderAscii::readBool() {
259     type = BOOL;
260     std::string text;
261     if (readString(&text)){
262         intData = atoi(text.c_str());
263         DRW_DBG(intData); DRW_DBG("\n");
264         return true;
265     } else
266         return false;
267 }
268 
269