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
14 #include "libdwgr.h"
15 #include <fstream>
16 #include <algorithm>
17 #include <sstream>
18 #include "intern/drw_dbg.h"
19 #include "intern/drw_textcodec.h"
20 #include "intern/dwgreader.h"
21 #include "intern/dwgreader15.h"
22 #include "intern/dwgreader18.h"
23 #include "intern/dwgreader21.h"
24 #include "intern/dwgreader24.h"
25 #include "intern/dwgreader27.h"
26
27 #define FIRSTHANDLE 48
28
29 /*enum sections {
30 secUnknown,
31 secHeader,
32 secTables,
33 secBlocks,
34 secEntities,
35 secObjects
36 };*/
37
dwgR(const char * name)38 dwgR::dwgR(const char* name){
39 DRW_DBGSL(DRW_dbg::NONE);
40 fileName = name;
41 reader = NULL;
42 // writer = NULL;
43 applyExt = false;
44 version = DRW::UNKNOWNV;
45 error = DRW::BAD_NONE;
46 }
47
~dwgR()48 dwgR::~dwgR(){
49 if (reader != NULL)
50 delete reader;
51
52 }
53
setDebug(DRW::DBG_LEVEL lvl)54 void dwgR::setDebug(DRW::DBG_LEVEL lvl){
55 switch (lvl){
56 case DRW::DEBUG:
57 DRW_DBGSL(DRW_dbg::DEBUG);
58 break;
59 default:
60 DRW_DBGSL(DRW_dbg::NONE);
61 }
62 }
63
64 /*reads metadata and loads image preview*/
getPreview()65 bool dwgR::getPreview(){
66 bool isOk = false;
67
68 std::ifstream filestr;
69 isOk = openFile(&filestr);
70 if (!isOk)
71 return false;
72
73 isOk = reader->readMetaData();
74 if (isOk) {
75 isOk = reader->readPreview();
76 } else
77 error = DRW::BAD_READ_METADATA;
78
79 filestr.close();
80 if (reader != NULL) {
81 delete reader;
82 reader = NULL;
83 }
84 return isOk;
85 }
86
testReader()87 bool dwgR::testReader(){
88 bool isOk = false;
89
90 std::ifstream filestr;
91 filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary);
92 if (!filestr.is_open() || !filestr.good() ){
93 error = DRW::BAD_OPEN;
94 return isOk;
95 }
96
97 dwgBuffer fileBuf(&filestr);
98 duint8 *tmpStrData = new duint8[fileBuf.size()];
99 fileBuf.getBytes(tmpStrData, fileBuf.size());
100 dwgBuffer dataBuf(tmpStrData, fileBuf.size());
101 fileBuf.setPosition(0);
102 DRW_DBG("\ndwgR::testReader filebuf size: ");DRW_DBG(fileBuf.size());
103 DRW_DBG("\ndwgR::testReader dataBuf size: ");DRW_DBG(dataBuf.size());
104 DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
105 DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
106 DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
107 DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
108 DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
109 DRW_DBG("\n dataBuf first byte : ");DRW_DBGH(dataBuf.getRawChar8());
110 fileBuf.setBitPos(4);
111 dataBuf.setBitPos(4);
112 DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
113 DRW_DBG("\n dataBuf first byte : ");DRW_DBGH(dataBuf.getRawChar8());
114 DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
115 DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
116 DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
117 DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
118 fileBuf.setBitPos(6);
119 dataBuf.setBitPos(6);
120 DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
121 DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
122 DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
123 DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
124 DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
125 DRW_DBG("\n dataBuf first byte : ");DRW_DBGH(dataBuf.getRawChar8());
126 fileBuf.setBitPos(0);
127 dataBuf.setBitPos(0);
128 DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
129 DRW_DBG("\n dataBuf first byte : ");DRW_DBGH(dataBuf.getRawChar8());
130 DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
131 DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
132 DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
133 DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
134
135 delete[]tmpStrData;
136 filestr.close();
137 DRW_DBG("\n\n");
138 return isOk;
139 }
140
141 /*start reading dwg file header and, if can read it, continue reading all*/
read(DRW_Interface * interface_,bool ext)142 bool dwgR::read(DRW_Interface *interface_, bool ext){
143 bool isOk = false;
144 applyExt = ext;
145 iface = interface_;
146
147 //testReader();return false;
148
149 std::ifstream filestr;
150 isOk = openFile(&filestr);
151 if (!isOk)
152 return false;
153
154 isOk = reader->readMetaData();
155 if (isOk) {
156 isOk = reader->readFileHeader();
157 if (isOk) {
158 isOk = processDwg();
159 } else
160 error = DRW::BAD_READ_FILE_HEADER;
161 } else
162 error = DRW::BAD_READ_METADATA;
163
164 filestr.close();
165 if (reader != NULL) {
166 delete reader;
167 reader = NULL;
168 }
169
170 return isOk;
171 }
172
173 /* Open the file and stores it in filestr, install the correct reader version.
174 * If fail opening file, error are set as DRW::BAD_OPEN
175 * If not are DWG or are unsupported version, error are set as DRW::BAD_VERSION
176 * and closes filestr.
177 * Return true on succeed or false on fail
178 */
openFile(std::ifstream * filestr)179 bool dwgR::openFile(std::ifstream *filestr){
180 bool isOk = false;
181 DRW_DBG("dwgR::read 1\n");
182 filestr->open (fileName.c_str(), std::ios_base::in | std::ios::binary);
183 if (!filestr->is_open() || !filestr->good() ){
184 error = DRW::BAD_OPEN;
185 return isOk;
186 }
187
188 char line[7];
189 filestr->read (line, 6);
190 line[6]='\0';
191 DRW_DBG("dwgR::read 2\n");
192 DRW_DBG("dwgR::read line version: ");
193 DRW_DBG(line);
194 DRW_DBG("\n");
195
196 if (strcmp(line, "AC1006") == 0)
197 version = DRW::AC1006;
198 else if (strcmp(line, "AC1009") == 0) {
199 version = DRW::AC1009;
200 // reader = new dwgReader09(&filestr, this);
201 }else if (strcmp(line, "AC1012") == 0){
202 version = DRW::AC1012;
203 reader = new dwgReader15(filestr, this);
204 } else if (strcmp(line, "AC1014") == 0) {
205 version = DRW::AC1014;
206 reader = new dwgReader15(filestr, this);
207 } else if (strcmp(line, "AC1015") == 0) {
208 version = DRW::AC1015;
209 reader = new dwgReader15(filestr, this);
210 } else if (strcmp(line, "AC1018") == 0){
211 version = DRW::AC1018;
212 reader = new dwgReader18(filestr, this);
213 } else if (strcmp(line, "AC1021") == 0) {
214 version = DRW::AC1021;
215 reader = new dwgReader21(filestr, this);
216 } else if (strcmp(line, "AC1024") == 0) {
217 version = DRW::AC1024;
218 reader = new dwgReader24(filestr, this);
219 } else if (strcmp(line, "AC1027") == 0) {
220 version = DRW::AC1027;
221 reader = new dwgReader27(filestr, this);
222 } else
223 version = DRW::UNKNOWNV;
224
225 if (reader == NULL) {
226 error = DRW::BAD_VERSION;
227 filestr->close();
228 } else
229 isOk = true;
230
231 return isOk;
232 }
233
234 /********* Reader Process *********/
235
processDwg()236 bool dwgR::processDwg() {
237 DRW_DBG("dwgR::processDwg() start processing dwg\n");
238 bool ret;
239 bool ret2;
240 DRW_Header hdr;
241 ret = reader->readDwgHeader(hdr);
242 if (!ret) {
243 error = DRW::BAD_READ_HEADER;
244 }
245
246 ret2 = reader->readDwgClasses();
247 if (ret && !ret2) {
248 error = DRW::BAD_READ_CLASSES;
249 ret = ret2;
250 }
251
252 ret2 = reader->readDwgHandles();
253 if (ret && !ret2) {
254 error = DRW::BAD_READ_HANDLES;
255 ret = ret2;
256 }
257
258 ret2 = reader->readDwgTables(hdr);
259 if (ret && !ret2) {
260 error = DRW::BAD_READ_TABLES;
261 ret = ret2;
262 }
263
264 iface->addHeader(&hdr);
265
266 for (std::map<duint32, DRW_LType*>::iterator it=reader->ltypemap.begin(); it!=reader->ltypemap.end(); ++it) {
267 DRW_LType *lt = it->second;
268 iface->addLType(const_cast<DRW_LType&>(*lt) );
269 }
270 for (std::map<duint32, DRW_Layer*>::iterator it=reader->layermap.begin(); it!=reader->layermap.end(); ++it) {
271 DRW_Layer *ly = it->second;
272 iface->addLayer(const_cast<DRW_Layer&>(*ly));
273 }
274
275 for (std::map<duint32, DRW_Textstyle*>::iterator it=reader->stylemap.begin(); it!=reader->stylemap.end(); ++it) {
276 DRW_Textstyle *ly = it->second;
277 iface->addTextStyle(const_cast<DRW_Textstyle&>(*ly));
278 }
279
280 for (std::map<duint32, DRW_Dimstyle*>::iterator it=reader->dimstylemap.begin(); it!=reader->dimstylemap.end(); ++it) {
281 DRW_Dimstyle *ly = it->second;
282 iface->addDimStyle(const_cast<DRW_Dimstyle&>(*ly));
283 }
284
285 for (std::map<duint32, DRW_Vport*>::iterator it=reader->vportmap.begin(); it!=reader->vportmap.end(); ++it) {
286 DRW_Vport *ly = it->second;
287 iface->addVport(const_cast<DRW_Vport&>(*ly));
288 }
289
290 for (std::map<duint32, DRW_AppId*>::iterator it=reader->appIdmap.begin(); it!=reader->appIdmap.end(); ++it) {
291 DRW_AppId *ly = it->second;
292 iface->addAppId(const_cast<DRW_AppId&>(*ly));
293 }
294
295 ret2 = reader->readDwgBlocks(*iface);
296 if (ret && !ret2) {
297 error = DRW::BAD_READ_BLOCKS;
298 ret = ret2;
299 }
300
301 ret2 = reader->readDwgEntities(*iface);
302 if (ret && !ret2) {
303 error = DRW::BAD_READ_ENTITIES;
304 ret = ret2;
305 }
306
307 ret2 = reader->readDwgObjects(*iface);
308 if (ret && !ret2) {
309 error = DRW::BAD_READ_OBJECTS;
310 ret = ret2;
311 }
312
313 return ret;
314 }
315