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(const char * name)38 dwgR::dwgR(const char* name){
39     DRW_DBGSL(DRW_dbg::NONE);
40     fileName = name;
41     reader = NULL;
42 //    writer = NULL;
43     applyExt = false;
44     version = DRW::UNKNOWNV;
45     error = DRW::BAD_NONE;
46 }
47 
~dwgR()48 dwgR::~dwgR(){
49     if (reader != NULL)
50         delete reader;
51 
52 }
53 
setDebug(DRW::DBG_LEVEL lvl)54 void dwgR::setDebug(DRW::DBG_LEVEL lvl){
55     switch (lvl){
56     case DRW::DEBUG:
57         DRW_DBGSL(DRW_dbg::DEBUG);
58         break;
59     default:
60         DRW_DBGSL(DRW_dbg::NONE);
61     }
62 }
63 
64 /*reads metadata and loads image preview*/
getPreview()65 bool dwgR::getPreview(){
66     bool isOk = false;
67 
68     std::ifstream filestr;
69     isOk = openFile(&filestr);
70     if (!isOk)
71         return false;
72 
73     isOk = reader->readMetaData();
74     if (isOk) {
75         isOk = reader->readPreview();
76     } else
77         error = DRW::BAD_READ_METADATA;
78 
79     filestr.close();
80     if (reader != NULL) {
81         delete reader;
82         reader = NULL;
83     }
84     return isOk;
85 }
86 
testReader()87 bool dwgR::testReader(){
88     bool isOk = false;
89 
90     std::ifstream filestr;
91     filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary);
92     if (!filestr.is_open() || !filestr.good() ){
93         error = DRW::BAD_OPEN;
94         return isOk;
95     }
96 
97     dwgBuffer fileBuf(&filestr);
98     duint8 *tmpStrData = new duint8[fileBuf.size()];
99     fileBuf.getBytes(tmpStrData, fileBuf.size());
100     dwgBuffer dataBuf(tmpStrData, fileBuf.size());
101     fileBuf.setPosition(0);
102     DRW_DBG("\ndwgR::testReader filebuf size: ");DRW_DBG(fileBuf.size());
103     DRW_DBG("\ndwgR::testReader dataBuf size: ");DRW_DBG(dataBuf.size());
104     DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
105     DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
106     DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
107     DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
108     DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
109     DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
110     fileBuf.setBitPos(4);
111     dataBuf.setBitPos(4);
112     DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
113     DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
114     DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
115     DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
116     DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
117     DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
118     fileBuf.setBitPos(6);
119     dataBuf.setBitPos(6);
120     DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
121     DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
122     DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
123     DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
124     DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
125     DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
126     fileBuf.setBitPos(0);
127     dataBuf.setBitPos(0);
128     DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
129     DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
130     DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
131     DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
132     DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
133     DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
134 
135     delete[]tmpStrData;
136     filestr.close();
137     DRW_DBG("\n\n");
138     return isOk;
139 }
140 
141 /*start reading dwg file header and, if can read it, continue reading all*/
read(DRW_Interface * interface_,bool ext)142 bool dwgR::read(DRW_Interface *interface_, bool ext){
143     bool isOk = false;
144     applyExt = ext;
145     iface = interface_;
146 
147 //testReader();return false;
148 
149     std::ifstream filestr;
150     isOk = openFile(&filestr);
151     if (!isOk)
152         return false;
153 
154     isOk = reader->readMetaData();
155     if (isOk) {
156         isOk = reader->readFileHeader();
157         if (isOk) {
158             isOk = processDwg();
159         } else
160             error = DRW::BAD_READ_FILE_HEADER;
161     } else
162         error = DRW::BAD_READ_METADATA;
163 
164     filestr.close();
165     if (reader != NULL) {
166         delete reader;
167         reader = NULL;
168     }
169 
170     return isOk;
171 }
172 
173 /* Open the file and stores it in filestr, install the correct reader version.
174  * If fail opening file, error are set as DRW::BAD_OPEN
175  * If not are DWG or are unsupported version, error are set as DRW::BAD_VERSION
176  * and closes filestr.
177  * Return true on succeed or false on fail
178 */
openFile(std::ifstream * filestr)179 bool dwgR::openFile(std::ifstream *filestr){
180     bool isOk = false;
181     DRW_DBG("dwgR::read 1\n");
182     filestr->open (fileName.c_str(), std::ios_base::in | std::ios::binary);
183     if (!filestr->is_open() || !filestr->good() ){
184         error = DRW::BAD_OPEN;
185         return isOk;
186     }
187 
188     char line[7];
189     filestr->read (line, 6);
190     line[6]='\0';
191     DRW_DBG("dwgR::read 2\n");
192     DRW_DBG("dwgR::read line version: ");
193     DRW_DBG(line);
194     DRW_DBG("\n");
195 
196     if (strcmp(line, "AC1006") == 0)
197         version = DRW::AC1006;
198     else if (strcmp(line, "AC1009") == 0) {
199         version = DRW::AC1009;
200 //        reader = new dwgReader09(&filestr, this);
201     }else if (strcmp(line, "AC1012") == 0){
202         version = DRW::AC1012;
203         reader = new dwgReader15(filestr, this);
204     } else if (strcmp(line, "AC1014") == 0) {
205         version = DRW::AC1014;
206         reader = new dwgReader15(filestr, this);
207     } else if (strcmp(line, "AC1015") == 0) {
208         version = DRW::AC1015;
209         reader = new dwgReader15(filestr, this);
210     } else if (strcmp(line, "AC1018") == 0){
211         version = DRW::AC1018;
212         reader = new dwgReader18(filestr, this);
213     } else if (strcmp(line, "AC1021") == 0) {
214         version = DRW::AC1021;
215         reader = new dwgReader21(filestr, this);
216     } else if (strcmp(line, "AC1024") == 0) {
217         version = DRW::AC1024;
218         reader = new dwgReader24(filestr, this);
219     } else if (strcmp(line, "AC1027") == 0) {
220         version = DRW::AC1027;
221         reader = new dwgReader27(filestr, this);
222     } else
223         version = DRW::UNKNOWNV;
224 
225     if (reader == NULL) {
226         error = DRW::BAD_VERSION;
227         filestr->close();
228     } else
229         isOk = true;
230 
231     return isOk;
232 }
233 
234 /********* Reader Process *********/
235 
processDwg()236 bool dwgR::processDwg() {
237     DRW_DBG("dwgR::processDwg() start processing dwg\n");
238     bool ret;
239     bool ret2;
240     DRW_Header hdr;
241     ret = reader->readDwgHeader(hdr);
242     if (!ret) {
243         error = DRW::BAD_READ_HEADER;
244     }
245 
246     ret2 = reader->readDwgClasses();
247     if (ret && !ret2) {
248         error = DRW::BAD_READ_CLASSES;
249         ret = ret2;
250     }
251 
252     ret2 = reader->readDwgHandles();
253     if (ret && !ret2) {
254         error = DRW::BAD_READ_HANDLES;
255         ret = ret2;
256     }
257 
258     ret2 = reader->readDwgTables(hdr);
259     if (ret && !ret2) {
260         error = DRW::BAD_READ_TABLES;
261         ret = ret2;
262     }
263 
264     iface->addHeader(&hdr);
265 
266     for (std::map<duint32, DRW_LType*>::iterator it=reader->ltypemap.begin(); it!=reader->ltypemap.end(); ++it) {
267         DRW_LType *lt = it->second;
268         iface->addLType(const_cast<DRW_LType&>(*lt) );
269     }
270     for (std::map<duint32, DRW_Layer*>::iterator it=reader->layermap.begin(); it!=reader->layermap.end(); ++it) {
271         DRW_Layer *ly = it->second;
272         iface->addLayer(const_cast<DRW_Layer&>(*ly));
273     }
274 
275     for (std::map<duint32, DRW_Textstyle*>::iterator it=reader->stylemap.begin(); it!=reader->stylemap.end(); ++it) {
276         DRW_Textstyle *ly = it->second;
277         iface->addTextStyle(const_cast<DRW_Textstyle&>(*ly));
278     }
279 
280     for (std::map<duint32, DRW_Dimstyle*>::iterator it=reader->dimstylemap.begin(); it!=reader->dimstylemap.end(); ++it) {
281         DRW_Dimstyle *ly = it->second;
282         iface->addDimStyle(const_cast<DRW_Dimstyle&>(*ly));
283     }
284 
285     for (std::map<duint32, DRW_Vport*>::iterator it=reader->vportmap.begin(); it!=reader->vportmap.end(); ++it) {
286         DRW_Vport *ly = it->second;
287         iface->addVport(const_cast<DRW_Vport&>(*ly));
288     }
289 
290     for (std::map<duint32, DRW_AppId*>::iterator it=reader->appIdmap.begin(); it!=reader->appIdmap.end(); ++it) {
291         DRW_AppId *ly = it->second;
292         iface->addAppId(const_cast<DRW_AppId&>(*ly));
293     }
294 
295     ret2 = reader->readDwgBlocks(*iface);
296     if (ret && !ret2) {
297         error = DRW::BAD_READ_BLOCKS;
298         ret = ret2;
299     }
300 
301     ret2 = reader->readDwgEntities(*iface);
302     if (ret && !ret2) {
303         error = DRW::BAD_READ_ENTITIES;
304         ret = ret2;
305     }
306 
307     ret2 = reader->readDwgObjects(*iface);
308     if (ret && !ret2) {
309         error = DRW::BAD_READ_OBJECTS;
310         ret = ret2;
311     }
312 
313     return ret;
314 }
315