1 /******************************************************************************
2 **  libDXFrw - Library to read/write DXF files (ascii & binary)              **
3 **                                                                           **
4 **  Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com               **
5 **                                                                           **
6 **  This library is free software, licensed under the terms of the GNU       **
7 **  General Public License as published by the Free Software Foundation,     **
8 **  either version 2 of the License, or (at your option) any later version.  **
9 **  You should have received a copy of the GNU General Public License        **
10 **  along with this program.  If not, see <http://www.gnu.org/licenses/>.    **
11 ******************************************************************************/
12 
13 
14 #include "libdwgr.h"
15 #include <fstream>
16 #include <algorithm>
17 #include <sstream>
18 #include "intern/drw_dbg.h"
19 #include "intern/drw_textcodec.h"
20 #include "intern/dwgreader.h"
21 #include "intern/dwgreader15.h"
22 #include "intern/dwgreader18.h"
23 #include "intern/dwgreader21.h"
24 #include "intern/dwgreader24.h"
25 #include "intern/dwgreader27.h"
26 
27 #define FIRSTHANDLE 48
28 
29 /*enum sections {
30     secUnknown,
31     secHeader,
32     secTables,
33     secBlocks,
34     secEntities,
35     secObjects
36 };*/
37 
dwgR()38 dwgR::dwgR(){
39     DRW_DBGSL(DRW_dbg::NONE);
40     reader = NULL;
41 //    writer = NULL;
42     applyExt = false;
43     version = DRW::UNKNOWNV;
44     error = DRW::BAD_NONE;
45 }
46 
~dwgR()47 dwgR::~dwgR(){
48     if (reader != NULL)
49         delete reader;
50 
51 }
52 
setDebug(DRW::DBG_LEVEL lvl)53 void dwgR::setDebug(DRW::DBG_LEVEL lvl){
54     switch (lvl){
55     case DRW::DEBUG:
56         DRW_DBGSL(DRW_dbg::DEBUG);
57         break;
58     default:
59         DRW_DBGSL(DRW_dbg::NONE);
60     }
61 }
62 
63 /*reads metadata and loads image preview*/
getPreview(std::istream & stream)64 bool dwgR::getPreview(std::istream &stream){
65     bool isOk = false;
66 
67     isOk = open(&stream);
68     if (!isOk)
69         return false;
70 
71     isOk = reader->readMetaData();
72     if (isOk) {
73         isOk = reader->readPreview();
74     } else
75         error = DRW::BAD_READ_METADATA;
76 
77     if (reader != NULL) {
78         delete reader;
79         reader = NULL;
80     }
81     return isOk;
82 }
83 
read(std::istream & stream,DRW_Interface * interface_,bool ext)84 bool dwgR::read(std::istream &stream, DRW_Interface *interface_, bool ext){
85     applyExt = ext;
86     iface = interface_;
87 
88     bool isOk = false;
89 
90     isOk = open(&stream);
91     if (!isOk)
92         return false;
93 
94     isOk = reader->readMetaData();
95     if (isOk) {
96         isOk = reader->readFileHeader();
97         if (isOk) {
98             isOk = processDwg();
99         } else
100             error = DRW::BAD_READ_FILE_HEADER;
101     } else
102         error = DRW::BAD_READ_METADATA;
103 
104     if (reader != NULL) {
105         delete reader;
106         reader = NULL;
107     }
108 
109     return isOk;
110 }
111 
open(std::istream * stream)112 bool dwgR::open(std::istream *stream){
113     char line[7];
114     stream->read (line, 6);
115     line[6]='\0';
116     DRW_DBG("dwgR::read 2\n");
117     DRW_DBG("dwgR::read line version: ");
118     DRW_DBG(line);
119     DRW_DBG("\n");
120 
121     if (strcmp(line, "AC1006") == 0)
122         version = DRW::AC1006;
123     else if (strcmp(line, "AC1009") == 0) {
124         version = DRW::AC1009;
125 //        reader = new dwgReader09(&filestr, this);
126     }else if (strcmp(line, "AC1012") == 0){
127         version = DRW::AC1012;
128         reader = new dwgReader15(stream, this);
129     } else if (strcmp(line, "AC1014") == 0) {
130         version = DRW::AC1014;
131         reader = new dwgReader15(stream, this);
132     } else if (strcmp(line, "AC1015") == 0) {
133         version = DRW::AC1015;
134         reader = new dwgReader15(stream, this);
135     } else if (strcmp(line, "AC1018") == 0){
136         version = DRW::AC1018;
137         reader = new dwgReader18(stream, this);
138     } else if (strcmp(line, "AC1021") == 0) {
139         version = DRW::AC1021;
140         reader = new dwgReader21(stream, this);
141     } else if (strcmp(line, "AC1024") == 0) {
142         version = DRW::AC1024;
143         reader = new dwgReader24(stream, this);
144     } else if (strcmp(line, "AC1027") == 0) {
145         version = DRW::AC1027;
146         reader = new dwgReader27(stream, this);
147     } else
148         version = DRW::UNKNOWNV;
149 
150     if (reader == NULL) {
151         error = DRW::BAD_VERSION;
152         return false;
153     }
154     return true;
155 }
156 
157 /********* Reader Process *********/
158 
processDwg()159 bool dwgR::processDwg() {
160     DRW_DBG("dwgR::processDwg() start processing dwg\n");
161     bool ret;
162     bool ret2;
163     DRW_Header hdr;
164     ret = reader->readDwgHeader(hdr);
165     if (!ret) {
166         error = DRW::BAD_READ_HEADER;
167     }
168 
169     ret2 = reader->readDwgClasses();
170     if (ret && !ret2) {
171         error = DRW::BAD_READ_CLASSES;
172         ret = ret2;
173     }
174 
175     ret2 = reader->readDwgHandles();
176     if (ret && !ret2) {
177         error = DRW::BAD_READ_HANDLES;
178         ret = ret2;
179     }
180 
181     ret2 = reader->readDwgTables(hdr);
182     if (ret && !ret2) {
183         error = DRW::BAD_READ_TABLES;
184         ret = ret2;
185     }
186 
187     iface->addHeader(&hdr);
188 
189     for (std::map<duint32, DRW_LType*>::iterator it=reader->ltypemap.begin(); it!=reader->ltypemap.end(); ++it) {
190         DRW_LType *lt = it->second;
191         iface->addLType(const_cast<DRW_LType&>(*lt) );
192     }
193     for (std::map<duint32, DRW_Layer*>::iterator it=reader->layermap.begin(); it!=reader->layermap.end(); ++it) {
194         DRW_Layer *ly = it->second;
195         iface->addLayer(const_cast<DRW_Layer&>(*ly));
196     }
197 
198     for (std::map<duint32, DRW_Textstyle*>::iterator it=reader->stylemap.begin(); it!=reader->stylemap.end(); ++it) {
199         DRW_Textstyle *ly = it->second;
200         iface->addTextStyle(const_cast<DRW_Textstyle&>(*ly));
201     }
202 
203     for (std::map<duint32, DRW_Dimstyle*>::iterator it=reader->dimstylemap.begin(); it!=reader->dimstylemap.end(); ++it) {
204         DRW_Dimstyle *ly = it->second;
205         iface->addDimStyle(const_cast<DRW_Dimstyle&>(*ly));
206     }
207 
208     for (std::map<duint32, DRW_Vport*>::iterator it=reader->vportmap.begin(); it!=reader->vportmap.end(); ++it) {
209         DRW_Vport *ly = it->second;
210         iface->addVport(const_cast<DRW_Vport&>(*ly));
211     }
212 
213     for (std::map<duint32, DRW_AppId*>::iterator it=reader->appIdmap.begin(); it!=reader->appIdmap.end(); ++it) {
214         DRW_AppId *ly = it->second;
215         iface->addAppId(const_cast<DRW_AppId&>(*ly));
216     }
217 
218     ret2 = reader->readDwgBlocks(*iface);
219     if (ret && !ret2) {
220         error = DRW::BAD_READ_BLOCKS;
221         ret = ret2;
222     }
223 
224     ret2 = reader->readDwgEntities(*iface);
225     if (ret && !ret2) {
226         error = DRW::BAD_READ_ENTITIES;
227         ret = ret2;
228     }
229 
230     ret2 = reader->readDwgObjects(*iface);
231     if (ret && !ret2) {
232         error = DRW::BAD_READ_OBJECTS;
233         ret = ret2;
234     }
235 
236     return ret;
237 }
238