1 /*******************************************************************************
2 * Project: libopencad
3 * Purpose: OpenSource CAD formats support library
4 * Author: Alexandr Borzykh, mush3d at gmail.com
5 * Author: Dmitry Baryshnikov, bishop.dev@gmail.com
6 * Language: C++
7 *******************************************************************************
8 * The MIT License (MIT)
9 *
10 * Copyright (c) 2016 Alexandr Borzykh
11 * Copyright (c) 2016 NextGIS, <info@nextgis.com>
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a copy
14 * of this software and associated documentation files (the "Software"), to deal
15 * in the Software without restriction, including without limitation the rights
16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 * copies of the Software, and to permit persons to whom the Software is
18 * furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in all
21 * copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 * SOFTWARE.
30 *******************************************************************************/
31
32 #include "cpl_port.h"
33 #include "cpl_safemaths.hpp"
34 #include "cadheader.h"
35 #include "opencad_api.h"
36 #include "dwg/io.h"
37
38 #include <cstring>
39 #include <iostream>
40 #include <time.h>
41
42 #if ((defined(__sun__) || defined(__FreeBSD__)) && __GNUC__ == 4 && __GNUC_MINOR__ == 8) || defined(__ANDROID__)
43 // gcc 4.8 on Solaris 11.3 or FreeBSD 11 doesn't have std::string
44 #include <sstream>
to_string(T val)45 template <typename T> std::string to_string(T val)
46 {
47 std::ostringstream os;
48 os << val;
49 return os.str();
50 }
51 #endif
52
53 using namespace std;
54
55 typedef struct
56 {
57 short nConstant;
58 short nGroupCode;
59 const char * pszValueName;
60 } CADHeaderConstantDetail;
61
62 #define FillCADConstantDetail( x, y ) {CADHeader::x, y, "$"#x}
63
64 static const CADHeaderConstantDetail CADHeaderConstantDetails[]{
65 FillCADConstantDetail( OPENCADVER, 777),
66 FillCADConstantDetail( ACADMAINTVER, 70 ), FillCADConstantDetail( ACADVER, 1 ),
67 FillCADConstantDetail( ANGBASE, 50 ), FillCADConstantDetail( ANGDIR, 70 ), FillCADConstantDetail( ATTMODE, 70 ),
68 FillCADConstantDetail( AUNITS, 70 ), FillCADConstantDetail( AUPREC, 70 ), FillCADConstantDetail( CECOLOR, 62 ),
69 FillCADConstantDetail( CELTSCALE, 40 ), FillCADConstantDetail( CELTYPE, 6 ),
70 FillCADConstantDetail( CELWEIGHT, 370 ), FillCADConstantDetail( CEPSNID, 390 ),
71 FillCADConstantDetail( CEPSNTYPE, 380 ), FillCADConstantDetail( CHAMFERA, 40 ),
72 FillCADConstantDetail( CHAMFERB, 40 ), FillCADConstantDetail( CHAMFERC, 40 ),
73 FillCADConstantDetail( CHAMFERD, 40 ), FillCADConstantDetail( CLAYER, 8 ), FillCADConstantDetail( CMLJUST, 70 ),
74 FillCADConstantDetail( CMLSCALE, 40 ), FillCADConstantDetail( CMLSTYLE, 2 ),
75 FillCADConstantDetail( CSHADOW, 280 ), FillCADConstantDetail( DIMADEC, 70 ),
76 FillCADConstantDetail( DIMALT, 70 ), FillCADConstantDetail( DIMALTD, 70 ), FillCADConstantDetail( DIMALTF, 40 ),
77 FillCADConstantDetail( DIMALTRND, 40 ), FillCADConstantDetail( DIMALTTD, 70 ),
78 FillCADConstantDetail( DIMALTTZ, 70 ), FillCADConstantDetail( DIMALTU, 70 ),
79 FillCADConstantDetail( DIMALTZ, 70 ), FillCADConstantDetail( DIMAPOST, 1 ), FillCADConstantDetail( DIMASO, 70 ),
80 FillCADConstantDetail( DIMASSOC, 280 ), FillCADConstantDetail( DIMASZ, 40 ),
81 FillCADConstantDetail( DIMATFIT, 70 ), FillCADConstantDetail( DIMAUNIT, 70 ),
82 FillCADConstantDetail( DIMAZIN, 70 ), FillCADConstantDetail( DIMBLK, 1 ), FillCADConstantDetail( DIMBLK1, 1 ),
83 FillCADConstantDetail( DIMBLK2, 1 ), FillCADConstantDetail( DIMCEN, 40 ), FillCADConstantDetail( DIMCLRD, 70 ),
84 FillCADConstantDetail( DIMCLRE, 70 ), FillCADConstantDetail( DIMCLRT, 70 ), FillCADConstantDetail( DIMDEC, 70 ),
85 FillCADConstantDetail( DIMDLE, 40 ), FillCADConstantDetail( DIMDLI, 40 ), FillCADConstantDetail( DIMDSEP, 70 ),
86 FillCADConstantDetail( DIMEXE, 40 ), FillCADConstantDetail( DIMEXO, 40 ), FillCADConstantDetail( DIMFAC, 40 ),
87 FillCADConstantDetail( DIMGAP, 40 ), FillCADConstantDetail( DIMJUST, 70 ),
88 FillCADConstantDetail( DIMLDRBLK, 1 ), FillCADConstantDetail( DIMLFAC, 40 ),
89 FillCADConstantDetail( DIMLIM, 70 ), FillCADConstantDetail( DIMLUNIT, 70 ), FillCADConstantDetail( DIMLWD, 70 ),
90 FillCADConstantDetail( DIMLWE, 70 ), FillCADConstantDetail( DIMPOST, 1 ), FillCADConstantDetail( DIMRND, 40 ),
91 FillCADConstantDetail( DIMSAH, 70 ), FillCADConstantDetail( DIMSCALE, 40 ), FillCADConstantDetail( DIMSD1, 70 ),
92 FillCADConstantDetail( DIMSD2, 70 ), FillCADConstantDetail( DIMSE1, 70 ), FillCADConstantDetail( DIMSE2, 70 ),
93 FillCADConstantDetail( DIMSHO, 70 ), FillCADConstantDetail( DIMSOXD, 70 ), FillCADConstantDetail( DIMSTYLE, 2 ),
94 FillCADConstantDetail( DIMTAD, 70 ), FillCADConstantDetail( DIMTDEC, 70 ), FillCADConstantDetail( DIMTFAC, 40 ),
95 FillCADConstantDetail( DIMTIH, 70 ), FillCADConstantDetail( DIMTIX, 70 ), FillCADConstantDetail( DIMTM, 40 ),
96 FillCADConstantDetail( DIMTMOVE, 70 ), FillCADConstantDetail( DIMTOFL, 70 ),
97 FillCADConstantDetail( DIMTOH, 70 ), FillCADConstantDetail( DIMTOL, 70 ), FillCADConstantDetail( DIMTOLJ, 70 ),
98 FillCADConstantDetail( DIMTP, 40 ), FillCADConstantDetail( DIMTSZ, 40 ), FillCADConstantDetail( DIMTVP, 40 ),
99 FillCADConstantDetail( DIMTXSTY, 7 ), FillCADConstantDetail( DIMTXT, 40 ), FillCADConstantDetail( DIMTZIN, 70 ),
100 FillCADConstantDetail( DIMUPT, 70 ), FillCADConstantDetail( DIMZIN, 70 ), FillCADConstantDetail( DISPSILH, 70 ),
101 FillCADConstantDetail( DRAGVS, 349 ), FillCADConstantDetail( DWGCODEPAGE, 3 ),
102 FillCADConstantDetail( ELEVATION, 40 ), FillCADConstantDetail( ENDCAPS, 280 ),
103 FillCADConstantDetail( EXTMAX, 123 ), FillCADConstantDetail( EXTMIN, 123 ),
104 FillCADConstantDetail( EXTNAMES, 290 ), FillCADConstantDetail( FILLETRAD, 40 ),
105 FillCADConstantDetail( FILLMODE, 70 ), FillCADConstantDetail( FINGERPRINTGUID, 2 ),
106 FillCADConstantDetail( HALOGAP, 280 ), FillCADConstantDetail( HANDSEED, 5 ),
107 FillCADConstantDetail( HIDETEXT, 290 ), FillCADConstantDetail( HYPERLINKBASE, 1 ),
108 FillCADConstantDetail( INDEXCTL, 280 ), FillCADConstantDetail( INSBASE, 123 ),
109 FillCADConstantDetail( INSUNITS, 70 ), FillCADConstantDetail( INTERFERECOLOR, 62 ),
110 FillCADConstantDetail( INTERFEREOBJVS, 345 ), FillCADConstantDetail( INTERFEREVPVS, 346 ),
111 FillCADConstantDetail( INTERSECTIONCOLOR, 70 ), FillCADConstantDetail( INTERSECTIONDISPLAY, 290 ),
112 FillCADConstantDetail( JOINSTYLE, 280 ), FillCADConstantDetail( LIMCHECK, 70 ),
113 FillCADConstantDetail( LIMMAX, 1020 ), FillCADConstantDetail( LIMMIN, 1020 ),
114 FillCADConstantDetail( LTSCALE, 40 ), FillCADConstantDetail( LUNITS, 70 ), FillCADConstantDetail( LUPREC, 70 ),
115 FillCADConstantDetail( LWDISPLAY, 290 ), FillCADConstantDetail( MAXACTVP, 70 ),
116 FillCADConstantDetail( MEASUREMENT, 70 ), FillCADConstantDetail( MENU, 1 ),
117 FillCADConstantDetail( MIRRTEXT, 70 ), FillCADConstantDetail( OBSCOLOR, 70 ),
118 FillCADConstantDetail( OBSLTYPE, 280 ), FillCADConstantDetail( ORTHOMODE, 70 ),
119 FillCADConstantDetail( PDMODE, 70 ), FillCADConstantDetail( PDSIZE, 40 ),
120 FillCADConstantDetail( PELEVATION, 40 ), FillCADConstantDetail( PEXTMAX, 123 ),
121 FillCADConstantDetail( PEXTMIN, 123 ), FillCADConstantDetail( PINSBASE, 123 ),
122 FillCADConstantDetail( PLIMCHECK, 70 ), FillCADConstantDetail( PLIMMAX, 1020 ),
123 FillCADConstantDetail( PLIMMIN, 1020 ), FillCADConstantDetail( PLINEGEN, 70 ),
124 FillCADConstantDetail( PLINEWID, 40 ), FillCADConstantDetail( PROJECTNAME, 1 ),
125 FillCADConstantDetail( PROXYGRAPHICS, 70 ), FillCADConstantDetail( PSLTSCALE, 70 ),
126 FillCADConstantDetail( PSTYLEMODE, 290 ), FillCADConstantDetail( PSVPSCALE, 40 ),
127 FillCADConstantDetail( PUCSBASE, 2 ), FillCADConstantDetail( PUCSNAME, 2 ),
128 FillCADConstantDetail( PUCSORG, 123 ), FillCADConstantDetail( PUCSORGBACK, 123 ),
129 FillCADConstantDetail( PUCSORGBOTTOM, 123 ), FillCADConstantDetail( PUCSORGFRONT, 123 ),
130 FillCADConstantDetail( PUCSORGLEFT, 123 ), FillCADConstantDetail( PUCSORGRIGHT, 123 ),
131 FillCADConstantDetail( PUCSORGTOP, 123 ), FillCADConstantDetail( PUCSORTHOREF, 2 ),
132 FillCADConstantDetail( PUCSORTHOVIEW, 70 ), FillCADConstantDetail( PUCSXDIR, 123 ),
133 FillCADConstantDetail( PUCSYDIR, 123 ), FillCADConstantDetail( QTEXTMODE, 70 ),
134 FillCADConstantDetail( REGENMODE, 70 ), FillCADConstantDetail( SHADEDGE, 70 ),
135 FillCADConstantDetail( SHADEDIF, 70 ), FillCADConstantDetail( SHADOWPLANELOCATION, 40 ),
136 FillCADConstantDetail( SKETCHINC, 40 ), FillCADConstantDetail( SKPOLY, 70 ),
137 FillCADConstantDetail( SORTENTS, 280 ), FillCADConstantDetail( SPLINESEGS, 70 ),
138 FillCADConstantDetail( SPLINETYPE, 70 ), FillCADConstantDetail( SURFTAB1, 70 ),
139 FillCADConstantDetail( SURFTAB2, 70 ), FillCADConstantDetail( SURFTYPE, 70 ),
140 FillCADConstantDetail( SURFU, 70 ), FillCADConstantDetail( SURFV, 70 ), FillCADConstantDetail( TDCREATE, 40 ),
141 FillCADConstantDetail( TDINDWG, 40 ), FillCADConstantDetail( TDUCREATE, 40 ),
142 FillCADConstantDetail( TDUPDATE, 40 ), FillCADConstantDetail( TDUSRTIMER, 40 ),
143 FillCADConstantDetail( TDUUPDATE, 40 ), FillCADConstantDetail( TEXTSIZE, 40 ),
144 FillCADConstantDetail( TEXTSTYLE, 7 ), FillCADConstantDetail( THICKNESS, 40 ),
145 FillCADConstantDetail( TILEMODE, 70 ), FillCADConstantDetail( TRACEWID, 40 ),
146 FillCADConstantDetail( TREEDEPTH, 70 ), FillCADConstantDetail( UCSBASE, 2 ),
147 FillCADConstantDetail( UCSNAME, 2 ), FillCADConstantDetail( UCSORG, 123 ),
148 FillCADConstantDetail( UCSORGBACK, 123 ), FillCADConstantDetail( UCSORGBOTTOM, 123 ),
149 FillCADConstantDetail( UCSORGFRONT, 123 ), FillCADConstantDetail( UCSORGLEFT, 123 ),
150 FillCADConstantDetail( UCSORGRIGHT, 123 ), FillCADConstantDetail( UCSORGTOP, 123 ),
151 FillCADConstantDetail( UCSORTHOREF, 2 ), FillCADConstantDetail( UCSORTHOVIEW, 70 ),
152 FillCADConstantDetail( UCSXDIR, 123 ), FillCADConstantDetail( UCSYDIR, 123 ),
153 FillCADConstantDetail( UNITMODE, 70 ), FillCADConstantDetail( USERI1, 70 ), FillCADConstantDetail( USERI2, 70 ),
154 FillCADConstantDetail( USERI3, 70 ), FillCADConstantDetail( USERI4, 70 ), FillCADConstantDetail( USERI5, 70 ),
155 FillCADConstantDetail( USERR1, 40 ), FillCADConstantDetail( USERR2, 40 ), FillCADConstantDetail( USERR3, 40 ),
156 FillCADConstantDetail( USERR4, 40 ), FillCADConstantDetail( USERR5, 40 ), FillCADConstantDetail( USRTIMER, 70 ),
157 FillCADConstantDetail( VERSIONGUID, 2 ), FillCADConstantDetail( VISRETAIN, 70 ),
158 FillCADConstantDetail( WORLDVIEW, 70 ), FillCADConstantDetail( XCLIPFRAME, 290 ),
159 FillCADConstantDetail( XEDIT, 290 ), { -1, -1, nullptr }
160 };
161
162 //------------------------------------------------------------------------------
163 // CADHandle
164 //------------------------------------------------------------------------------
165
CADHandle(unsigned char codeIn)166 CADHandle::CADHandle( unsigned char codeIn ) : code( codeIn )
167 {
168 }
169
CADHandle(const CADHandle & other)170 CADHandle::CADHandle( const CADHandle& other ) :
171 code( other.code ),
172 handleOrOffset( other.handleOrOffset )
173 {
174 }
175
operator =(const CADHandle & other)176 CADHandle& CADHandle::operator=( const CADHandle& other )
177 {
178 if( this == & other )
179 return * this;
180 code = other.code;
181 handleOrOffset = other.handleOrOffset;
182 return * this;
183 }
184
addOffset(unsigned char val)185 void CADHandle::addOffset( unsigned char val )
186 {
187 handleOrOffset.push_back( val );
188 }
189
getAsLong(const CADHandle & ref_handle) const190 long CADHandle::getAsLong( const CADHandle& ref_handle ) const
191 {
192 // FIXME: Remove GDAL specific code. The library cannot compile as separate project.
193 try
194 {
195 switch( code )
196 {
197 case 0x06:
198 {
199 return static_cast<long>((CPLSM(static_cast<GInt64>(getAsLong(ref_handle.handleOrOffset))) +
200 CPLSM(static_cast<GInt64>(1))).v());
201 }
202 case 0x08:
203 {
204 return static_cast<long>((CPLSM(static_cast<GInt64>(getAsLong(ref_handle.handleOrOffset))) -
205 CPLSM(static_cast<GInt64>(1))).v());
206 }
207 case 0x0A:
208 {
209 return static_cast<long>((CPLSM(static_cast<GInt64>(getAsLong(ref_handle.handleOrOffset))) +
210 CPLSM(static_cast<GInt64>(getAsLong(handleOrOffset)))).v());
211 }
212 case 0x0C:
213 {
214 return static_cast<long>((CPLSM(static_cast<GInt64>(getAsLong(ref_handle.handleOrOffset))) -
215 CPLSM(static_cast<GInt64>(getAsLong(handleOrOffset)))).v());
216 }
217 }
218 }
219 catch( const CPLSafeIntOverflow& )
220 {
221 // TODO: handle this differently ?
222 return 0;
223 }
224
225 return getAsLong(handleOrOffset);
226 }
227
getAsLong() const228 long CADHandle::getAsLong() const
229 {
230 return getAsLong(handleOrOffset);
231 }
232
getAsLong(const std::vector<unsigned char> & handle)233 long CADHandle::getAsLong(const std::vector<unsigned char>& handle)
234 {
235 unsigned long result = 0;
236 if( handle.empty() )
237 return result;
238 size_t copySize = handle.size();
239 if( copySize > sizeof(long) )
240 copySize = sizeof(long);
241 for( size_t i = 0; i < copySize; ++i )
242 result = result * 256U + handle[i];
243 return static_cast<long>(result);
244 }
245
isNull() const246 bool CADHandle::isNull() const
247 {
248 return handleOrOffset.empty() ? true : false;
249 }
250
251 //------------------------------------------------------------------------------
252 // CADVariant
253 //------------------------------------------------------------------------------
254
CADVariant()255 CADVariant::CADVariant() :
256 type ( DataType::INVALID ),
257 decimalVal ( 0 ),
258 xVal ( 0 ),
259 yVal ( 0 ),
260 zVal ( 0 ),
261 dateTimeVal ( 0 )
262 {
263 }
264
CADVariant(const char * val)265 CADVariant::CADVariant( const char * val ) :
266 type ( DataType::STRING ),
267 decimalVal ( 0 ),
268 xVal ( 0 ),
269 yVal ( 0 ),
270 zVal ( 0 ),
271 stringVal ( string( val ) ),
272 dateTimeVal ( 0 )
273 {
274 }
275
CADVariant(int val)276 CADVariant::CADVariant( int val ) :
277 type ( DataType::DECIMAL ),
278 decimalVal ( val ),
279 xVal ( 0 ),
280 yVal ( 0 ),
281 zVal ( 0 ),
282 stringVal ( to_string( val ) ),
283 dateTimeVal ( 0 )
284 {
285 }
286
CADVariant(short val)287 CADVariant::CADVariant( short val ) :
288 type ( DataType::DECIMAL ),
289 decimalVal ( val ),
290 xVal ( 0 ),
291 yVal ( 0 ),
292 zVal ( 0 ),
293 stringVal ( to_string( val ) ),
294 dateTimeVal ( 0 )
295 {
296 }
297
CADVariant(double val)298 CADVariant::CADVariant( double val ) :
299 type ( DataType::REAL ),
300 decimalVal ( 0 ),
301 xVal ( val ),
302 yVal ( 0 ),
303 zVal ( 0 ),
304 stringVal ( to_string( val ) ),
305 dateTimeVal ( 0 )
306 {
307 }
308
CADVariant(double x,double y,double z)309 CADVariant::CADVariant( double x, double y, double z ) :
310 type ( DataType::COORDINATES ),
311 decimalVal ( 0 ),
312 xVal ( x ),
313 yVal ( y ),
314 zVal ( z ),
315 dateTimeVal ( 0 )
316 {
317 char str_buff[256];
318 snprintf( str_buff, sizeof(str_buff), "[%.15g,%.15g,%.15g]", x, y, z );
319 str_buff[sizeof(str_buff)-1] = '\0';
320 stringVal = str_buff;
321 }
322
CADVariant(const string & val)323 CADVariant::CADVariant( const string& val ) :
324 type ( DataType::STRING ),
325 decimalVal ( 0 ),
326 xVal ( 0 ),
327 yVal ( 0 ),
328 zVal ( 0 ),
329 stringVal ( val ),
330 dateTimeVal ( 0 )
331 {
332 }
333
CADVariant(long julianday,long milliseconds)334 CADVariant::CADVariant( long julianday, long milliseconds ) :
335 type ( DataType::DATETIME ),
336 decimalVal ( 0 ),
337 xVal ( 0 ),
338 yVal ( 0 ),
339 zVal ( 0 )
340 {
341 double dfSeconds = double( milliseconds ) / 1000;
342 double dfUnix = 0;
343 if(julianday != 0)
344 dfUnix = ( double( julianday ) - 2440587.5 ) * 86400.0;
345 dateTimeVal = static_cast<time_t>( dfUnix + dfSeconds );
346
347 char str_buff[256] = "Invalid date";
348 struct tm *poLocaltime = localtime(&dateTimeVal);
349 if(poLocaltime)
350 strftime(str_buff, 255, "%Y-%m-%d %H:%M:%S", poLocaltime);
351 stringVal = str_buff;
352 }
353
CADVariant(const CADHandle & val)354 CADVariant::CADVariant( const CADHandle& val ) :
355 type ( DataType::HANDLE ),
356 decimalVal ( 0 ),
357 xVal ( 0 ),
358 yVal ( 0 ),
359 zVal ( 0 ),
360 stringVal ( to_string( val.getAsLong() ) ),
361 handleVal ( val ),
362 dateTimeVal ( 0 )
363 {
364 }
365
getDecimal() const366 long CADVariant::getDecimal() const
367 {
368 return decimalVal;
369 }
370
getReal() const371 double CADVariant::getReal() const
372 {
373 return xVal;
374 }
375
getString() const376 const string& CADVariant::getString() const
377 {
378 return stringVal;
379 }
380
getType() const381 CADVariant::DataType CADVariant::getType() const
382 {
383 return type;
384 }
385
getX() const386 double CADVariant::getX() const
387 {
388 return xVal;
389 }
390
getY() const391 double CADVariant::getY() const
392 {
393 return yVal;
394 }
395
getZ() const396 double CADVariant::getZ() const
397 {
398 return zVal;
399 }
400
getHandle() const401 const CADHandle& CADVariant::getHandle() const
402 {
403 return handleVal;
404 }
405
406 //------------------------------------------------------------------------------
407 // CADHeader
408 //------------------------------------------------------------------------------
409
CADHeader()410 CADHeader::CADHeader()
411 {
412 }
413
addValue(short code,const CADVariant & val)414 int CADHeader::addValue( short code, const CADVariant& val )
415 {
416 if( valuesMap.find( code ) != valuesMap.end() )
417 return CADErrorCodes::VALUE_EXISTS;
418
419 valuesMap[code] = val;
420 return CADErrorCodes::SUCCESS;
421 }
422
addValue(short code,const char * val)423 int CADHeader::addValue( short code, const char * val )
424 {
425 return addValue( code, CADVariant( val ) );
426 }
427 /*
428 int CADHeader::addValue( short code, long val )
429 {
430 return addValue( code, CADVariant( val ) );
431 }
432 */
addValue(short code,int val)433 int CADHeader::addValue( short code, int val )
434 {
435 return addValue( code, CADVariant( val ) );
436 }
437
addValue(short code,short val)438 int CADHeader::addValue( short code, short val )
439 {
440 return addValue( code, CADVariant( val ) );
441 }
442
addValue(short code,double val)443 int CADHeader::addValue( short code, double val )
444 {
445 return addValue( code, CADVariant( val ) );
446 }
447
addValue(short code,const string & val)448 int CADHeader::addValue( short code, const string& val )
449 {
450 return addValue( code, CADVariant( val ) );
451 }
452
addValue(short code,bool val)453 int CADHeader::addValue( short code, bool val )
454 {
455 return addValue( code, CADVariant( val ? 1 : 0 ) );
456 }
457
addValue(short code,double x,double y,double z)458 int CADHeader::addValue( short code, double x, double y, double z )
459 {
460 return addValue( code, CADVariant( x, y, z ) );
461 }
462
addValue(short code,long julianday,long milliseconds)463 int CADHeader::addValue( short code, long julianday, long milliseconds )
464 {
465 // unix -> julian return ( unixSecs / 86400.0 ) + 2440587.5;
466 // julian -> unix return (julian - 2440587.5) * 86400.0
467
468 return addValue( code, CADVariant( julianday, milliseconds ) );
469 }
470
getGroupCode(short code)471 int CADHeader::getGroupCode( short code )
472 {
473 for( CADHeaderConstantDetail detail : CADHeaderConstantDetails )
474 {
475 if( detail.nConstant == code )
476 return detail.nGroupCode;
477 }
478
479 return -1;
480 }
481
getValue(short code,const CADVariant & val) const482 const CADVariant CADHeader::getValue( short code, const CADVariant& val ) const
483 {
484 auto it = valuesMap.find( code );
485 if( it != valuesMap.end() )
486 return it->second;
487 else
488 return val;
489 }
490
getValueName(short code)491 const char * CADHeader::getValueName( short code )
492 {
493 for( CADHeaderConstantDetail detail : CADHeaderConstantDetails )
494 {
495 if( detail.nConstant == code )
496 return detail.pszValueName;
497 }
498 return "Undefined";
499 }
500
print() const501 void CADHeader::print() const
502 {
503 cout << "============ HEADER Section ============\n";
504 for( auto it : valuesMap )
505 {
506 cout << getValueName( it.first ) << ": " << it.second.getString() << "\n";
507 }
508 cout << "\n";
509 }
510
getSize() const511 size_t CADHeader::getSize() const
512 {
513 return valuesMap.size();
514 }
515
getCode(int index) const516 short CADHeader::getCode( int index ) const
517 {
518 auto it = valuesMap.begin();
519 advance( it, index );
520 return it->first;
521 }
522