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