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