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 <iostream>
15 #include <fstream>
16 #include <string>
17 #include <sstream>
18 #include "dwgreader.h"
19 #include "drw_textcodec.h"
20 #include "drw_dbg.h"
21
~dwgReader()22 dwgReader::~dwgReader(){
23 for (std::map<duint32, DRW_LType*>::iterator it=ltypemap.begin(); it!=ltypemap.end(); ++it)
24 delete(it->second);
25 for (std::map<duint32, DRW_Layer*>::iterator it=layermap.begin(); it!=layermap.end(); ++it)
26 delete(it->second);
27 for (std::map<duint32, DRW_Block*>::iterator it=blockmap.begin(); it!=blockmap.end(); ++it)
28 delete(it->second);
29 for (std::map<duint32, DRW_Textstyle*>::iterator it=stylemap.begin(); it!=stylemap.end(); ++it)
30 delete(it->second);
31 for (std::map<duint32, DRW_Dimstyle*>::iterator it=dimstylemap.begin(); it!=dimstylemap.end(); ++it)
32 delete(it->second);
33 for (std::map<duint32, DRW_Vport*>::iterator it=vportmap.begin(); it!=vportmap.end(); ++it)
34 delete(it->second);
35 for (std::map<duint32, DRW_Class*>::iterator it=classesmap.begin(); it!=classesmap.end(); ++it)
36 delete(it->second);
37 for (std::map<duint32, DRW_Block_Record*>::iterator it=blockRecordmap.begin(); it!=blockRecordmap.end(); ++it)
38 delete(it->second);
39 for (std::map<duint32, DRW_AppId*>::iterator it=appIdmap.begin(); it!=appIdmap.end(); ++it)
40 delete(it->second);
41
42 delete fileBuf;
43 }
44
parseAttribs(DRW_Entity * e)45 void dwgReader::parseAttribs(DRW_Entity* e){
46 if (e != NULL){
47 duint32 ltref =e->lTypeH.ref;
48 duint32 lyref =e->layerH.ref;
49 std::map<duint32, DRW_LType*>::iterator lt_it = ltypemap.find(ltref);
50 if (lt_it != ltypemap.end()){
51 e->lineType = (lt_it->second)->name;
52 }
53 std::map<duint32, DRW_Layer*>::iterator ly_it = layermap.find(lyref);
54 if (ly_it != layermap.end()){
55 e->layer = (ly_it->second)->name;
56 }
57 }
58 }
59
findTableName(DRW::TTYPE table,dint32 handle)60 std::string dwgReader::findTableName(DRW::TTYPE table, dint32 handle){
61 std::string name;
62 switch (table){
63 case DRW::STYLE:{
64 std::map<duint32, DRW_Textstyle*>::iterator st_it = stylemap.find(handle);
65 if (st_it != stylemap.end())
66 name = (st_it->second)->name;
67 break;}
68 case DRW::DIMSTYLE:{
69 std::map<duint32, DRW_Dimstyle*>::iterator ds_it = dimstylemap.find(handle);
70 if (ds_it != dimstylemap.end())
71 name = (ds_it->second)->name;
72 break;}
73 case DRW::BLOCK_RECORD:{ //use DRW_Block because name are more correct
74 // std::map<duint32, DRW_Block*>::iterator bk_it = blockmap.find(handle);
75 // if (bk_it != blockmap.end())
76 std::map<duint32, DRW_Block_Record*>::iterator bk_it = blockRecordmap.find(handle);
77 if (bk_it != blockRecordmap.end())
78 name = (bk_it->second)->name;
79 break;}
80 /* case DRW::VPORT:{
81 std::map<duint32, DRW_Vport*>::iterator vp_it = vportmap.find(handle);
82 if (vp_it != vportmap.end())
83 name = (vp_it->second)->name;
84 break;}*/
85 case DRW::LAYER:{
86 std::map<duint32, DRW_Layer*>::iterator ly_it = layermap.find(handle);
87 if (ly_it != layermap.end())
88 name = (ly_it->second)->name;
89 break;}
90 case DRW::LTYPE:{
91 std::map<duint32, DRW_LType*>::iterator lt_it = ltypemap.find(handle);
92 if (lt_it != ltypemap.end())
93 name = (lt_it->second)->name;
94 break;}
95 default:
96 break;
97 }
98 return name;
99 }
100
readDwgHeader(DRW_Header & hdr,dwgBuffer * buf,dwgBuffer * hBuf)101 bool dwgReader::readDwgHeader(DRW_Header& hdr, dwgBuffer *buf, dwgBuffer *hBuf){
102 bool ret = hdr.parseDwg(version, buf, hBuf, maintenanceVersion);
103 //RLZ: copy objectControl handles
104 return ret;
105 }
106
107 //RLZ: TODO add check instead print
checkSentinel(dwgBuffer * buf,enum secEnum::DWGSection,bool start)108 bool dwgReader::checkSentinel(dwgBuffer *buf, enum secEnum::DWGSection, bool start){
109 DRW_UNUSED(start);
110 for (int i=0; i<16;i++) {
111 DRW_DBGH(buf->getRawChar8()); DRW_DBG(" ");
112 }
113 return true;
114 }
115
116 /*********** objects map ************************/
117 /** Note: object map are split in sections with max size 2035?
118 * heach section are 2 bytes size + data bytes + 2 bytes crc
119 * size value are data bytes + 2 and to calculate crc are used
120 * 2 bytes size + data bytes
121 * last section are 2 bytes size + 2 bytes crc (size value always 2)
122 **/
readDwgHandles(dwgBuffer * dbuf,duint32 offset,duint32 size)123 bool dwgReader::readDwgHandles(dwgBuffer *dbuf, duint32 offset, duint32 size) {
124 DRW_DBG("\ndwgReader::readDwgHandles\n");
125 if (!dbuf->setPosition(offset))
126 return false;
127
128 duint32 maxPos = offset + size;
129 DRW_DBG("\nSection HANDLES offset= "); DRW_DBG(offset);
130 DRW_DBG("\nSection HANDLES size= "); DRW_DBG(size);
131 DRW_DBG("\nSection HANDLES maxPos= "); DRW_DBG(maxPos);
132
133 int startPos = offset;
134
135 while (maxPos > dbuf->getPosition()) {
136 DRW_DBG("\nstart handles section buf->curPosition()= "); DRW_DBG(dbuf->getPosition()); DRW_DBG("\n");
137 duint16 size = dbuf->getBERawShort16();
138 DRW_DBG("object map section size= "); DRW_DBG(size); DRW_DBG("\n");
139 dbuf->setPosition(startPos);
140 duint8 *tmpByteStr = new duint8[size];
141 dbuf->getBytes(tmpByteStr, size);
142 dwgBuffer buff(tmpByteStr, size, &decoder);
143 if (size != 2){
144 buff.setPosition(2);
145 int lastHandle = 0;
146 int lastLoc = 0;
147 //read data
148 while(buff.getPosition()< size){
149 lastHandle += buff.getUModularChar();
150 DRW_DBG("object map lastHandle= "); DRW_DBGH(lastHandle);
151 lastLoc += buff.getModularChar();
152 DRW_DBG(" lastLoc= "); DRW_DBG(lastLoc); DRW_DBG("\n");
153 ObjectMap[lastHandle]= objHandle(0, lastHandle, lastLoc);
154 }
155 }
156 //verify crc
157 duint16 crcCalc = buff.crc8(0xc0c1,0,size);
158 delete[]tmpByteStr;
159 duint16 crcRead = dbuf->getBERawShort16();
160 DRW_DBG("object map section crc8 read= "); DRW_DBG(crcRead);
161 DRW_DBG("\nobject map section crc8 calculated= "); DRW_DBG(crcCalc);
162 DRW_DBG("\nobject section buf->curPosition()= "); DRW_DBG(dbuf->getPosition()); DRW_DBG("\n");
163 startPos = dbuf->getPosition();
164 }
165
166 bool ret = dbuf->isGood();
167 return ret;
168 }
169
170 /*********** objects ************************/
171 /**
172 * Reads all the object referenced in the object map section of the DWG file
173 * (using their object file offsets)
174 */
readDwgTables(DRW_Header & hdr,dwgBuffer * dbuf)175 bool dwgReader::readDwgTables(DRW_Header& hdr, dwgBuffer *dbuf) {
176 DRW_DBG("\ndwgReader::readDwgTables start\n");
177 bool ret = true;
178 bool ret2 = true;
179 objHandle oc;
180 std::map<duint32, objHandle>::iterator mit;
181 dint16 oType;
182 duint32 bs = 0; //bit size of handle stream 2010+
183 duint8 *tmpByteStr;
184
185 //parse linetypes, start with linetype Control
186 mit = ObjectMap.find(hdr.linetypeCtrl);
187 if (mit==ObjectMap.end()) {
188 DRW_DBG("\nWARNING: LineType control not found\n");
189 ret = false;
190 } else {
191 DRW_DBG("\n**********Parsing LineType control*******\n");
192 oc = mit->second;
193 ObjectMap.erase(mit);
194 DRW_ObjControl ltControl;
195 dbuf->setPosition(oc.loc);
196 int csize = dbuf->getModularShort();
197 if (version > DRW::AC1021) //2010+
198 bs = dbuf->getUModularChar();
199 else
200 bs = 0;
201 tmpByteStr = new duint8[csize];
202 dbuf->getBytes(tmpByteStr, csize);
203 dwgBuffer cbuff(tmpByteStr, csize, &decoder);
204 //verify if object are correct
205 oType = cbuff.getObjType(version);
206 if (oType != 0x38) {
207 DRW_DBG("\nWARNING: Not LineType control object, found oType ");
208 DRW_DBG(oType); DRW_DBG(" instead 0x38\n");
209 ret = false;
210 } else { //reset position
211 cbuff.resetPosition();
212 ret2 = ltControl.parseDwg(version, &cbuff, bs);
213 if(ret)
214 ret = ret2;
215 }
216 delete[]tmpByteStr;
217 for (std::list<duint32>::iterator it=ltControl.hadlesList.begin(); it != ltControl.hadlesList.end(); ++it){
218 mit = ObjectMap.find(*it);
219 if (mit==ObjectMap.end()) {
220 DRW_DBG("\nWARNING: LineType not found\n");
221 ret = false;
222 } else {
223 oc = mit->second;
224 ObjectMap.erase(mit);
225 DRW_DBG("\nLineType Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" loc.: "); DRW_DBG(oc.loc); DRW_DBG("\n");
226 DRW_LType *lt = new DRW_LType();
227 dbuf->setPosition(oc.loc);
228 int lsize = dbuf->getModularShort();
229 DRW_DBG("LineType size in bytes= "); DRW_DBG(lsize);
230 if (version > DRW::AC1021) //2010+
231 bs = dbuf->getUModularChar();
232 else
233 bs = 0;
234 tmpByteStr = new duint8[lsize];
235 dbuf->getBytes(tmpByteStr, lsize);
236 dwgBuffer lbuff(tmpByteStr, lsize, &decoder);
237 ret2 = lt->parseDwg(version, &lbuff, bs);
238 ltypemap[lt->handle] = lt;
239 if(ret)
240 ret = ret2;
241 delete[]tmpByteStr;
242 }
243 }
244 }
245
246 //parse layers, start with layer Control
247 mit = ObjectMap.find(hdr.layerCtrl);
248 if (mit==ObjectMap.end()) {
249 DRW_DBG("\nWARNING: Layer control not found\n");
250 ret = false;
251 } else {
252 DRW_DBG("\n**********Parsing Layer control*******\n");
253 oc = mit->second;
254 ObjectMap.erase(mit);
255 DRW_ObjControl layControl;
256 dbuf->setPosition(oc.loc);
257 int size = dbuf->getModularShort();
258 if (version > DRW::AC1021) //2010+
259 bs = dbuf->getUModularChar();
260 else
261 bs = 0;
262 tmpByteStr = new duint8[size];
263 dbuf->getBytes(tmpByteStr, size);
264 dwgBuffer buff(tmpByteStr, size, &decoder);
265 //verify if object are correct
266 oType = buff.getObjType(version);
267 if (oType != 0x32) {
268 DRW_DBG("\nWARNING: Not Layer control object, found oType ");
269 DRW_DBG(oType); DRW_DBG(" instead 0x32\n");
270 ret = false;
271 } else { //reset position
272 buff.resetPosition();
273 ret2 = layControl.parseDwg(version, &buff, bs);
274 if(ret)
275 ret = ret2;
276 }
277 delete[]tmpByteStr;
278 for (std::list<duint32>::iterator it=layControl.hadlesList.begin(); it != layControl.hadlesList.end(); ++it){
279 mit = ObjectMap.find(*it);
280 if (mit==ObjectMap.end()) {
281 DRW_DBG("\nWARNING: Layer not found\n");
282 ret = false;
283 } else {
284 oc = mit->second;
285 ObjectMap.erase(mit);
286 DRW_DBG("Layer Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
287 DRW_Layer *la = new DRW_Layer();
288 dbuf->setPosition(oc.loc);
289 int size = dbuf->getModularShort();
290 if (version > DRW::AC1021) //2010+
291 bs = dbuf->getUModularChar();
292 else
293 bs = 0;
294 tmpByteStr = new duint8[size];
295 dbuf->getBytes(tmpByteStr, size);
296 dwgBuffer buff(tmpByteStr, size, &decoder);
297 ret2 = la->parseDwg(version, &buff, bs);
298 layermap[la->handle] = la;
299 if(ret)
300 ret = ret2;
301 delete[]tmpByteStr;
302 }
303 }
304 }
305
306 //set linetype in layer
307 for (std::map<duint32, DRW_Layer*>::iterator it=layermap.begin(); it!=layermap.end(); ++it) {
308 DRW_Layer *ly = it->second;
309 duint32 ref =ly->lTypeH.ref;
310 std::map<duint32, DRW_LType*>::iterator lt_it = ltypemap.find(ref);
311 if (lt_it != ltypemap.end()){
312 ly->lineType = (lt_it->second)->name;
313 }
314 }
315
316 //parse text styles, start with style Control
317 mit = ObjectMap.find(hdr.styleCtrl);
318 if (mit==ObjectMap.end()) {
319 DRW_DBG("\nWARNING: Style control not found\n");
320 ret = false;
321 } else {
322 DRW_DBG("\n**********Parsing Style control*******\n");
323 oc = mit->second;
324 ObjectMap.erase(mit);
325 DRW_ObjControl styControl;
326 dbuf->setPosition(oc.loc);
327 int size = dbuf->getModularShort();
328 if (version > DRW::AC1021) //2010+
329 bs = dbuf->getUModularChar();
330 else
331 bs = 0;
332 tmpByteStr = new duint8[size];
333 dbuf->getBytes(tmpByteStr, size);
334 dwgBuffer buff(tmpByteStr, size, &decoder);
335 //verify if object are correct
336 oType = buff.getObjType(version);
337 if (oType != 0x34) {
338 DRW_DBG("\nWARNING: Not Text Style control object, found oType ");
339 DRW_DBG(oType); DRW_DBG(" instead 0x34\n");
340 ret = false;
341 } else { //reset position
342 buff.resetPosition();
343 ret2 = styControl.parseDwg(version, &buff, bs);
344 if(ret)
345 ret = ret2;
346 }
347 delete[]tmpByteStr;
348 for (std::list<duint32>::iterator it=styControl.hadlesList.begin(); it != styControl.hadlesList.end(); ++it){
349 mit = ObjectMap.find(*it);
350 if (mit==ObjectMap.end()) {
351 DRW_DBG("\nWARNING: Style not found\n");
352 ret = false;
353 } else {
354 oc = mit->second;
355 ObjectMap.erase(mit);
356 DRW_DBG("Style Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
357 DRW_Textstyle *sty = new DRW_Textstyle();
358 dbuf->setPosition(oc.loc);
359 int size = dbuf->getModularShort();
360 if (version > DRW::AC1021) //2010+
361 bs = dbuf->getUModularChar();
362 else
363 bs = 0;
364 tmpByteStr = new duint8[size];
365 dbuf->getBytes(tmpByteStr, size);
366 dwgBuffer buff(tmpByteStr, size, &decoder);
367 ret2 = sty->parseDwg(version, &buff, bs);
368 stylemap[sty->handle] = sty;
369 if(ret)
370 ret = ret2;
371 delete[]tmpByteStr;
372 }
373 }
374 }
375
376 //parse dim styles, start with dimstyle Control
377 mit = ObjectMap.find(hdr.dimstyleCtrl);
378 if (mit==ObjectMap.end()) {
379 DRW_DBG("\nWARNING: Dimension Style control not found\n");
380 ret = false;
381 } else {
382 DRW_DBG("\n**********Parsing Dimension Style control*******\n");
383 oc = mit->second;
384 ObjectMap.erase(mit);
385 DRW_ObjControl dimstyControl;
386 dbuf->setPosition(oc.loc);
387 duint32 size = dbuf->getModularShort();
388 if (version > DRW::AC1021) //2010+
389 bs = dbuf->getUModularChar();
390 else
391 bs = 0;
392 tmpByteStr = new duint8[size];
393 dbuf->getBytes(tmpByteStr, size);
394 dwgBuffer buff(tmpByteStr, size, &decoder);
395 //verify if object are correct
396 oType = buff.getObjType(version);
397 if (oType != 0x44) {
398 DRW_DBG("\nWARNING: Not Dim Style control object, found oType ");
399 DRW_DBG(oType); DRW_DBG(" instead 0x44\n");
400 ret = false;
401 } else { //reset position
402 buff.resetPosition();
403 ret2 = dimstyControl.parseDwg(version, &buff, bs);
404 if(ret)
405 ret = ret2;
406 }
407 delete[]tmpByteStr;
408 for (std::list<duint32>::iterator it=dimstyControl.hadlesList.begin(); it != dimstyControl.hadlesList.end(); ++it){
409 mit = ObjectMap.find(*it);
410 if (mit==ObjectMap.end()) {
411 DRW_DBG("\nWARNING: Dimension Style not found\n");
412 ret = false;
413 } else {
414 oc = mit->second;
415 ObjectMap.erase(mit);
416 DRW_DBG("Dimstyle Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
417 DRW_Dimstyle *sty = new DRW_Dimstyle();
418 dbuf->setPosition(oc.loc);
419 int size = dbuf->getModularShort();
420 if (version > DRW::AC1021) //2010+
421 bs = dbuf->getUModularChar();
422 else
423 bs = 0;
424 tmpByteStr = new duint8[size];
425 dbuf->getBytes(tmpByteStr, size);
426 dwgBuffer buff(tmpByteStr, size, &decoder);
427 ret2 = sty->parseDwg(version, &buff, bs);
428 dimstylemap[sty->handle] = sty;
429 if(ret)
430 ret = ret2;
431 delete[]tmpByteStr;
432 }
433 }
434 }
435
436 //parse vports, start with vports Control
437 mit = ObjectMap.find(hdr.vportCtrl);
438 if (mit==ObjectMap.end()) {
439 DRW_DBG("\nWARNING: vports control not found\n");
440 ret = false;
441 } else {
442 DRW_DBG("\n**********Parsing vports control*******\n");
443 oc = mit->second;
444 ObjectMap.erase(mit);
445 DRW_ObjControl vportControl;
446 dbuf->setPosition(oc.loc);
447 int size = dbuf->getModularShort();
448 if (version > DRW::AC1021) //2010+
449 bs = dbuf->getUModularChar();
450 else
451 bs = 0;
452 tmpByteStr = new duint8[size];
453 dbuf->getBytes(tmpByteStr, size);
454 dwgBuffer buff(tmpByteStr, size, &decoder);
455 //verify if object are correct
456 oType = buff.getObjType(version);
457 if (oType != 0x40) {
458 DRW_DBG("\nWARNING: Not VPorts control object, found oType: ");
459 DRW_DBG(oType); DRW_DBG(" instead 0x40\n");
460 ret = false;
461 } else { //reset position
462 buff.resetPosition();
463 ret2 = vportControl.parseDwg(version, &buff, bs);
464 if(ret)
465 ret = ret2;
466 }
467 delete[]tmpByteStr;
468 for (std::list<duint32>::iterator it=vportControl.hadlesList.begin(); it != vportControl.hadlesList.end(); ++it){
469 mit = ObjectMap.find(*it);
470 if (mit==ObjectMap.end()) {
471 DRW_DBG("\nWARNING: vport not found\n");
472 ret = false;
473 } else {
474 oc = mit->second;
475 ObjectMap.erase(mit);
476 DRW_DBG("Vport Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
477 DRW_Vport *vp = new DRW_Vport();
478 dbuf->setPosition(oc.loc);
479 int size = dbuf->getModularShort();
480 if (version > DRW::AC1021) //2010+
481 bs = dbuf->getUModularChar();
482 else
483 bs = 0;
484 tmpByteStr = new duint8[size];
485 dbuf->getBytes(tmpByteStr, size);
486 dwgBuffer buff(tmpByteStr, size, &decoder);
487 ret2 = vp->parseDwg(version, &buff, bs);
488 vportmap[vp->handle] = vp;
489 if(ret)
490 ret = ret2;
491 delete[]tmpByteStr;
492 }
493 }
494 }
495
496 //parse Block_records , start with Block_record Control
497 mit = ObjectMap.find(hdr.blockCtrl);
498 if (mit==ObjectMap.end()) {
499 DRW_DBG("\nWARNING: Block_record control not found\n");
500 ret = false;
501 } else {
502 DRW_DBG("\n**********Parsing Block_record control*******\n");
503 oc = mit->second;
504 ObjectMap.erase(mit);
505 DRW_ObjControl blockControl;
506 dbuf->setPosition(oc.loc);
507 int csize = dbuf->getModularShort();
508 if (version > DRW::AC1021) //2010+
509 bs = dbuf->getUModularChar();
510 else
511 bs = 0;
512 tmpByteStr = new duint8[csize];
513 dbuf->getBytes(tmpByteStr, csize);
514 dwgBuffer buff(tmpByteStr, csize, &decoder);
515 //verify if object are correct
516 oType = buff.getObjType(version);
517 if (oType != 0x30) {
518 DRW_DBG("\nWARNING: Not Block Record control object, found oType ");
519 DRW_DBG(oType); DRW_DBG(" instead 0x30\n");
520 ret = false;
521 } else { //reset position
522 buff.resetPosition();
523 ret2 = blockControl.parseDwg(version, &buff, bs);
524 if(ret)
525 ret = ret2;
526 }
527 delete[]tmpByteStr;
528 for (std::list<duint32>::iterator it=blockControl.hadlesList.begin(); it != blockControl.hadlesList.end(); ++it){
529 mit = ObjectMap.find(*it);
530 if (mit==ObjectMap.end()) {
531 DRW_DBG("\nWARNING: block record not found\n");
532 ret = false;
533 } else {
534 oc = mit->second;
535 ObjectMap.erase(mit);
536 DRW_DBG("block record Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
537 DRW_Block_Record *br = new DRW_Block_Record();
538 dbuf->setPosition(oc.loc);
539 int size = dbuf->getModularShort();
540 if (version > DRW::AC1021) //2010+
541 bs = dbuf->getUModularChar();
542 else
543 bs = 0;
544 tmpByteStr = new duint8[size];
545 dbuf->getBytes(tmpByteStr, size);
546 dwgBuffer buff(tmpByteStr, size, &decoder);
547 ret2 = br->parseDwg(version, &buff, bs);
548 blockRecordmap[br->handle] = br;
549 if(ret)
550 ret = ret2;
551 delete[]tmpByteStr;
552 }
553 }
554 }
555
556 //parse appId , start with appId Control
557 mit = ObjectMap.find(hdr.appidCtrl);
558 if (mit==ObjectMap.end()) {
559 DRW_DBG("\nWARNING: AppId control not found\n");
560 ret = false;
561 } else {
562 DRW_DBG("\n**********Parsing AppId control*******\n");
563 oc = mit->second;
564 ObjectMap.erase(mit);
565 DRW_DBG("AppId Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
566 DRW_ObjControl appIdControl;
567 dbuf->setPosition(oc.loc);
568 int size = dbuf->getModularShort();
569 if (version > DRW::AC1021) //2010+
570 bs = dbuf->getUModularChar();
571 else
572 bs = 0;
573 tmpByteStr = new duint8[size];
574 dbuf->getBytes(tmpByteStr, size);
575 dwgBuffer buff(tmpByteStr, size, &decoder);
576 //verify if object are correct
577 oType = buff.getObjType(version);
578 if (oType != 0x42) {
579 DRW_DBG("\nWARNING: Not AppId control object, found oType ");
580 DRW_DBG(oType); DRW_DBG(" instead 0x42\n");
581 ret = false;
582 } else { //reset position
583 buff.resetPosition();
584 ret2 = appIdControl.parseDwg(version, &buff, bs);
585 if(ret)
586 ret = ret2;
587 }
588 delete[]tmpByteStr;
589 for (std::list<duint32>::iterator it=appIdControl.hadlesList.begin(); it != appIdControl.hadlesList.end(); ++it){
590 mit = ObjectMap.find(*it);
591 if (mit==ObjectMap.end()) {
592 DRW_DBG("\nWARNING: AppId not found\n");
593 ret = false;
594 } else {
595 oc = mit->second;
596 ObjectMap.erase(mit);
597 DRW_DBG("AppId Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
598 DRW_AppId *ai = new DRW_AppId();
599 dbuf->setPosition(oc.loc);
600 int size = dbuf->getModularShort();
601 if (version > DRW::AC1021) //2010+
602 bs = dbuf->getUModularChar();
603 else
604 bs = 0;
605 tmpByteStr = new duint8[size];
606 dbuf->getBytes(tmpByteStr, size);
607 dwgBuffer buff(tmpByteStr, size, &decoder);
608 ret2 = ai->parseDwg(version, &buff, bs);
609 appIdmap[ai->handle] = ai;
610 if(ret)
611 ret = ret2;
612 delete[]tmpByteStr;
613 }
614 }
615 }
616
617 //RLZ: parse remaining object controls, TODO: implement all
618 if (DRW_DBGGL == DRW_dbg::DEBUG){
619 mit = ObjectMap.find(hdr.viewCtrl);
620 if (mit==ObjectMap.end()) {
621 DRW_DBG("\nWARNING: View control not found\n");
622 ret = false;
623 } else {
624 DRW_DBG("\n**********Parsing View control*******\n");
625 oc = mit->second;
626 ObjectMap.erase(mit);
627 DRW_DBG("View Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
628 DRW_ObjControl viewControl;
629 dbuf->setPosition(oc.loc);
630 int size = dbuf->getModularShort();
631 if (version > DRW::AC1021) //2010+
632 bs = dbuf->getUModularChar();
633 else
634 bs = 0;
635 tmpByteStr = new duint8[size];
636 dbuf->getBytes(tmpByteStr, size);
637 dwgBuffer buff(tmpByteStr, size, &decoder);
638 //verify if object are correct
639 oType = buff.getObjType(version);
640 if (oType != 0x3C) {
641 DRW_DBG("\nWARNING: Not View control object, found oType ");
642 DRW_DBG(oType); DRW_DBG(" instead 0x3C\n");
643 ret = false;
644 } else { //reset position
645 buff.resetPosition();
646 ret2 = viewControl.parseDwg(version, &buff, bs);
647 if(ret)
648 ret = ret2;
649 }
650 delete[]tmpByteStr;
651 }
652
653 mit = ObjectMap.find(hdr.ucsCtrl);
654 if (mit==ObjectMap.end()) {
655 DRW_DBG("\nWARNING: Ucs control not found\n");
656 ret = false;
657 } else {
658 oc = mit->second;
659 ObjectMap.erase(mit);
660 DRW_DBG("\n**********Parsing Ucs control*******\n");
661 DRW_DBG("Ucs Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
662 DRW_ObjControl ucsControl;
663 dbuf->setPosition(oc.loc);
664 int size = dbuf->getModularShort();
665 if (version > DRW::AC1021) //2010+
666 bs = dbuf->getUModularChar();
667 else
668 bs = 0;
669 tmpByteStr = new duint8[size];
670 dbuf->getBytes(tmpByteStr, size);
671 dwgBuffer buff(tmpByteStr, size, &decoder);
672 //verify if object are correct
673 oType = buff.getObjType(version);
674 if (oType != 0x3E) {
675 DRW_DBG("\nWARNING: Not Ucs control object, found oType ");
676 DRW_DBG(oType); DRW_DBG(" instead 0x3E\n");
677 ret = false;
678 } else { //reset position
679 buff.resetPosition();
680 ret2 = ucsControl.parseDwg(version, &buff, bs);
681 if(ret)
682 ret = ret2;
683 }
684 delete[]tmpByteStr;
685 }
686
687 if (version < DRW::AC1018) {//r2000-
688 mit = ObjectMap.find(hdr.vpEntHeaderCtrl);
689 if (mit==ObjectMap.end()) {
690 DRW_DBG("\nWARNING: vpEntHeader control not found\n");
691 ret = false;
692 } else {
693 DRW_DBG("\n**********Parsing vpEntHeader control*******\n");
694 oc = mit->second;
695 ObjectMap.erase(mit);
696 DRW_DBG("vpEntHeader Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n");
697 DRW_ObjControl vpEntHeaderCtrl;
698 dbuf->setPosition(oc.loc);
699 int size = dbuf->getModularShort();
700 if (version > DRW::AC1021) //2010+
701 bs = dbuf->getUModularChar();
702 else
703 bs = 0;
704 tmpByteStr = new duint8[size];
705 dbuf->getBytes(tmpByteStr, size);
706 dwgBuffer buff(tmpByteStr, size, &decoder);
707 //verify if object are correct
708 oType = buff.getObjType(version);
709 if (oType != 0x46) {
710 DRW_DBG("\nWARNING: Not vpEntHeader control object, found oType ");
711 DRW_DBG(oType); DRW_DBG(" instead 0x46\n");
712 ret = false;
713 } else { //reset position
714 buff.resetPosition();
715 /* RLZ: writeme ret2 = vpEntHeader.parseDwg(version, &buff, bs);
716 if(ret)
717 ret = ret2;*/
718 }
719 delete[]tmpByteStr;
720 }
721 }
722 }
723
724 return ret;
725 }
726
readDwgBlocks(DRW_Interface & intfa,dwgBuffer * dbuf)727 bool dwgReader::readDwgBlocks(DRW_Interface& intfa, dwgBuffer *dbuf){
728 bool ret = true;
729 bool ret2 = true;
730 duint32 bs =0;
731 duint8 *tmpByteStr;
732 std::map<duint32, objHandle>::iterator mit;
733 DRW_DBG("\nobject map total size= "); DRW_DBG(ObjectMap.size());
734
735 for (std::map<duint32, DRW_Block_Record*>::iterator it=blockRecordmap.begin(); it != blockRecordmap.end(); ++it){
736 DRW_Block_Record* bkr= it->second;
737 DRW_DBG("\nParsing Block, record handle= "); DRW_DBGH(it->first); DRW_DBG(" Name= "); DRW_DBG(bkr->name); DRW_DBG("\n");
738 DRW_DBG("\nFinding Block, handle= "); DRW_DBGH(bkr->block); DRW_DBG("\n");
739 mit = ObjectMap.find(bkr->block);
740 if (mit==ObjectMap.end()) {
741 DRW_DBG("\nWARNING: block entity not found\n");
742 ret = false;
743 continue;
744 }
745 objHandle oc = mit->second;
746 ObjectMap.erase(mit);
747 DRW_DBG("Block Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" Location: "); DRW_DBG(oc.loc); DRW_DBG("\n");
748 if ( !(dbuf->setPosition(oc.loc)) ){
749 DRW_DBG("Bad Location reading blocks\n");
750 ret = false;
751 continue;
752 }
753 int size = dbuf->getModularShort();
754 if (version > DRW::AC1021) //2010+
755 bs = dbuf->getUModularChar();
756 else
757 bs = 0;
758 tmpByteStr = new duint8[size];
759 dbuf->getBytes(tmpByteStr, size);
760 dwgBuffer buff(tmpByteStr, size, &decoder);
761 DRW_Block bk;
762 ret2 = bk.parseDwg(version, &buff, bs);
763 delete[]tmpByteStr;
764 ret = ret && ret2;
765 parseAttribs(&bk);
766 //complete block entity with block record data
767 bk.basePoint = bkr->basePoint;
768 bk.flags = bkr->flags;
769 intfa.addBlock(bk);
770 //and update block record name
771 bkr->name = bk.name;
772
773 /**read & send block entities**/
774 // in dwg code 330 are not set like dxf in ModelSpace & PaperSpace, set it (RLZ: only tested in 2000)
775 if (bk.parentHandle == DRW::NoHandle) {
776 // in dwg code 330 are not set like dxf in ModelSpace & PaperSpace, set it
777 bk.parentHandle= bkr->handle;
778 //and do not send block entities like dxf
779 } else {
780 if (version < DRW::AC1018) { //pre 2004
781 duint32 nextH = bkr->firstEH;
782 while (nextH != 0){
783 mit = ObjectMap.find(nextH);
784 if (mit==ObjectMap.end()) {
785 nextH = bkr->lastEH;//end while if entity not foud
786 DRW_DBG("\nWARNING: Entity of block not found\n");
787 ret = false;
788 continue;
789 } else {//foud entity reads it
790 oc = mit->second;
791 ObjectMap.erase(mit);
792 ret2 = readDwgEntity(dbuf, oc, intfa);
793 ret = ret && ret2;
794 }
795 if (nextH == bkr->lastEH)
796 nextH = 0; //redundant, but prevent read errors
797 else
798 nextH = nextEntLink;
799 }
800 } else {//2004+
801 for (std::vector<duint32>::iterator it = bkr->entMap.begin() ; it != bkr->entMap.end(); ++it){
802 duint32 nextH = *it;
803 mit = ObjectMap.find(nextH);
804 if (mit==ObjectMap.end()) {
805 DRW_DBG("\nWARNING: Entity of block not found\n");
806 ret = false;
807 continue;
808 } else {//foud entity reads it
809 oc = mit->second;
810 ObjectMap.erase(mit);
811 DRW_DBG("\nBlocks, parsing entity: "); DRW_DBGH(oc.handle); DRW_DBG(", pos: "); DRW_DBG(oc.loc); DRW_DBG("\n");
812 ret2 = readDwgEntity(dbuf, oc, intfa);
813 ret = ret && ret2;
814 }
815 }
816 }//end 2004+
817 }
818
819 //end block entity, really needed to parse a dummy entity??
820 mit = ObjectMap.find(bkr->endBlock);
821 if (mit==ObjectMap.end()) {
822 DRW_DBG("\nWARNING: end block entity not found\n");
823 ret = false;
824 continue;
825 }
826 oc = mit->second;
827 ObjectMap.erase(mit);
828 DRW_DBG("End block Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" Location: "); DRW_DBG(oc.loc); DRW_DBG("\n");
829 dbuf->setPosition(oc.loc);
830 size = dbuf->getModularShort();
831 if (version > DRW::AC1021) //2010+
832 bs = dbuf->getUModularChar();
833 else
834 bs = 0;
835 tmpByteStr = new duint8[size];
836 dbuf->getBytes(tmpByteStr, size);
837 dwgBuffer buff1(tmpByteStr, size, &decoder);
838 DRW_Block end;
839 end.isEnd = true;
840 ret2 = end.parseDwg(version, &buff1, bs);
841 delete[]tmpByteStr;
842 ret = ret && ret2;
843 if (bk.parentHandle == DRW::NoHandle) bk.parentHandle= bkr->handle;
844 parseAttribs(&end);
845 intfa.endBlock();
846 }
847
848 return ret;
849 }
850
readPlineVertex(DRW_Polyline & pline,dwgBuffer * dbuf)851 bool dwgReader::readPlineVertex(DRW_Polyline& pline, dwgBuffer *dbuf){
852 bool ret = true;
853 bool ret2 = true;
854 objHandle oc;
855 duint32 bs = 0;
856 std::map<duint32, objHandle>::iterator mit;
857
858 if (version < DRW::AC1018) { //pre 2004
859 duint32 nextH = pline.firstEH;
860 while (nextH != 0){
861 mit = ObjectMap.find(nextH);
862 if (mit==ObjectMap.end()) {
863 nextH = pline.lastEH;//end while if entity not foud
864 DRW_DBG("\nWARNING: pline vertex not found\n");
865 ret = false;
866 continue;
867 } else {//foud entity reads it
868 oc = mit->second;
869 ObjectMap.erase(mit);
870 DRW_Vertex vt;
871 dbuf->setPosition(oc.loc);
872 //RLZ: verify if pos is ok
873 int size = dbuf->getModularShort();
874 if (version > DRW::AC1021) {//2010+
875 bs = dbuf->getUModularChar();
876 }
877 duint8 *tmpByteStr = new duint8[size];
878 dbuf->getBytes(tmpByteStr, size);
879 dwgBuffer buff(tmpByteStr, size, &decoder);
880 dint16 oType = buff.getObjType(version);
881 buff.resetPosition();
882 DRW_DBG(" object type= "); DRW_DBG(oType); DRW_DBG("\n");
883 ret2 = vt.parseDwg(version, &buff, bs, pline.basePoint.z);
884 delete[]tmpByteStr;
885 pline.addVertex(vt);
886 nextEntLink = vt.nextEntLink; \
887 prevEntLink = vt.prevEntLink;
888 ret = ret && ret2;
889 }
890 if (nextH == pline.lastEH)
891 nextH = 0; //redundant, but prevent read errors
892 else
893 nextH = nextEntLink;
894 }
895 } else {//2004+
896 for (std::list<duint32>::iterator it = pline.hadlesList.begin() ; it != pline.hadlesList.end(); ++it){
897 duint32 nextH = *it;
898 mit = ObjectMap.find(nextH);
899 if (mit==ObjectMap.end()) {
900 DRW_DBG("\nWARNING: Entity of block not found\n");
901 ret = false;
902 continue;
903 } else {//foud entity reads it
904 oc = mit->second;
905 ObjectMap.erase(mit);
906 DRW_DBG("\nPline vertex, parsing entity: "); DRW_DBGH(oc.handle); DRW_DBG(", pos: "); DRW_DBG(oc.loc); DRW_DBG("\n");
907 DRW_Vertex vt;
908 dbuf->setPosition(oc.loc);
909 //RLZ: verify if pos is ok
910 int size = dbuf->getModularShort();
911 if (version > DRW::AC1021) {//2010+
912 bs = dbuf->getUModularChar();
913 }
914 duint8 *tmpByteStr = new duint8[size];
915 dbuf->getBytes(tmpByteStr, size);
916 dwgBuffer buff(tmpByteStr, size, &decoder);
917 dint16 oType = buff.getObjType(version);
918 buff.resetPosition();
919 DRW_DBG(" object type= "); DRW_DBG(oType); DRW_DBG("\n");
920 ret2 = vt.parseDwg(version, &buff, bs, pline.basePoint.z);
921 delete[]tmpByteStr;
922 pline.addVertex(vt);
923 nextEntLink = vt.nextEntLink; \
924 prevEntLink = vt.prevEntLink;
925 ret = ret && ret2;
926 }
927 }
928 }//end 2004+
929 DRW_DBG("\nRemoved SEQEND entity: "); DRW_DBGH(pline.seqEndH.ref);DRW_DBG("\n");
930 ObjectMap.erase(pline.seqEndH.ref);
931
932 return ret;
933 }
934
readDwgEntities(DRW_Interface & intfa,dwgBuffer * dbuf)935 bool dwgReader::readDwgEntities(DRW_Interface& intfa, dwgBuffer *dbuf){
936 bool ret = true;
937 bool ret2 = true;
938
939 DRW_DBG("\nobject map total size= "); DRW_DBG(ObjectMap.size());
940 std::map<duint32, objHandle>::iterator itB=ObjectMap.begin();
941 std::map<duint32, objHandle>::iterator itE=ObjectMap.end();
942 while (itB != itE){
943 ret2 = readDwgEntity(dbuf, itB->second, intfa);
944 ObjectMap.erase(itB);
945 itB=ObjectMap.begin();
946 if (ret)
947 ret = ret2;
948 }
949 return ret;
950 }
951
952 /**
953 * Reads a dwg drawing entity (dwg object entity) given its offset in the file
954 */
readDwgEntity(dwgBuffer * dbuf,objHandle & obj,DRW_Interface & intfa)955 bool dwgReader::readDwgEntity(dwgBuffer *dbuf, objHandle& obj, DRW_Interface& intfa){
956 bool ret = true;
957 duint32 bs = 0;
958
959 #define ENTRY_PARSE(e) \
960 ret = e.parseDwg(version, &buff, bs); \
961 parseAttribs(&e); \
962 nextEntLink = e.nextEntLink; \
963 prevEntLink = e.prevEntLink;
964
965 nextEntLink = prevEntLink = 0;// set to 0 to skip unimplemented entities
966 dbuf->setPosition(obj.loc);
967 //verify if position is ok:
968 if (!dbuf->isGood()){
969 DRW_DBG(" Warning: readDwgEntity, bad location\n");
970 return false;
971 }
972 int size = dbuf->getModularShort();
973 if (version > DRW::AC1021) {//2010+
974 bs = dbuf->getUModularChar();
975 }
976 duint8 *tmpByteStr = new duint8[size];
977 dbuf->getBytes(tmpByteStr, size);
978 //verify if getBytes is ok:
979 if (!dbuf->isGood()){
980 DRW_DBG(" Warning: readDwgEntity, bad size\n");
981 delete[]tmpByteStr;
982 return false;
983 }
984 dwgBuffer buff(tmpByteStr, size, &decoder);
985 dint16 oType = buff.getObjType(version);
986 buff.resetPosition();
987
988 if (oType > 499){
989 std::map<duint32, DRW_Class*>::iterator it = classesmap.find(oType);
990 if (it == classesmap.end()){//fail, not found in classes set error
991 DRW_DBG("Class "); DRW_DBG(oType);DRW_DBG("not found, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n");
992 delete[]tmpByteStr;
993 return false;
994 } else {
995 DRW_Class *cl = it->second;
996 if (cl->dwgType != 0)
997 oType = cl->dwgType;
998 }
999 }
1000
1001 obj.type = oType;
1002 switch (oType){
1003 case 17: {
1004 DRW_Arc e;
1005 ENTRY_PARSE(e)
1006 intfa.addArc(e);
1007 break; }
1008 case 18: {
1009 DRW_Circle e;
1010 ENTRY_PARSE(e)
1011 intfa.addCircle(e);
1012 break; }
1013 case 19:{
1014 DRW_Line e;
1015 ENTRY_PARSE(e)
1016 intfa.addLine(e);
1017 break;}
1018 case 27: {
1019 DRW_Point e;
1020 ENTRY_PARSE(e)
1021 intfa.addPoint(e);
1022 break; }
1023 case 35: {
1024 DRW_Ellipse e;
1025 ENTRY_PARSE(e)
1026 intfa.addEllipse(e);
1027 break; }
1028 case 7:
1029 case 8: {//minsert = 8
1030 DRW_Insert e;
1031 ENTRY_PARSE(e)
1032 e.name = findTableName(DRW::BLOCK_RECORD, e.blockRecH.ref);//RLZ: find as block or blockrecord (ps & ps0)
1033 intfa.addInsert(e);
1034 break; }
1035 case 77: {
1036 DRW_LWPolyline e;
1037 ENTRY_PARSE(e)
1038 intfa.addLWPolyline(e);
1039 break; }
1040 case 1: {
1041 DRW_Text e;
1042 ENTRY_PARSE(e)
1043 e.style = findTableName(DRW::STYLE, e.styleH.ref);
1044 intfa.addText(e);
1045 break; }
1046 case 44: {
1047 DRW_MText e;
1048 ENTRY_PARSE(e)
1049 e.style = findTableName(DRW::STYLE, e.styleH.ref);
1050 intfa.addMText(e);
1051 break; }
1052 case 28: {
1053 DRW_3Dface e;
1054 ENTRY_PARSE(e)
1055 intfa.add3dFace(e);
1056 break; }
1057 case 20: {
1058 DRW_DimOrdinate e;
1059 ENTRY_PARSE(e)
1060 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1061 intfa.addDimOrdinate(&e);
1062 break; }
1063 case 21: {
1064 DRW_DimLinear e;
1065 ENTRY_PARSE(e)
1066 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1067 intfa.addDimLinear(&e);
1068 break; }
1069 case 22: {
1070 DRW_DimAligned e;
1071 ENTRY_PARSE(e)
1072 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1073 intfa.addDimAlign(&e);
1074 break; }
1075 case 23: {
1076 DRW_DimAngular3p e;
1077 ENTRY_PARSE(e)
1078 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1079 intfa.addDimAngular3P(&e);
1080 break; }
1081 case 24: {
1082 DRW_DimAngular e;
1083 ENTRY_PARSE(e)
1084 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1085 intfa.addDimAngular(&e);
1086 break; }
1087 case 25: {
1088 DRW_DimRadial e;
1089 ENTRY_PARSE(e)
1090 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1091 intfa.addDimRadial(&e);
1092 break; }
1093 case 26: {
1094 DRW_DimDiametric e;
1095 ENTRY_PARSE(e)
1096 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1097 intfa.addDimDiametric(&e);
1098 break; }
1099 case 45: {
1100 DRW_Leader e;
1101 ENTRY_PARSE(e)
1102 e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref);
1103 intfa.addLeader(&e);
1104 break; }
1105 case 31: {
1106 DRW_Solid e;
1107 ENTRY_PARSE(e)
1108 intfa.addSolid(e);
1109 break; }
1110 case 78: {
1111 DRW_Hatch e;
1112 ENTRY_PARSE(e)
1113 intfa.addHatch(&e);
1114 break; }
1115 case 32: {
1116 DRW_Trace e;
1117 ENTRY_PARSE(e)
1118 intfa.addTrace(e);
1119 break; }
1120 case 34: {
1121 DRW_Viewport e;
1122 ENTRY_PARSE(e)
1123 intfa.addViewport(e);
1124 break; }
1125 case 36: {
1126 DRW_Spline e;
1127 ENTRY_PARSE(e)
1128 intfa.addSpline(&e);
1129 break; }
1130 case 40: {
1131 DRW_Ray e;
1132 ENTRY_PARSE(e)
1133 intfa.addRay(e);
1134 break; }
1135 case 15: // pline 2D
1136 case 16: // pline 3D
1137 case 29: { // pline PFACE
1138 DRW_Polyline e;
1139 ENTRY_PARSE(e)
1140 readPlineVertex(e, dbuf);
1141 intfa.addPolyline(e);
1142 break; }
1143 // case 30: {
1144 // DRW_Polyline e;// MESH (not pline)
1145 // ENTRY_PARSE(e)
1146 // intfa.addRay(e);
1147 // break; }
1148 case 41: {
1149 DRW_Xline e;
1150 ENTRY_PARSE(e)
1151 intfa.addXline(e);
1152 break; }
1153 case 101: {
1154 DRW_Image e;
1155 ENTRY_PARSE(e)
1156 intfa.addImage(&e);
1157 break; }
1158
1159 default:
1160 //not supported or are object add to remaining map
1161 objObjectMap[obj.handle]= obj;
1162 break;
1163 }
1164 if (!ret){
1165 DRW_DBG("Warning: Entity type "); DRW_DBG(oType);DRW_DBG("has failed, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n");
1166 }
1167 delete[]tmpByteStr;
1168 return ret;
1169 }
1170
readDwgObjects(DRW_Interface & intfa,dwgBuffer * dbuf)1171 bool dwgReader::readDwgObjects(DRW_Interface& intfa, dwgBuffer *dbuf){
1172 bool ret = true;
1173 bool ret2 = true;
1174
1175 duint32 i=0;
1176 DRW_DBG("\nentities map total size= "); DRW_DBG(ObjectMap.size());
1177 DRW_DBG("\nobjects map total size= "); DRW_DBG(objObjectMap.size());
1178 std::map<duint32, objHandle>::iterator itB=objObjectMap.begin();
1179 std::map<duint32, objHandle>::iterator itE=objObjectMap.end();
1180 while (itB != itE){
1181 ret2 = readDwgObject(dbuf, itB->second, intfa);
1182 objObjectMap.erase(itB);
1183 itB=objObjectMap.begin();
1184 if (ret)
1185 ret = ret2;
1186 }
1187 if (DRW_DBGGL == DRW_dbg::DEBUG) {
1188 for (std::map<duint32, objHandle>::iterator it=remainingMap.begin(); it != remainingMap.end(); ++it){
1189 DRW_DBG("\nnum.# "); DRW_DBG(i++); DRW_DBG(" Remaining object Handle, loc, type= "); DRW_DBG(it->first);
1190 DRW_DBG(" "); DRW_DBG(it->second.loc); DRW_DBG(" "); DRW_DBG(it->second.type);
1191 }
1192 DRW_DBG("\n");
1193 }
1194 return ret;
1195 }
1196
1197 /**
1198 * Reads a dwg drawing object (dwg object object) given its offset in the file
1199 */
readDwgObject(dwgBuffer * dbuf,objHandle & obj,DRW_Interface & intfa)1200 bool dwgReader::readDwgObject(dwgBuffer *dbuf, objHandle& obj, DRW_Interface& intfa){
1201 bool ret = true;
1202 duint32 bs = 0;
1203
1204 dbuf->setPosition(obj.loc);
1205 //verify if position is ok:
1206 if (!dbuf->isGood()){
1207 DRW_DBG(" Warning: readDwgObject, bad location\n");
1208 return false;
1209 }
1210 int size = dbuf->getModularShort();
1211 if (version > DRW::AC1021) {//2010+
1212 bs = dbuf->getUModularChar();
1213 }
1214 duint8 *tmpByteStr = new duint8[size];
1215 dbuf->getBytes(tmpByteStr, size);
1216 //verify if getBytes is ok:
1217 if (!dbuf->isGood()){
1218 DRW_DBG(" Warning: readDwgObject, bad size\n");
1219 delete[]tmpByteStr;
1220 return false;
1221 }
1222 dwgBuffer buff(tmpByteStr, size, &decoder);
1223 //oType are set parsing entities
1224 dint16 oType = obj.type;
1225
1226 switch (oType){
1227 case 102: {
1228 DRW_ImageDef e;
1229 ret = e.parseDwg(version, &buff, bs);
1230 intfa.linkImage(&e);
1231 break; }
1232 default:
1233 //not supported object or entity add to remaining map for debug
1234 remainingMap[obj.handle]= obj;
1235 break;
1236 }
1237 if (!ret){
1238 DRW_DBG("Warning: Object type "); DRW_DBG(oType);DRW_DBG("has failed, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n");
1239 }
1240 delete[]tmpByteStr;
1241 return ret;
1242 }
1243
1244
1245
parseDwg(DRW::Version version,dwgBuffer * buf,duint32 bs)1246 bool DRW_ObjControl::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){
1247 int unkData=0;
1248 bool ret = DRW_TableEntry::parseDwg(version, buf, NULL, bs);
1249 DRW_DBG("\n***************************** parsing object control entry *********************************************\n");
1250 if (!ret)
1251 return ret;
1252 //last parsed is: XDic Missing Flag 2004+
1253 int numEntries = buf->getBitLong();
1254 DRW_DBG(" num entries: "); DRW_DBG(numEntries); DRW_DBG("\n");
1255 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1256
1257 // if (oType == 68 && version== DRW::AC1015){//V2000 dimstyle seems have one unknown byte hard handle counter??
1258 if (oType == 68 && version > DRW::AC1014){//dimstyle seems have one unknown byte hard handle counter??
1259 unkData = buf->getRawChar8();
1260 DRW_DBG(" unknown v2000 byte: "); DRW_DBG( unkData); DRW_DBG("\n");
1261 }
1262 if (version > DRW::AC1018){//from v2007+ have a bit for strings follows (ObjControl do not have)
1263 int stringBit = buf->getBit();
1264 DRW_DBG(" string bit for v2007+: "); DRW_DBG( stringBit); DRW_DBG("\n");
1265 }
1266
1267 dwgHandle objectH = buf->getHandle();
1268 DRW_DBG(" NULL Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n");
1269 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1270
1271 // if (oType == 56 && version== DRW::AC1015){//linetype in 2004 seems not have XDicObjH or NULL handle
1272 if (xDictFlag !=1){//linetype in 2004 seems not have XDicObjH or NULL handle
1273 dwgHandle XDicObjH = buf->getHandle();
1274 DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n");
1275 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1276 }
1277 //add 2 for modelspace, paperspace blocks & bylayer, byblock linetypes
1278 numEntries = ((oType == 48) || (oType == 56)) ? (numEntries +2) : numEntries;
1279
1280 for (int i =0; i< numEntries; i++){
1281 objectH = buf->getOffsetHandle(handle);
1282 if (objectH.ref != 0) //in vports R14 I found some NULL handles
1283 hadlesList.push_back (objectH.ref);
1284 DRW_DBG(" objectH Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n");
1285 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1286 }
1287
1288 for (int i =0; i< unkData; i++){
1289 objectH = buf->getOffsetHandle(handle);
1290 DRW_DBG(" unknown Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n");
1291 DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n");
1292 }
1293 return buf->isGood();
1294 }
1295