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