Line data Source code
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-2018 NextGIS, <info@nextgis.com>
12 : *
13 : * SPDX-License-Identifier: MIT
14 : *******************************************************************************/
15 : #include "cadgeometry.h"
16 : #include "cadobjects.h"
17 : #include "opencad_api.h"
18 : #include "r2000.h"
19 :
20 : #include <cassert>
21 : #include <cstdint>
22 : #include <cstring>
23 : #include <iostream>
24 : #include <limits>
25 : #include <memory>
26 : #include <string>
27 :
28 : #if ((defined(__sun__) || defined(__FreeBSD__)) && __GNUC__ == 4 && __GNUC_MINOR__ == 8) || defined(__ANDROID__)
29 : // gcc 4.8 on Solaris 11.3 or FreeBSD 11 doesn't have std::string
30 : #include <sstream>
31 : namespace std
32 : {
33 : template <typename T> std::string to_string(T val)
34 : {
35 : std::ostringstream os;
36 : os << val;
37 : return os.str();
38 : }
39 : }
40 : #endif
41 :
42 : #define UNKNOWN1 CADHeader::MAX_HEADER_CONSTANT + 1
43 : #define UNKNOWN2 CADHeader::MAX_HEADER_CONSTANT + 2
44 : #define UNKNOWN3 CADHeader::MAX_HEADER_CONSTANT + 3
45 : #define UNKNOWN4 CADHeader::MAX_HEADER_CONSTANT + 4
46 : #define UNKNOWN5 CADHeader::MAX_HEADER_CONSTANT + 5
47 : #define UNKNOWN6 CADHeader::MAX_HEADER_CONSTANT + 6
48 : #define UNKNOWN7 CADHeader::MAX_HEADER_CONSTANT + 7
49 : #define UNKNOWN8 CADHeader::MAX_HEADER_CONSTANT + 8
50 : #define UNKNOWN9 CADHeader::MAX_HEADER_CONSTANT + 9
51 : #define UNKNOWN10 CADHeader::MAX_HEADER_CONSTANT + 10
52 : #define UNKNOWN11 CADHeader::MAX_HEADER_CONSTANT + 11
53 : #define UNKNOWN12 CADHeader::MAX_HEADER_CONSTANT + 12
54 : #define UNKNOWN13 CADHeader::MAX_HEADER_CONSTANT + 13
55 : #define UNKNOWN14 CADHeader::MAX_HEADER_CONSTANT + 14
56 : #define UNKNOWN15 CADHeader::MAX_HEADER_CONSTANT + 15
57 :
58 : using namespace std;
59 :
60 8 : int DWGFileR2000::ReadHeader( OpenOptions eOptions )
61 : {
62 : char bufferPre[255];
63 8 : unsigned dHeaderVarsSectionLength = 0;
64 8 : constexpr size_t dSizeOfSectionSize = sizeof(dHeaderVarsSectionLength);
65 :
66 8 : pFileIO->Seek( sectionLocatorRecords[0].dSeeker, CADFileIO::SeekOrigin::BEG );
67 8 : size_t readSize = pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
68 8 : if(readSize < DWGConstants::SentinelLength)
69 : {
70 0 : DebugMsg( "File is corrupted (size is less than sentinel length)" );
71 :
72 0 : return CADErrorCodes::HEADER_SECTION_READ_FAILED;
73 : }
74 :
75 : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
76 8 : if( memcmp( bufferPre, DWGConstants::HeaderVariablesStart,
77 : DWGConstants::SentinelLength ) )
78 : {
79 0 : DebugMsg( "File is corrupted (wrong pointer to HEADER_VARS section,"
80 : "or HEADERVARS starting sentinel corrupted.)" );
81 :
82 0 : return CADErrorCodes::HEADER_SECTION_READ_FAILED;
83 : }
84 : #endif
85 :
86 8 : readSize = pFileIO->Read( &dHeaderVarsSectionLength, dSizeOfSectionSize );
87 8 : const auto dHeaderVarsSectionLengthOriginal = dHeaderVarsSectionLength;
88 8 : FromLSB(dHeaderVarsSectionLength);
89 8 : DebugMsg( "Header variables section length: %d\n",
90 : static_cast<int>(dHeaderVarsSectionLength) );
91 8 : if(readSize != dSizeOfSectionSize || dHeaderVarsSectionLength > 65536) //NOTE: maybe header section may be bigger
92 : {
93 0 : DebugMsg( "File is corrupted (HEADER_VARS section length too big)" );
94 0 : return CADErrorCodes::HEADER_SECTION_READ_FAILED;
95 : }
96 :
97 16 : CADBuffer buffer(dHeaderVarsSectionLength + dSizeOfSectionSize + 10);
98 8 : buffer.WriteRAW(&dHeaderVarsSectionLengthOriginal, dSizeOfSectionSize);
99 8 : readSize = pFileIO->Read(buffer.GetRawBuffer(), dHeaderVarsSectionLength + 2 );
100 8 : if(readSize != dHeaderVarsSectionLength + 2)
101 : {
102 0 : DebugMsg( "Failed to read %d byte of file. Read only %d",
103 0 : static_cast<int>(dHeaderVarsSectionLength + 2),
104 : static_cast<int>(readSize) );
105 0 : return CADErrorCodes::HEADER_SECTION_READ_FAILED;
106 : }
107 :
108 8 : if( eOptions == OpenOptions::READ_ALL )
109 : {
110 0 : oHeader.addValue( UNKNOWN1, buffer.ReadBITDOUBLE() );
111 0 : oHeader.addValue( UNKNOWN2, buffer.ReadBITDOUBLE() );
112 0 : oHeader.addValue( UNKNOWN3, buffer.ReadBITDOUBLE() );
113 0 : oHeader.addValue( UNKNOWN4, buffer.ReadBITDOUBLE() );
114 0 : oHeader.addValue( UNKNOWN5, buffer.ReadTV() );
115 0 : oHeader.addValue( UNKNOWN6, buffer.ReadTV() );
116 0 : oHeader.addValue( UNKNOWN7, buffer.ReadTV() );
117 0 : oHeader.addValue( UNKNOWN8, buffer.ReadTV() );
118 0 : oHeader.addValue( UNKNOWN9, buffer.ReadBITLONG() );
119 0 : oHeader.addValue( UNKNOWN10, buffer.ReadBITLONG() );
120 : }
121 : else
122 : {
123 8 : buffer.SkipBITDOUBLE();
124 8 : buffer.SkipBITDOUBLE();
125 8 : buffer.SkipBITDOUBLE();
126 8 : buffer.SkipBITDOUBLE();
127 8 : buffer.SkipTV();
128 8 : buffer.SkipTV();
129 8 : buffer.SkipTV();
130 8 : buffer.SkipTV();
131 8 : buffer.SkipBITLONG();
132 8 : buffer.SkipBITLONG();
133 : }
134 :
135 16 : CADHandle stCurrentViewportTable = buffer.ReadHANDLE();
136 8 : oTables.AddTable( CADTables::CurrentViewportTable, stCurrentViewportTable );
137 :
138 8 : if( eOptions == OpenOptions::READ_ALL )
139 : {
140 0 : oHeader.addValue( CADHeader::DIMASO, buffer.ReadBIT() ); // 1
141 0 : oHeader.addValue( CADHeader::DIMSHO, buffer.ReadBIT() ); // 2
142 0 : oHeader.addValue( CADHeader::PLINEGEN, buffer.ReadBIT() ); // 3
143 0 : oHeader.addValue( CADHeader::ORTHOMODE, buffer.ReadBIT() ); // 4
144 0 : oHeader.addValue( CADHeader::REGENMODE, buffer.ReadBIT() ); // 5
145 0 : oHeader.addValue( CADHeader::FILLMODE, buffer.ReadBIT() ); // 6
146 0 : oHeader.addValue( CADHeader::QTEXTMODE, buffer.ReadBIT() ); // 7
147 0 : oHeader.addValue( CADHeader::PSLTSCALE, buffer.ReadBIT() ); // 8
148 0 : oHeader.addValue( CADHeader::LIMCHECK, buffer.ReadBIT() ); // 9
149 0 : oHeader.addValue( CADHeader::USRTIMER, buffer.ReadBIT() ); // 10
150 0 : oHeader.addValue( CADHeader::SKPOLY, buffer.ReadBIT() ); // 11
151 0 : oHeader.addValue( CADHeader::ANGDIR, buffer.ReadBIT() ); // 12
152 0 : oHeader.addValue( CADHeader::SPLFRAME, buffer.ReadBIT() ); // 13
153 0 : oHeader.addValue( CADHeader::MIRRTEXT, buffer.ReadBIT() ); // 14
154 0 : oHeader.addValue( CADHeader::WORDLVIEW, buffer.ReadBIT() ); // 15
155 0 : oHeader.addValue( CADHeader::TILEMODE, buffer.ReadBIT() ); // 16
156 0 : oHeader.addValue( CADHeader::PLIMCHECK, buffer.ReadBIT() ); // 17
157 0 : oHeader.addValue( CADHeader::VISRETAIN, buffer.ReadBIT() ); // 18
158 0 : oHeader.addValue( CADHeader::DISPSILH, buffer.ReadBIT() ); // 19
159 0 : oHeader.addValue( CADHeader::PELLIPSE, buffer.ReadBIT() ); // 20
160 : }
161 : else
162 : {
163 8 : buffer.Seek(20);
164 : }
165 :
166 8 : if( eOptions == OpenOptions::READ_ALL )
167 : {
168 0 : oHeader.addValue( CADHeader::PROXYGRAPHICS, buffer.ReadBITSHORT() ); // 1
169 0 : oHeader.addValue( CADHeader::TREEDEPTH, buffer.ReadBITSHORT() ); // 2
170 0 : oHeader.addValue( CADHeader::LUNITS, buffer.ReadBITSHORT() ); // 3
171 0 : oHeader.addValue( CADHeader::LUPREC, buffer.ReadBITSHORT() ); // 4
172 0 : oHeader.addValue( CADHeader::AUNITS, buffer.ReadBITSHORT() ); // 5
173 0 : oHeader.addValue( CADHeader::AUPREC, buffer.ReadBITSHORT() ); // 6
174 : } else
175 : {
176 56 : for( char i = 0; i < 6; ++i )
177 48 : buffer.SkipBITSHORT();
178 : }
179 :
180 8 : oHeader.addValue( CADHeader::ATTMODE, buffer.ReadBITSHORT() );
181 8 : oHeader.addValue( CADHeader::PDMODE, buffer.ReadBITSHORT() );
182 :
183 8 : if( eOptions == OpenOptions::READ_ALL )
184 : {
185 0 : oHeader.addValue( CADHeader::USERI1, buffer.ReadBITSHORT() ); // 1
186 0 : oHeader.addValue( CADHeader::USERI2, buffer.ReadBITSHORT() ); // 2
187 0 : oHeader.addValue( CADHeader::USERI3, buffer.ReadBITSHORT() ); // 3
188 0 : oHeader.addValue( CADHeader::USERI4, buffer.ReadBITSHORT() ); // 4
189 0 : oHeader.addValue( CADHeader::USERI5, buffer.ReadBITSHORT() ); // 5
190 0 : oHeader.addValue( CADHeader::SPLINESEGS, buffer.ReadBITSHORT() );// 6
191 0 : oHeader.addValue( CADHeader::SURFU, buffer.ReadBITSHORT() ); // 7
192 0 : oHeader.addValue( CADHeader::SURFV, buffer.ReadBITSHORT() ); // 8
193 0 : oHeader.addValue( CADHeader::SURFTYPE, buffer.ReadBITSHORT() ); // 9
194 0 : oHeader.addValue( CADHeader::SURFTAB1, buffer.ReadBITSHORT() ); // 10
195 0 : oHeader.addValue( CADHeader::SURFTAB2, buffer.ReadBITSHORT() ); // 11
196 0 : oHeader.addValue( CADHeader::SPLINETYPE, buffer.ReadBITSHORT() );// 12
197 0 : oHeader.addValue( CADHeader::SHADEDGE, buffer.ReadBITSHORT() ); // 13
198 0 : oHeader.addValue( CADHeader::SHADEDIF, buffer.ReadBITSHORT() ); // 14
199 0 : oHeader.addValue( CADHeader::UNITMODE, buffer.ReadBITSHORT() ); // 15
200 0 : oHeader.addValue( CADHeader::MAXACTVP, buffer.ReadBITSHORT() ); // 16
201 0 : oHeader.addValue( CADHeader::ISOLINES, buffer.ReadBITSHORT() ); // 17
202 0 : oHeader.addValue( CADHeader::CMLJUST, buffer.ReadBITSHORT() ); // 18
203 0 : oHeader.addValue( CADHeader::TEXTQLTY, buffer.ReadBITSHORT() ); // 19
204 : }
205 : else
206 : {
207 160 : for( char i = 0; i < 19; ++i )
208 152 : buffer.SkipBITSHORT();
209 : }
210 :
211 8 : oHeader.addValue( CADHeader::LTSCALE, buffer.ReadBITDOUBLE() );
212 8 : oHeader.addValue( CADHeader::TEXTSIZE, buffer.ReadBITDOUBLE() );
213 8 : oHeader.addValue( CADHeader::TRACEWID, buffer.ReadBITDOUBLE() );
214 8 : oHeader.addValue( CADHeader::SKETCHINC, buffer.ReadBITDOUBLE() );
215 8 : oHeader.addValue( CADHeader::FILLETRAD, buffer.ReadBITDOUBLE() );
216 8 : oHeader.addValue( CADHeader::THICKNESS, buffer.ReadBITDOUBLE() );
217 8 : oHeader.addValue( CADHeader::ANGBASE, buffer.ReadBITDOUBLE() );
218 8 : oHeader.addValue( CADHeader::PDSIZE, buffer.ReadBITDOUBLE() );
219 8 : oHeader.addValue( CADHeader::PLINEWID, buffer.ReadBITDOUBLE() );
220 :
221 8 : if( eOptions == OpenOptions::READ_ALL )
222 : {
223 0 : oHeader.addValue( CADHeader::USERR1, buffer.ReadBITDOUBLE() ); // 1
224 0 : oHeader.addValue( CADHeader::USERR2, buffer.ReadBITDOUBLE() ); // 2
225 0 : oHeader.addValue( CADHeader::USERR3, buffer.ReadBITDOUBLE() ); // 3
226 0 : oHeader.addValue( CADHeader::USERR4, buffer.ReadBITDOUBLE() ); // 4
227 0 : oHeader.addValue( CADHeader::USERR5, buffer.ReadBITDOUBLE() ); // 5
228 0 : oHeader.addValue( CADHeader::CHAMFERA, buffer.ReadBITDOUBLE() ); // 6
229 0 : oHeader.addValue( CADHeader::CHAMFERB, buffer.ReadBITDOUBLE() ); // 7
230 0 : oHeader.addValue( CADHeader::CHAMFERC, buffer.ReadBITDOUBLE() ); // 8
231 0 : oHeader.addValue( CADHeader::CHAMFERD, buffer.ReadBITDOUBLE() ); // 9
232 0 : oHeader.addValue( CADHeader::FACETRES, buffer.ReadBITDOUBLE() ); // 10
233 0 : oHeader.addValue( CADHeader::CMLSCALE, buffer.ReadBITDOUBLE() ); // 11
234 0 : oHeader.addValue( CADHeader::CELTSCALE, buffer.ReadBITDOUBLE() );// 12
235 :
236 0 : oHeader.addValue( CADHeader::MENU, buffer.ReadTV() );
237 : } else
238 : {
239 104 : for( char i = 0; i < 12; ++i )
240 96 : buffer.SkipBITDOUBLE();
241 8 : buffer.SkipTV();
242 : }
243 :
244 : long juliandate, millisec;
245 8 : juliandate = buffer.ReadBITLONG();
246 8 : millisec = buffer.ReadBITLONG();
247 8 : oHeader.addValue( CADHeader::TDCREATE, juliandate, millisec );
248 8 : juliandate = buffer.ReadBITLONG();
249 8 : millisec = buffer.ReadBITLONG();
250 8 : oHeader.addValue( CADHeader::TDUPDATE, juliandate, millisec );
251 8 : juliandate = buffer.ReadBITLONG();
252 8 : millisec = buffer.ReadBITLONG();
253 8 : oHeader.addValue( CADHeader::TDINDWG, juliandate, millisec );
254 8 : juliandate = buffer.ReadBITLONG();
255 8 : millisec = buffer.ReadBITLONG();
256 8 : oHeader.addValue( CADHeader::TDUSRTIMER, juliandate, millisec );
257 :
258 8 : oHeader.addValue( CADHeader::CECOLOR, buffer.ReadBITSHORT() );
259 :
260 8 : oHeader.addValue( CADHeader::HANDSEED, buffer.ReadHANDLE() );
261 :
262 8 : oHeader.addValue( CADHeader::CLAYER, buffer.ReadHANDLE() );
263 8 : oHeader.addValue( CADHeader::TEXTSTYLE, buffer.ReadHANDLE() );
264 8 : oHeader.addValue( CADHeader::CELTYPE, buffer.ReadHANDLE() );
265 8 : oHeader.addValue( CADHeader::DIMSTYLE, buffer.ReadHANDLE() );
266 8 : oHeader.addValue( CADHeader::CMLSTYLE, buffer.ReadHANDLE() );
267 :
268 8 : oHeader.addValue( CADHeader::PSVPSCALE, buffer.ReadBITDOUBLE() );
269 : double dX, dY, dZ;
270 8 : dX = buffer.ReadBITDOUBLE();
271 8 : dY = buffer.ReadBITDOUBLE();
272 8 : dZ = buffer.ReadBITDOUBLE();
273 8 : oHeader.addValue( CADHeader::PINSBASE, dX, dY, dZ );
274 :
275 8 : dX = buffer.ReadBITDOUBLE();
276 8 : dY = buffer.ReadBITDOUBLE();
277 8 : dZ = buffer.ReadBITDOUBLE();
278 8 : oHeader.addValue( CADHeader::PEXTMIN, dX, dY, dZ );
279 8 : dX = buffer.ReadBITDOUBLE();
280 8 : dY = buffer.ReadBITDOUBLE();
281 8 : dZ = buffer.ReadBITDOUBLE();
282 8 : oHeader.addValue( CADHeader::PEXTMAX, dX, dY, dZ );
283 8 : dX = buffer.ReadRAWDOUBLE();
284 8 : dY = buffer.ReadRAWDOUBLE();
285 8 : oHeader.addValue( CADHeader::PLIMMIN, dX, dY );
286 8 : dX = buffer.ReadRAWDOUBLE();
287 8 : dY = buffer.ReadRAWDOUBLE();
288 8 : oHeader.addValue( CADHeader::PLIMMAX, dX, dY );
289 :
290 8 : oHeader.addValue( CADHeader::PELEVATION, buffer.ReadBITDOUBLE() );
291 :
292 8 : dX = buffer.ReadBITDOUBLE();
293 8 : dY = buffer.ReadBITDOUBLE();
294 8 : dZ = buffer.ReadBITDOUBLE();
295 8 : oHeader.addValue( CADHeader::PUCSORG, dX, dY, dZ );
296 8 : dX = buffer.ReadBITDOUBLE();
297 8 : dY = buffer.ReadBITDOUBLE();
298 8 : dZ = buffer.ReadBITDOUBLE();
299 8 : oHeader.addValue( CADHeader::PUCSXDIR, dX, dY, dZ );
300 8 : dX = buffer.ReadBITDOUBLE();
301 8 : dY = buffer.ReadBITDOUBLE();
302 8 : dZ = buffer.ReadBITDOUBLE();
303 8 : oHeader.addValue( CADHeader::PUCSYDIR, dX, dY, dZ );
304 :
305 8 : oHeader.addValue( CADHeader::PUCSNAME, buffer.ReadHANDLE() );
306 8 : oHeader.addValue( CADHeader::PUCSORTHOREF, buffer.ReadHANDLE() );
307 :
308 8 : oHeader.addValue( CADHeader::PUCSORTHOVIEW, buffer.ReadBITSHORT() );
309 8 : oHeader.addValue( CADHeader::PUCSBASE, buffer.ReadHANDLE() );
310 :
311 8 : dX = buffer.ReadBITDOUBLE();
312 8 : dY = buffer.ReadBITDOUBLE();
313 8 : dZ = buffer.ReadBITDOUBLE();
314 8 : oHeader.addValue( CADHeader::PUCSORGTOP, dX, dY, dZ );
315 8 : dX = buffer.ReadBITDOUBLE();
316 8 : dY = buffer.ReadBITDOUBLE();
317 8 : dZ = buffer.ReadBITDOUBLE();
318 8 : oHeader.addValue( CADHeader::PUCSORGBOTTOM, dX, dY, dZ );
319 8 : dX = buffer.ReadBITDOUBLE();
320 8 : dY = buffer.ReadBITDOUBLE();
321 8 : dZ = buffer.ReadBITDOUBLE();
322 8 : oHeader.addValue( CADHeader::PUCSORGLEFT, dX, dY, dZ );
323 8 : dX = buffer.ReadBITDOUBLE();
324 8 : dY = buffer.ReadBITDOUBLE();
325 8 : dZ = buffer.ReadBITDOUBLE();
326 8 : oHeader.addValue( CADHeader::PUCSORGRIGHT, dX, dY, dZ );
327 8 : dX = buffer.ReadBITDOUBLE();
328 8 : dY = buffer.ReadBITDOUBLE();
329 8 : dZ = buffer.ReadBITDOUBLE();
330 8 : oHeader.addValue( CADHeader::PUCSORGFRONT, dX, dY, dZ );
331 8 : dX = buffer.ReadBITDOUBLE();
332 8 : dY = buffer.ReadBITDOUBLE();
333 8 : dZ = buffer.ReadBITDOUBLE();
334 8 : oHeader.addValue( CADHeader::PUCSORGBACK, dX, dY, dZ );
335 :
336 8 : dX = buffer.ReadBITDOUBLE();
337 8 : dY = buffer.ReadBITDOUBLE();
338 8 : dZ = buffer.ReadBITDOUBLE();
339 8 : oHeader.addValue( CADHeader::INSBASE, dX, dY, dZ );
340 8 : dX = buffer.ReadBITDOUBLE();
341 8 : dY = buffer.ReadBITDOUBLE();
342 8 : dZ = buffer.ReadBITDOUBLE();
343 8 : oHeader.addValue( CADHeader::EXTMIN, dX, dY, dZ );
344 8 : dX = buffer.ReadBITDOUBLE();
345 8 : dY = buffer.ReadBITDOUBLE();
346 8 : dZ = buffer.ReadBITDOUBLE();
347 8 : oHeader.addValue( CADHeader::EXTMAX, dX, dY, dZ );
348 8 : dX = buffer.ReadRAWDOUBLE();
349 8 : dY = buffer.ReadRAWDOUBLE();
350 8 : oHeader.addValue( CADHeader::LIMMIN, dX, dY );
351 8 : dX = buffer.ReadRAWDOUBLE();
352 8 : dY = buffer.ReadRAWDOUBLE();
353 8 : oHeader.addValue( CADHeader::LIMMAX, dX, dY );
354 :
355 8 : oHeader.addValue( CADHeader::ELEVATION, buffer.ReadBITDOUBLE() );
356 8 : dX = buffer.ReadBITDOUBLE();
357 8 : dY = buffer.ReadBITDOUBLE();
358 8 : dZ = buffer.ReadBITDOUBLE();
359 8 : oHeader.addValue( CADHeader::UCSORG, dX, dY, dZ );
360 8 : dX = buffer.ReadBITDOUBLE();
361 8 : dY = buffer.ReadBITDOUBLE();
362 8 : dZ = buffer.ReadBITDOUBLE();
363 8 : oHeader.addValue( CADHeader::UCSXDIR, dX, dY, dZ );
364 8 : dX = buffer.ReadBITDOUBLE();
365 8 : dY = buffer.ReadBITDOUBLE();
366 8 : dZ = buffer.ReadBITDOUBLE();
367 8 : oHeader.addValue( CADHeader::UCSYDIR, dX, dY, dZ );
368 :
369 8 : oHeader.addValue( CADHeader::UCSNAME, buffer.ReadHANDLE() );
370 8 : oHeader.addValue( CADHeader::UCSORTHOREF, buffer.ReadHANDLE() );
371 :
372 8 : oHeader.addValue( CADHeader::UCSORTHOVIEW, buffer.ReadBITSHORT() );
373 :
374 8 : oHeader.addValue( CADHeader::UCSBASE, buffer.ReadHANDLE() );
375 :
376 8 : dX = buffer.ReadBITDOUBLE();
377 8 : dY = buffer.ReadBITDOUBLE();
378 8 : dZ = buffer.ReadBITDOUBLE();
379 8 : oHeader.addValue( CADHeader::UCSORGTOP, dX, dY, dZ );
380 8 : dX = buffer.ReadBITDOUBLE();
381 8 : dY = buffer.ReadBITDOUBLE();
382 8 : dZ = buffer.ReadBITDOUBLE();
383 8 : oHeader.addValue( CADHeader::UCSORGBOTTOM, dX, dY, dZ );
384 8 : dX = buffer.ReadBITDOUBLE();
385 8 : dY = buffer.ReadBITDOUBLE();
386 8 : dZ = buffer.ReadBITDOUBLE();
387 8 : oHeader.addValue( CADHeader::UCSORGLEFT, dX, dY, dZ );
388 8 : dX = buffer.ReadBITDOUBLE();
389 8 : dY = buffer.ReadBITDOUBLE();
390 8 : dZ = buffer.ReadBITDOUBLE();
391 8 : oHeader.addValue( CADHeader::UCSORGRIGHT, dX, dY, dZ );
392 8 : dX = buffer.ReadBITDOUBLE();
393 8 : dY = buffer.ReadBITDOUBLE();
394 8 : dZ = buffer.ReadBITDOUBLE();
395 8 : oHeader.addValue( CADHeader::UCSORGFRONT, dX, dY, dZ );
396 8 : dX = buffer.ReadBITDOUBLE();
397 8 : dY = buffer.ReadBITDOUBLE();
398 8 : dZ = buffer.ReadBITDOUBLE();
399 8 : oHeader.addValue( CADHeader::UCSORGBACK, dX, dY, dZ );
400 :
401 8 : if( eOptions == OpenOptions::READ_ALL )
402 : {
403 0 : oHeader.addValue( CADHeader::DIMPOST, buffer.ReadTV() );
404 0 : oHeader.addValue( CADHeader::DIMAPOST, buffer.ReadTV() );
405 :
406 0 : oHeader.addValue( CADHeader::DIMSCALE, buffer.ReadBITDOUBLE() ); // 1
407 0 : oHeader.addValue( CADHeader::DIMASZ, buffer.ReadBITDOUBLE() ); // 2
408 0 : oHeader.addValue( CADHeader::DIMEXO, buffer.ReadBITDOUBLE() ); // 3
409 0 : oHeader.addValue( CADHeader::DIMDLI, buffer.ReadBITDOUBLE() ); // 4
410 0 : oHeader.addValue( CADHeader::DIMEXE, buffer.ReadBITDOUBLE() ); // 5
411 0 : oHeader.addValue( CADHeader::DIMRND, buffer.ReadBITDOUBLE() ); // 6
412 0 : oHeader.addValue( CADHeader::DIMDLE, buffer.ReadBITDOUBLE() ); // 7
413 0 : oHeader.addValue( CADHeader::DIMTP, buffer.ReadBITDOUBLE() ); // 8
414 0 : oHeader.addValue( CADHeader::DIMTM, buffer.ReadBITDOUBLE() ); // 9
415 :
416 0 : oHeader.addValue( CADHeader::DIMTOL, buffer.ReadBIT() );
417 0 : oHeader.addValue( CADHeader::DIMLIM, buffer.ReadBIT() );
418 0 : oHeader.addValue( CADHeader::DIMTIH, buffer.ReadBIT() );
419 0 : oHeader.addValue( CADHeader::DIMTOH, buffer.ReadBIT() );
420 0 : oHeader.addValue( CADHeader::DIMSE1, buffer.ReadBIT() );
421 0 : oHeader.addValue( CADHeader::DIMSE2, buffer.ReadBIT() );
422 :
423 0 : oHeader.addValue( CADHeader::DIMTAD, buffer.ReadBITSHORT() );
424 0 : oHeader.addValue( CADHeader::DIMZIN, buffer.ReadBITSHORT() );
425 0 : oHeader.addValue( CADHeader::DIMAZIN, buffer.ReadBITSHORT() );
426 :
427 0 : oHeader.addValue( CADHeader::DIMTXT, buffer.ReadBITDOUBLE() ); // 1
428 0 : oHeader.addValue( CADHeader::DIMCEN, buffer.ReadBITDOUBLE() ); // 2
429 0 : oHeader.addValue( CADHeader::DIMTSZ, buffer.ReadBITDOUBLE() ); // 3
430 0 : oHeader.addValue( CADHeader::DIMALTF, buffer.ReadBITDOUBLE() ); // 4
431 0 : oHeader.addValue( CADHeader::DIMLFAC, buffer.ReadBITDOUBLE() ); // 5
432 0 : oHeader.addValue( CADHeader::DIMTVP, buffer.ReadBITDOUBLE() ); // 6
433 0 : oHeader.addValue( CADHeader::DIMTFAC, buffer.ReadBITDOUBLE() ); // 7
434 0 : oHeader.addValue( CADHeader::DIMGAP, buffer.ReadBITDOUBLE() ); // 8
435 0 : oHeader.addValue( CADHeader::DIMALTRND, buffer.ReadBITDOUBLE() );// 9
436 :
437 0 : oHeader.addValue( CADHeader::DIMALT, buffer.ReadBIT() );
438 :
439 0 : oHeader.addValue( CADHeader::DIMALTD, buffer.ReadBITSHORT() );
440 :
441 0 : oHeader.addValue( CADHeader::DIMTOFL, buffer.ReadBIT() );
442 0 : oHeader.addValue( CADHeader::DIMSAH, buffer.ReadBIT() );
443 0 : oHeader.addValue( CADHeader::DIMTIX, buffer.ReadBIT() );
444 0 : oHeader.addValue( CADHeader::DIMSOXD, buffer.ReadBIT() );
445 :
446 0 : oHeader.addValue( CADHeader::DIMCLRD, buffer.ReadBITSHORT() ); // 1
447 0 : oHeader.addValue( CADHeader::DIMCLRE, buffer.ReadBITSHORT() ); // 2
448 0 : oHeader.addValue( CADHeader::DIMCLRT, buffer.ReadBITSHORT() ); // 3
449 0 : oHeader.addValue( CADHeader::DIMADEC, buffer.ReadBITSHORT() ); // 4
450 0 : oHeader.addValue( CADHeader::DIMDEC, buffer.ReadBITSHORT() ); // 5
451 0 : oHeader.addValue( CADHeader::DIMTDEC, buffer.ReadBITSHORT() ); // 6
452 0 : oHeader.addValue( CADHeader::DIMALTU, buffer.ReadBITSHORT() ); // 7
453 0 : oHeader.addValue( CADHeader::DIMALTTD, buffer.ReadBITSHORT() ); // 8
454 0 : oHeader.addValue( CADHeader::DIMAUNIT, buffer.ReadBITSHORT() ); // 9
455 0 : oHeader.addValue( CADHeader::DIMFRAC, buffer.ReadBITSHORT() ); // 10
456 0 : oHeader.addValue( CADHeader::DIMLUNIT, buffer.ReadBITSHORT() ); // 11
457 0 : oHeader.addValue( CADHeader::DIMDSEP, buffer.ReadBITSHORT() ); // 12
458 0 : oHeader.addValue( CADHeader::DIMTMOVE, buffer.ReadBITSHORT() ); // 13
459 0 : oHeader.addValue( CADHeader::DIMJUST, buffer.ReadBITSHORT() ); // 14
460 :
461 0 : oHeader.addValue( CADHeader::DIMSD1, buffer.ReadBIT() );
462 0 : oHeader.addValue( CADHeader::DIMSD2, buffer.ReadBIT() );
463 :
464 0 : oHeader.addValue( CADHeader::DIMTOLJ, buffer.ReadBITSHORT() );
465 0 : oHeader.addValue( CADHeader::DIMTZIN, buffer.ReadBITSHORT() );
466 0 : oHeader.addValue( CADHeader::DIMALTZ, buffer.ReadBITSHORT() );
467 0 : oHeader.addValue( CADHeader::DIMALTTZ, buffer.ReadBITSHORT() );
468 :
469 0 : oHeader.addValue( CADHeader::DIMUPT, buffer.ReadBIT() );
470 :
471 0 : oHeader.addValue( CADHeader::DIMATFIT, buffer.ReadBITSHORT() );
472 :
473 0 : oHeader.addValue( CADHeader::DIMTXSTY, buffer.ReadHANDLE() );
474 0 : oHeader.addValue( CADHeader::DIMLDRBLK, buffer.ReadHANDLE() );
475 0 : oHeader.addValue( CADHeader::DIMBLK, buffer.ReadHANDLE() );
476 0 : oHeader.addValue( CADHeader::DIMBLK1, buffer.ReadHANDLE() );
477 0 : oHeader.addValue( CADHeader::DIMBLK2, buffer.ReadHANDLE() );
478 :
479 0 : oHeader.addValue( CADHeader::DIMLWD, buffer.ReadBITSHORT() );
480 0 : oHeader.addValue( CADHeader::DIMLWE, buffer.ReadBITSHORT() );
481 : } else
482 : {
483 8 : buffer.SkipTV();
484 8 : buffer.SkipTV();
485 :
486 80 : for( char i = 0; i < 9; ++i )
487 72 : buffer.SkipBITDOUBLE();
488 :
489 8 : buffer.Seek(6);
490 :
491 32 : for( char i = 0; i < 3; ++i )
492 24 : buffer.SkipBITSHORT();
493 :
494 80 : for( char i = 0; i < 9; ++i )
495 72 : buffer.SkipBITDOUBLE();
496 :
497 8 : buffer.Seek(1);
498 :
499 8 : buffer.SkipBITSHORT();
500 :
501 8 : buffer.Seek(4);
502 :
503 120 : for( char i = 0; i < 14; ++i )
504 112 : buffer.SkipBITSHORT();
505 :
506 8 : buffer.Seek(2);
507 :
508 40 : for( char i = 0; i < 4; ++i )
509 32 : buffer.SkipBITSHORT();
510 :
511 8 : buffer.Seek(1);
512 8 : buffer.SkipBITSHORT();
513 :
514 48 : for( char i = 0; i < 5; ++i )
515 40 : buffer.SkipHANDLE();
516 :
517 8 : buffer.SkipBITSHORT();
518 8 : buffer.SkipBITSHORT();
519 : }
520 :
521 16 : CADHandle stBlocksTable = buffer.ReadHANDLE();
522 8 : oTables.AddTable( CADTables::BlocksTable, stBlocksTable );
523 :
524 16 : CADHandle stLayersTable = buffer.ReadHANDLE();
525 8 : oTables.AddTable( CADTables::LayersTable, stLayersTable );
526 :
527 16 : CADHandle stStyleTable = buffer.ReadHANDLE();
528 8 : oTables.AddTable( CADTables::StyleTable, stStyleTable );
529 :
530 16 : CADHandle stLineTypesTable = buffer.ReadHANDLE();
531 8 : oTables.AddTable( CADTables::LineTypesTable, stLineTypesTable );
532 :
533 16 : CADHandle stViewTable = buffer.ReadHANDLE();
534 8 : oTables.AddTable( CADTables::ViewTable, stViewTable );
535 :
536 16 : CADHandle stUCSTable = buffer.ReadHANDLE();
537 8 : oTables.AddTable( CADTables::UCSTable, stUCSTable );
538 :
539 16 : CADHandle stViewportTable = buffer.ReadHANDLE();
540 8 : oTables.AddTable( CADTables::ViewportTable, stViewportTable );
541 :
542 16 : CADHandle stAPPIDTable = buffer.ReadHANDLE();
543 8 : oTables.AddTable( CADTables::APPIDTable, stAPPIDTable );
544 :
545 8 : if( eOptions == OpenOptions::READ_ALL )
546 : {
547 0 : oHeader.addValue( CADHeader::DIMSTYLE, buffer.ReadHANDLE() );
548 : }
549 : else
550 : {
551 8 : buffer.SkipHANDLE();
552 : }
553 :
554 16 : CADHandle stEntityTable = buffer.ReadHANDLE();
555 8 : oTables.AddTable( CADTables::EntityTable, stEntityTable );
556 :
557 16 : CADHandle stACADGroupDict = buffer.ReadHANDLE();
558 8 : oTables.AddTable( CADTables::ACADGroupDict, stACADGroupDict );
559 :
560 16 : CADHandle stACADMLineStyleDict = buffer.ReadHANDLE();
561 8 : oTables.AddTable( CADTables::ACADMLineStyleDict, stACADMLineStyleDict );
562 :
563 16 : CADHandle stNamedObjectsDict = buffer.ReadHANDLE();
564 8 : oTables.AddTable( CADTables::NamedObjectsDict, stNamedObjectsDict );
565 :
566 8 : if( eOptions == OpenOptions::READ_ALL )
567 : {
568 0 : oHeader.addValue( CADHeader::TSTACKALIGN, buffer.ReadBITSHORT() );
569 0 : oHeader.addValue( CADHeader::TSTACKSIZE, buffer.ReadBITSHORT() );
570 : } else
571 : {
572 8 : buffer.SkipBITSHORT();
573 8 : buffer.SkipBITSHORT();
574 : }
575 :
576 8 : oHeader.addValue( CADHeader::HYPERLINKBASE, buffer.ReadTV() );
577 8 : oHeader.addValue( CADHeader::STYLESHEET, buffer.ReadTV() );
578 :
579 16 : CADHandle stLayoutsDict = buffer.ReadHANDLE();
580 8 : oTables.AddTable( CADTables::LayoutsDict, stLayoutsDict );
581 :
582 16 : CADHandle stPlotSettingsDict = buffer.ReadHANDLE();
583 8 : oTables.AddTable( CADTables::PlotSettingsDict, stPlotSettingsDict );
584 :
585 16 : CADHandle stPlotStylesDict = buffer.ReadHANDLE();
586 8 : oTables.AddTable( CADTables::PlotStylesDict, stPlotStylesDict );
587 :
588 8 : if( eOptions == OpenOptions::READ_ALL )
589 : {
590 0 : int Flags = buffer.ReadBITLONG();
591 0 : oHeader.addValue( CADHeader::CELWEIGHT, Flags & 0x001F );
592 0 : oHeader.addValue( CADHeader::ENDCAPS, ( Flags & 0x0060 ) != 0 );
593 0 : oHeader.addValue( CADHeader::JOINSTYLE, (Flags & 0x0180) != 0);
594 0 : oHeader.addValue( CADHeader::LWDISPLAY, ( Flags & 0x0200 ) == 0);
595 0 : oHeader.addValue( CADHeader::XEDIT, ( Flags & 0x0400 ) == 0);
596 0 : oHeader.addValue( CADHeader::EXTNAMES, ( Flags & 0x0800 ) != 0 );
597 0 : oHeader.addValue( CADHeader::PSTYLEMODE, ( Flags & 0x2000 ) != 0 );
598 0 : oHeader.addValue( CADHeader::OLESTARTUP, ( Flags & 0x4000 ) != 0);
599 : }
600 : else
601 : {
602 8 : buffer.SkipBITLONG();
603 : }
604 :
605 8 : oHeader.addValue( CADHeader::INSUNITS, buffer.ReadBITSHORT() );
606 8 : short nCEPSNTYPE = buffer.ReadBITSHORT();
607 8 : oHeader.addValue( CADHeader::CEPSNTYPE, nCEPSNTYPE );
608 :
609 8 : if( nCEPSNTYPE == 3 )
610 0 : oHeader.addValue( CADHeader::CEPSNID, buffer.ReadHANDLE() );
611 :
612 8 : oHeader.addValue( CADHeader::FINGERPRINTGUID, buffer.ReadTV() );
613 8 : oHeader.addValue( CADHeader::VERSIONGUID, buffer.ReadTV() );
614 :
615 16 : CADHandle stBlockRecordPaperSpace = buffer.ReadHANDLE();
616 8 : oTables.AddTable( CADTables::BlockRecordPaperSpace, stBlockRecordPaperSpace );
617 : // TODO: is this part of the header?
618 16 : CADHandle stBlockRecordModelSpace = buffer.ReadHANDLE();
619 8 : oTables.AddTable( CADTables::BlockRecordModelSpace, stBlockRecordModelSpace );
620 :
621 8 : if( eOptions == OpenOptions::READ_ALL )
622 : {
623 : // Is this part of the header?
624 :
625 0 : /*CADHandle LTYPE_BYLAYER = */buffer.ReadHANDLE();
626 0 : /*CADHandle LTYPE_BYBLOCK = */buffer.ReadHANDLE();
627 0 : /*CADHandle LTYPE_CONTINUOUS = */buffer.ReadHANDLE();
628 :
629 0 : oHeader.addValue( UNKNOWN11, buffer.ReadBITSHORT() );
630 0 : oHeader.addValue( UNKNOWN12, buffer.ReadBITSHORT() );
631 0 : oHeader.addValue( UNKNOWN13, buffer.ReadBITSHORT() );
632 0 : oHeader.addValue( UNKNOWN14, buffer.ReadBITSHORT() );
633 : } else
634 : {
635 8 : buffer.SkipHANDLE();
636 8 : buffer.SkipHANDLE();
637 8 : buffer.SkipHANDLE();
638 8 : buffer.SkipBITSHORT();
639 8 : buffer.SkipBITSHORT();
640 8 : buffer.SkipBITSHORT();
641 8 : buffer.SkipBITSHORT();
642 : }
643 :
644 8 : int returnCode = CADErrorCodes::SUCCESS;
645 8 : unsigned short dSectionCRC = validateEntityCRC( buffer,
646 : static_cast<unsigned int>(dHeaderVarsSectionLength + dSizeOfSectionSize), "HEADERVARS" );
647 : #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
648 : (void)dSectionCRC;
649 : #else
650 8 : if(dSectionCRC == 0)
651 : {
652 0 : std::cerr << "File is corrupted (HEADERVARS section CRC doesn't match.)\n";
653 0 : return CADErrorCodes::HEADER_SECTION_READ_FAILED;
654 : }
655 : #endif
656 8 : pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
657 : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
658 8 : if( memcmp( bufferPre, DWGConstants::HeaderVariablesEnd,
659 : DWGConstants::SentinelLength ) )
660 : {
661 : std::cerr << "File is corrupted (HEADERVARS section ending sentinel "
662 0 : "doesn't match.)\n";
663 0 : returnCode = CADErrorCodes::HEADER_SECTION_READ_FAILED;
664 : }
665 : #endif
666 8 : return returnCode;
667 : }
668 :
669 8 : int DWGFileR2000::ReadClasses( enum OpenOptions eOptions )
670 : {
671 8 : if( eOptions == OpenOptions::READ_ALL || eOptions == OpenOptions::READ_FAST )
672 : {
673 : char bufferPre[255];
674 8 : unsigned dSectionSize = 0;
675 8 : constexpr size_t dSizeOfSectionSize = sizeof(dSectionSize);
676 :
677 8 : pFileIO->Seek( sectionLocatorRecords[1].dSeeker, CADFileIO::SeekOrigin::BEG );
678 :
679 8 : pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
680 : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
681 8 : if( memcmp( bufferPre, DWGConstants::DSClassesStart,
682 : DWGConstants::SentinelLength ) )
683 : {
684 : std::cerr << "File is corrupted (wrong pointer to CLASSES section,"
685 0 : "or CLASSES starting sentinel corrupted.)\n";
686 :
687 0 : return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
688 : }
689 : #endif
690 :
691 8 : pFileIO->Read( &dSectionSize, dSizeOfSectionSize );
692 8 : const auto dSectionSizeOriginal = dSectionSize;
693 8 : FromLSB(dSectionSize);
694 8 : DebugMsg("Classes section length: %d\n",
695 : static_cast<int>(dSectionSize) );
696 8 : if(dSectionSize > 65535) {
697 0 : DebugMsg("File is corrupted (CLASSES section is too large: %d\n",
698 : static_cast<int>(dSectionSize));
699 :
700 0 : return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
701 : }
702 :
703 8 : CADBuffer buffer(dSectionSize + dSizeOfSectionSize + 10);
704 8 : buffer.WriteRAW(&dSectionSizeOriginal, dSizeOfSectionSize);
705 8 : size_t readSize = pFileIO->Read( buffer.GetRawBuffer(), dSectionSize + 2 );
706 8 : if(readSize != dSectionSize + 2)
707 : {
708 0 : DebugMsg( "Failed to read %d byte of file. Read only %d",
709 0 : static_cast<int>(dSectionSize + 2),
710 : static_cast<int>(readSize) );
711 0 : return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
712 : }
713 :
714 8 : const size_t dSectionBitSize = (dSectionSize + dSizeOfSectionSize) * 8;
715 129 : while( buffer.PositionBit() < dSectionBitSize - 8)
716 : {
717 121 : CADClass stClass;
718 121 : stClass.dClassNum = buffer.ReadBITSHORT();
719 121 : stClass.dProxyCapFlag = buffer.ReadBITSHORT();
720 121 : stClass.sApplicationName = buffer.ReadTV();
721 121 : stClass.sCppClassName = buffer.ReadTV();
722 121 : stClass.sDXFRecordName = buffer.ReadTV();
723 121 : stClass.bWasZombie = buffer.ReadBIT();
724 121 : stClass.bIsEntity = buffer.ReadBITSHORT() == 0x1F2;
725 :
726 121 : oClasses.addClass( std::move(stClass) );
727 : }
728 :
729 8 : buffer.Seek(dSectionBitSize, CADBuffer::BEG);
730 8 : unsigned short dSectionCRC = validateEntityCRC( buffer,
731 : static_cast<unsigned int>(dSectionSize + dSizeOfSectionSize),
732 : "CLASSES" );
733 : #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
734 : (void)dSectionCRC;
735 : #else
736 8 : if(dSectionCRC == 0)
737 : {
738 0 : std::cerr << "File is corrupted (CLASSES section CRC doesn't match.)\n";
739 0 : return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
740 : }
741 : #endif
742 :
743 8 : pFileIO->Read( bufferPre, DWGConstants::SentinelLength );
744 : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
745 8 : if( memcmp( bufferPre, DWGConstants::DSClassesEnd,
746 : DWGConstants::SentinelLength ) )
747 : {
748 : std::cerr << "File is corrupted (CLASSES section ending sentinel "
749 0 : "doesn't match.)\n";
750 0 : return CADErrorCodes::CLASSES_SECTION_READ_FAILED;
751 : }
752 : #endif
753 : }
754 8 : return CADErrorCodes::SUCCESS;
755 : }
756 :
757 8 : int DWGFileR2000::CreateFileMap()
758 : {
759 8 : size_t nSection = 0;
760 :
761 : typedef pair<long, long> ObjHandleOffset;
762 8 : ObjHandleOffset previousObjHandleOffset;
763 8 : ObjHandleOffset tmpOffset;
764 :
765 8 : mapObjects.clear();
766 :
767 : // Seek to the beginning of the objects map
768 8 : pFileIO->Seek( sectionLocatorRecords[2].dSeeker, CADFileIO::SeekOrigin::BEG );
769 :
770 : while( true )
771 : {
772 16 : unsigned short dSectionSize = 0;
773 16 : constexpr size_t dSizeOfSectionSize = sizeof(dSectionSize);
774 :
775 : // Read section size
776 :
777 16 : pFileIO->Read( &dSectionSize, dSizeOfSectionSize );
778 16 : const unsigned short dSectionSizeOriginal = dSectionSize;
779 : #if !defined(CAD_MSB)
780 16 : SwapEndianness( dSectionSize, sizeof( dSectionSize ) );
781 : #endif
782 :
783 16 : DebugMsg( "Object map section #%d size: %d\n",
784 : static_cast<int>(++nSection), dSectionSize );
785 :
786 16 : if( dSectionSize <= dSizeOfSectionSize )
787 8 : break; // Last section is empty.
788 :
789 8 : CADBuffer buffer(dSectionSize + dSizeOfSectionSize + 10);
790 8 : buffer.WriteRAW(&dSectionSizeOriginal, dSizeOfSectionSize);
791 8 : size_t nRecordsInSection = 0;
792 :
793 : // Read section datsa
794 8 : size_t readSize = pFileIO->Read( buffer.GetRawBuffer(), dSectionSize );
795 8 : if(readSize != dSectionSize)
796 : {
797 0 : DebugMsg( "Failed to read %d byte of file. Read only %d",
798 : static_cast<int>(dSectionSize),
799 : static_cast<int>(readSize) );
800 0 : return CADErrorCodes::OBJECTS_SECTION_READ_FAILED;
801 : }
802 8 : unsigned int dSectionBitSize = dSectionSize * 8;
803 :
804 1801 : while( buffer.PositionBit() < dSectionBitSize )
805 : {
806 1793 : tmpOffset.first = buffer.ReadUMCHAR(); // 8 + 8*8
807 1793 : tmpOffset.second = buffer.ReadMCHAR(); // 8 + 8*8
808 :
809 1793 : if( 0 == nRecordsInSection )
810 : {
811 8 : previousObjHandleOffset = tmpOffset;
812 : }
813 : else
814 : {
815 5355 : if( (tmpOffset.first >= 0 &&
816 1785 : std::numeric_limits<long>::max() - tmpOffset.first > previousObjHandleOffset.first) ||
817 0 : (tmpOffset.first < 0 &&
818 0 : std::numeric_limits<long>::min() - tmpOffset.first <= previousObjHandleOffset.first) )
819 : {
820 1785 : previousObjHandleOffset.first += tmpOffset.first;
821 : }
822 4632 : if( (tmpOffset.second >= 0 &&
823 2508 : std::numeric_limits<long>::max() - tmpOffset.second > previousObjHandleOffset.second) ||
824 723 : (tmpOffset.second < 0 &&
825 723 : std::numeric_limits<long>::min() - tmpOffset.second <= previousObjHandleOffset.second) )
826 : {
827 1785 : previousObjHandleOffset.second += tmpOffset.second;
828 : }
829 : }
830 : #ifdef _DEBUG
831 : assert( mapObjects.find( previousObjHandleOffset.first ) ==
832 : mapObjects.end() );
833 : #endif //_DEBUG
834 1793 : mapObjects.insert( previousObjHandleOffset );
835 1793 : ++nRecordsInSection;
836 : }
837 :
838 8 : unsigned short dSectionCRC = validateEntityCRC( buffer,
839 : static_cast<unsigned int>(dSectionSize), "OBJECTMAP", true );
840 : #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
841 : (void)dSectionCRC;
842 : #else
843 8 : if(dSectionCRC == 0)
844 : {
845 0 : std::cerr << "File is corrupted (OBJECTMAP section CRC doesn't match.)\n";
846 0 : return CADErrorCodes::OBJECTS_SECTION_READ_FAILED;
847 : }
848 : #endif
849 8 : }
850 :
851 8 : return CADErrorCodes::SUCCESS;
852 : }
853 :
854 213 : CADObject * DWGFileR2000::GetObject( long dHandle, bool bHandlesOnly )
855 : {
856 426 : CADBuffer buffer(8);
857 :
858 213 : pFileIO->Seek( mapObjects[dHandle], CADFileIO::SeekOrigin::BEG );
859 213 : pFileIO->Read( buffer.GetRawBuffer(), 8 );
860 213 : unsigned int dObjectSize = buffer.ReadMSHORT();
861 :
862 : // FIXME: Limit object size to 64kB
863 213 : if( dObjectSize > 65536 )
864 0 : return nullptr;
865 :
866 : // And read whole data chunk into memory for future parsing.
867 : // + nBitOffsetFromStart/8 + 2 is because dObjectSize doesn't cover CRC and itself.
868 213 : dObjectSize += static_cast<unsigned int>(buffer.PositionBit() / 8 + 2);
869 :
870 426 : CADBuffer objectBuffer(dObjectSize + 64);
871 :
872 213 : pFileIO->Seek( mapObjects[dHandle], CADFileIO::SeekOrigin::BEG );
873 213 : size_t readSize = pFileIO->Read( objectBuffer.GetRawBuffer(),
874 213 : static_cast<size_t>(dObjectSize) );
875 213 : if(readSize != static_cast<size_t>(dObjectSize))
876 : {
877 0 : DebugMsg( "Failed to read %d byte of file. Read only %d",
878 : static_cast<int>(dObjectSize),
879 : static_cast<int>(readSize) );
880 0 : return nullptr;
881 : }
882 :
883 213 : /* Unused dObjectSize = */ objectBuffer.ReadMSHORT();
884 213 : short dObjectType = objectBuffer.ReadBITSHORT();
885 213 : if( dObjectType >= 500 )
886 : {
887 16 : CADClass cadClass = oClasses.getClassByNum( dObjectType );
888 : // FIXME: replace strcmp() with C++ analog
889 8 : if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbRasterImage" ) )
890 : {
891 0 : dObjectType = CADObject::IMAGE;
892 : }
893 8 : else if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbRasterImageDef" ) )
894 : {
895 0 : dObjectType = CADObject::IMAGEDEF;
896 : }
897 8 : else if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbRasterImageDefReactor" ) )
898 : {
899 0 : dObjectType = CADObject::IMAGEDEFREACTOR;
900 : }
901 8 : else if( !strcmp( cadClass.sCppClassName.c_str(), "AcDbWipeout" ) )
902 : {
903 0 : dObjectType = CADObject::WIPEOUT;
904 : }
905 : }
906 :
907 : // Entities handling
908 213 : if( isCommonEntityType( dObjectType ) )
909 : {
910 70 : struct CADCommonED stCommonEntityData; // Common for all entities
911 :
912 35 : stCommonEntityData.nObjectSizeInBits = objectBuffer.ReadRAWLONG();
913 35 : stCommonEntityData.hObjectHandle = objectBuffer.ReadHANDLE();
914 :
915 : short dEEDSize;
916 70 : CADEed dwgEed;
917 50 : while( ( dEEDSize = objectBuffer.ReadBITSHORT() ) != 0 )
918 : {
919 15 : dwgEed.dLength = dEEDSize;
920 15 : dwgEed.hApplication = objectBuffer.ReadHANDLE();
921 :
922 15 : if(dEEDSize < 0)
923 : {
924 0 : return nullptr;
925 : }
926 :
927 1119 : for( short i = 0; i < dEEDSize; ++i )
928 : {
929 1104 : dwgEed.acData.push_back( objectBuffer.ReadCHAR() );
930 : }
931 :
932 15 : stCommonEntityData.aEED.push_back( dwgEed );
933 : }
934 :
935 35 : stCommonEntityData.bGraphicsPresented = objectBuffer.ReadBIT();
936 35 : if( stCommonEntityData.bGraphicsPresented )
937 : {
938 0 : const auto rawLong = objectBuffer.ReadRAWLONG();
939 0 : if( rawLong < 0 )
940 0 : return nullptr;
941 0 : size_t nGraphicsDataSize = static_cast<size_t>(rawLong);
942 0 : if( nGraphicsDataSize > std::numeric_limits<size_t>::max() / 8 )
943 0 : return nullptr;
944 : // Skip read graphics data
945 0 : buffer.Seek(nGraphicsDataSize * 8);
946 : }
947 35 : stCommonEntityData.bbEntMode = objectBuffer.Read2B();
948 35 : stCommonEntityData.nNumReactors = objectBuffer.ReadBITLONG();
949 35 : if(stCommonEntityData.nNumReactors < 0 ||
950 35 : stCommonEntityData.nNumReactors > 5000)
951 : {
952 0 : return nullptr;
953 : }
954 35 : stCommonEntityData.bNoLinks = objectBuffer.ReadBIT();
955 35 : stCommonEntityData.nCMColor = objectBuffer.ReadBITSHORT();
956 35 : stCommonEntityData.dfLTypeScale = objectBuffer.ReadBITDOUBLE();
957 35 : stCommonEntityData.bbLTypeFlags = objectBuffer.Read2B();
958 35 : stCommonEntityData.bbPlotStyleFlags = objectBuffer.Read2B();
959 35 : stCommonEntityData.nInvisibility = objectBuffer.ReadBITSHORT();
960 35 : stCommonEntityData.nLineWeight = objectBuffer.ReadCHAR();
961 :
962 : // Skip entitity-specific data, we don't need it if bHandlesOnly == true
963 35 : if( bHandlesOnly == true )
964 : {
965 18 : return getEntity( dObjectType, dObjectSize, stCommonEntityData, objectBuffer);
966 : }
967 :
968 17 : switch( dObjectType )
969 : {
970 0 : case CADObject::BLOCK:
971 0 : return getBlock( dObjectSize, stCommonEntityData, objectBuffer);
972 :
973 1 : case CADObject::ELLIPSE:
974 1 : return getEllipse( dObjectSize, stCommonEntityData, objectBuffer);
975 :
976 0 : case CADObject::MLINE:
977 0 : return getMLine( dObjectSize, stCommonEntityData, objectBuffer);
978 :
979 0 : case CADObject::SOLID:
980 0 : return getSolid( dObjectSize, stCommonEntityData, objectBuffer);
981 :
982 1 : case CADObject::POINT:
983 1 : return getPoint( dObjectSize, stCommonEntityData, objectBuffer);
984 :
985 0 : case CADObject::POLYLINE3D:
986 0 : return getPolyLine3D( dObjectSize, stCommonEntityData, objectBuffer);
987 :
988 0 : case CADObject::RAY:
989 0 : return getRay( dObjectSize, stCommonEntityData, objectBuffer);
990 :
991 0 : case CADObject::XLINE:
992 0 : return getXLine( dObjectSize, stCommonEntityData, objectBuffer);
993 :
994 1 : case CADObject::LINE:
995 1 : return getLine( dObjectSize, stCommonEntityData, objectBuffer);
996 :
997 4 : case CADObject::TEXT:
998 4 : return getText( dObjectSize, stCommonEntityData, objectBuffer);
999 :
1000 0 : case CADObject::VERTEX3D:
1001 0 : return getVertex3D( dObjectSize, stCommonEntityData, objectBuffer);
1002 :
1003 3 : case CADObject::CIRCLE:
1004 3 : return getCircle( dObjectSize, stCommonEntityData, objectBuffer);
1005 :
1006 0 : case CADObject::ENDBLK:
1007 0 : return getEndBlock( dObjectSize, stCommonEntityData, objectBuffer);
1008 :
1009 0 : case CADObject::POLYLINE2D:
1010 0 : return getPolyline2D( dObjectSize, stCommonEntityData, objectBuffer);
1011 :
1012 0 : case CADObject::ATTRIB:
1013 0 : return getAttributes( dObjectSize, stCommonEntityData, objectBuffer);
1014 :
1015 5 : case CADObject::ATTDEF:
1016 5 : return getAttributesDefn( dObjectSize, stCommonEntityData, objectBuffer);
1017 :
1018 0 : case CADObject::LWPOLYLINE:
1019 0 : return getLWPolyLine( dObjectSize, stCommonEntityData, objectBuffer);
1020 :
1021 0 : case CADObject::ARC:
1022 0 : return getArc( dObjectSize, stCommonEntityData, objectBuffer);
1023 :
1024 0 : case CADObject::SPLINE:
1025 0 : return getSpline( dObjectSize, stCommonEntityData, objectBuffer);
1026 :
1027 0 : case CADObject::POLYLINE_PFACE:
1028 0 : return getPolylinePFace( dObjectSize, stCommonEntityData, objectBuffer);
1029 :
1030 0 : case CADObject::IMAGE:
1031 0 : return getImage( dObjectSize, stCommonEntityData, objectBuffer);
1032 :
1033 0 : case CADObject::FACE3D:
1034 0 : return get3DFace( dObjectSize, stCommonEntityData, objectBuffer);
1035 :
1036 0 : case CADObject::VERTEX_MESH:
1037 0 : return getVertexMesh( dObjectSize, stCommonEntityData, objectBuffer);
1038 :
1039 0 : case CADObject::VERTEX_PFACE:
1040 0 : return getVertexPFace( dObjectSize, stCommonEntityData,
1041 0 : objectBuffer);
1042 :
1043 2 : case CADObject::MTEXT:
1044 2 : return getMText( dObjectSize, stCommonEntityData,
1045 2 : objectBuffer);
1046 :
1047 0 : case CADObject::DIMENSION_RADIUS:
1048 : case CADObject::DIMENSION_DIAMETER:
1049 : case CADObject::DIMENSION_ALIGNED:
1050 : case CADObject::DIMENSION_ANG_3PT:
1051 : case CADObject::DIMENSION_ANG_2LN:
1052 : case CADObject::DIMENSION_ORDINATE:
1053 : case CADObject::DIMENSION_LINEAR:
1054 0 : return getDimension( dObjectType, dObjectSize, stCommonEntityData,
1055 0 : objectBuffer);
1056 :
1057 0 : case CADObject::INSERT:
1058 0 : return getInsert( dObjectType, dObjectSize, stCommonEntityData,
1059 0 : objectBuffer);
1060 :
1061 0 : default:
1062 0 : return getEntity( dObjectType, dObjectSize, stCommonEntityData,
1063 0 : objectBuffer);
1064 : }
1065 : }
1066 : else
1067 : {
1068 178 : switch( dObjectType )
1069 : {
1070 120 : case CADObject::DICTIONARY:
1071 120 : return getDictionary( dObjectSize, objectBuffer);
1072 :
1073 10 : case CADObject::LAYER:
1074 10 : return getLayerObject( dObjectSize, objectBuffer);
1075 :
1076 8 : case CADObject::LAYER_CONTROL_OBJ:
1077 8 : return getLayerControl( dObjectSize, objectBuffer);
1078 :
1079 0 : case CADObject::BLOCK_CONTROL_OBJ:
1080 0 : return getBlockControl( dObjectSize, objectBuffer);
1081 :
1082 8 : case CADObject::BLOCK_HEADER:
1083 8 : return getBlockHeader( dObjectSize, objectBuffer);
1084 :
1085 0 : case CADObject::LTYPE_CONTROL_OBJ:
1086 0 : return getLineTypeControl( dObjectSize, objectBuffer);
1087 :
1088 0 : case CADObject::LTYPE1:
1089 0 : return getLineType1( dObjectSize, objectBuffer);
1090 :
1091 0 : case CADObject::IMAGEDEF:
1092 0 : return getImageDef( dObjectSize, objectBuffer);
1093 :
1094 0 : case CADObject::IMAGEDEFREACTOR:
1095 0 : return getImageDefReactor( dObjectSize, objectBuffer);
1096 :
1097 24 : case CADObject::XRECORD:
1098 24 : return getXRecord( dObjectSize, objectBuffer);
1099 : }
1100 : }
1101 :
1102 8 : return nullptr;
1103 : }
1104 :
1105 17 : CADGeometry * DWGFileR2000::GetGeometry( size_t iLayerIndex, long dHandle, long dBlockRefHandle )
1106 : {
1107 17 : CADGeometry * poGeometry = nullptr;
1108 34 : unique_ptr<CADObject> pCADEntityObject( GetObject( dHandle ) );
1109 : CADEntityObject* readObject =
1110 17 : dynamic_cast<CADEntityObject *>( pCADEntityObject.get() );
1111 :
1112 17 : if( !readObject )
1113 : {
1114 0 : return nullptr;
1115 : }
1116 :
1117 17 : switch( readObject->getType() )
1118 : {
1119 0 : case CADObject::ARC:
1120 : {
1121 0 : CADArc * arc = new CADArc();
1122 0 : CADArcObject * cadArc = static_cast<CADArcObject *>(
1123 : readObject);
1124 :
1125 0 : arc->setPosition( cadArc->vertPosition );
1126 0 : arc->setExtrusion( cadArc->vectExtrusion );
1127 0 : arc->setRadius( cadArc->dfRadius );
1128 0 : arc->setThickness( cadArc->dfThickness );
1129 0 : arc->setStartingAngle( cadArc->dfStartAngle );
1130 0 : arc->setEndingAngle( cadArc->dfEndAngle );
1131 :
1132 0 : poGeometry = arc;
1133 0 : break;
1134 : }
1135 :
1136 1 : case CADObject::POINT:
1137 : {
1138 1 : CADPoint3D * point = new CADPoint3D();
1139 1 : CADPointObject * cadPoint = static_cast<CADPointObject *>(
1140 : readObject);
1141 :
1142 1 : point->setPosition( cadPoint->vertPosition );
1143 1 : point->setExtrusion( cadPoint->vectExtrusion );
1144 1 : point->setXAxisAng( cadPoint->dfXAxisAng );
1145 1 : point->setThickness( cadPoint->dfThickness );
1146 :
1147 1 : poGeometry = point;
1148 1 : break;
1149 : }
1150 :
1151 0 : case CADObject::POLYLINE3D:
1152 : {
1153 0 : CADPolyline3D * polyline = new CADPolyline3D();
1154 0 : CADPolyline3DObject * cadPolyline3D = static_cast<CADPolyline3DObject *>(
1155 : readObject);
1156 :
1157 : // TODO: code can be much simplified if CADHandle will be used.
1158 : // to do so, == and ++ operators should be implemented.
1159 0 : unique_ptr<CADVertex3DObject> vertex;
1160 0 : long currentVertexH = cadPolyline3D->hVertices[0].getAsLong();
1161 0 : while( currentVertexH != 0 )
1162 : {
1163 0 : CADObject *poCADVertexObject = GetObject( currentVertexH );
1164 0 : vertex.reset( dynamic_cast<CADVertex3DObject *>( poCADVertexObject ) );
1165 :
1166 0 : if( !vertex )
1167 : {
1168 0 : delete poCADVertexObject;
1169 0 : break;
1170 : }
1171 :
1172 0 : currentVertexH = vertex->stCed.hObjectHandle.getAsLong();
1173 0 : polyline->addVertex( vertex->vertPosition );
1174 0 : if( vertex->stCed.bNoLinks == true )
1175 : {
1176 0 : ++currentVertexH;
1177 : }
1178 : else
1179 : {
1180 0 : currentVertexH = vertex->stChed.hNextEntity.getAsLong(
1181 0 : vertex->stCed.hObjectHandle );
1182 : }
1183 :
1184 : // Last vertex is reached. Read it and break reading.
1185 0 : if( currentVertexH == cadPolyline3D->hVertices[1].getAsLong() )
1186 : {
1187 0 : CADObject *poCADVertex3DObject = GetObject( currentVertexH );
1188 0 : vertex.reset( dynamic_cast<CADVertex3DObject *>(
1189 0 : poCADVertex3DObject) );
1190 0 : if( vertex)
1191 : {
1192 0 : polyline->addVertex( vertex->vertPosition );
1193 : }
1194 : else
1195 : {
1196 0 : delete poCADVertex3DObject;
1197 : }
1198 0 : break;
1199 : }
1200 : }
1201 :
1202 0 : poGeometry = polyline;
1203 0 : break;
1204 : }
1205 :
1206 0 : case CADObject::LWPOLYLINE:
1207 : {
1208 0 : CADLWPolyline * lwPolyline = new CADLWPolyline();
1209 0 : CADLWPolylineObject * cadlwPolyline = static_cast<CADLWPolylineObject *>(
1210 : readObject);
1211 :
1212 0 : lwPolyline->setBulges( cadlwPolyline->adfBulges );
1213 0 : lwPolyline->setClosed( cadlwPolyline->bClosed );
1214 0 : lwPolyline->setConstWidth( cadlwPolyline->dfConstWidth );
1215 0 : lwPolyline->setElevation( cadlwPolyline->dfElevation );
1216 0 : for( const CADVector& vertex : cadlwPolyline->avertVertices )
1217 0 : lwPolyline->addVertex( vertex );
1218 0 : lwPolyline->setVectExtrusion( cadlwPolyline->vectExtrusion );
1219 0 : lwPolyline->setWidths( cadlwPolyline->astWidths );
1220 :
1221 0 : poGeometry = lwPolyline;
1222 0 : break;
1223 : }
1224 :
1225 3 : case CADObject::CIRCLE:
1226 : {
1227 3 : CADCircle * circle = new CADCircle();
1228 3 : CADCircleObject * cadCircle = static_cast<CADCircleObject *>(
1229 : readObject);
1230 :
1231 3 : circle->setPosition( cadCircle->vertPosition );
1232 3 : circle->setExtrusion( cadCircle->vectExtrusion );
1233 3 : circle->setRadius( cadCircle->dfRadius );
1234 3 : circle->setThickness( cadCircle->dfThickness );
1235 :
1236 3 : poGeometry = circle;
1237 3 : break;
1238 : }
1239 :
1240 0 : case CADObject::ATTRIB:
1241 : {
1242 0 : CADAttrib * attrib = new CADAttrib();
1243 0 : CADAttribObject * cadAttrib = static_cast<CADAttribObject *>(
1244 : readObject );
1245 :
1246 0 : attrib->setPosition( cadAttrib->vertInsetionPoint );
1247 0 : attrib->setExtrusion( cadAttrib->vectExtrusion );
1248 0 : attrib->setRotationAngle( cadAttrib->dfRotationAng );
1249 0 : attrib->setAlignmentPoint( cadAttrib->vertAlignmentPoint );
1250 0 : attrib->setElevation( cadAttrib->dfElevation );
1251 0 : attrib->setHeight( cadAttrib->dfHeight );
1252 0 : attrib->setObliqueAngle( cadAttrib->dfObliqueAng );
1253 0 : attrib->setPositionLocked( cadAttrib->bLockPosition );
1254 0 : attrib->setTag( cadAttrib->sTag );
1255 0 : attrib->setTextValue( cadAttrib->sTextValue );
1256 0 : attrib->setThickness( cadAttrib->dfThickness );
1257 :
1258 0 : poGeometry = attrib;
1259 0 : break;
1260 : }
1261 :
1262 5 : case CADObject::ATTDEF:
1263 : {
1264 5 : CADAttdef * attdef = new CADAttdef();
1265 5 : CADAttdefObject * cadAttrib = static_cast<CADAttdefObject*>(
1266 : readObject );
1267 :
1268 5 : attdef->setPosition( cadAttrib->vertInsetionPoint );
1269 5 : attdef->setExtrusion( cadAttrib->vectExtrusion );
1270 5 : attdef->setRotationAngle( cadAttrib->dfRotationAng );
1271 5 : attdef->setAlignmentPoint( cadAttrib->vertAlignmentPoint );
1272 5 : attdef->setElevation( cadAttrib->dfElevation );
1273 5 : attdef->setHeight( cadAttrib->dfHeight );
1274 5 : attdef->setObliqueAngle( cadAttrib->dfObliqueAng );
1275 5 : attdef->setPositionLocked( cadAttrib->bLockPosition );
1276 5 : attdef->setTag( cadAttrib->sTag );
1277 5 : attdef->setTextValue( cadAttrib->sTextValue );
1278 5 : attdef->setThickness( cadAttrib->dfThickness );
1279 5 : attdef->setPrompt( cadAttrib->sPrompt );
1280 :
1281 5 : poGeometry = attdef;
1282 5 : break;
1283 : }
1284 :
1285 1 : case CADObject::ELLIPSE:
1286 : {
1287 1 : CADEllipse * ellipse = new CADEllipse();
1288 1 : CADEllipseObject * cadEllipse = static_cast<CADEllipseObject *>(
1289 : readObject);
1290 :
1291 1 : ellipse->setPosition( cadEllipse->vertPosition );
1292 1 : ellipse->setSMAxis( cadEllipse->vectSMAxis );
1293 1 : ellipse->setAxisRatio( cadEllipse->dfAxisRatio );
1294 1 : ellipse->setEndingAngle( cadEllipse->dfEndAngle );
1295 1 : ellipse->setStartingAngle( cadEllipse->dfBegAngle );
1296 :
1297 1 : poGeometry = ellipse;
1298 1 : break;
1299 : }
1300 :
1301 1 : case CADObject::LINE:
1302 : {
1303 1 : CADLineObject * cadLine = static_cast<CADLineObject *>(
1304 : readObject);
1305 :
1306 2 : CADPoint3D ptBeg( cadLine->vertStart, cadLine->dfThickness );
1307 2 : CADPoint3D ptEnd( cadLine->vertEnd, cadLine->dfThickness );
1308 :
1309 1 : CADLine * line = new CADLine( ptBeg, ptEnd );
1310 :
1311 1 : poGeometry = line;
1312 1 : break;
1313 : }
1314 :
1315 0 : case CADObject::RAY:
1316 : {
1317 0 : CADRay * ray = new CADRay();
1318 0 : CADRayObject * cadRay = static_cast<CADRayObject *>(
1319 : readObject);
1320 :
1321 0 : ray->setVectVector( cadRay->vectVector );
1322 0 : ray->setPosition( cadRay->vertPosition );
1323 :
1324 0 : poGeometry = ray;
1325 0 : break;
1326 : }
1327 :
1328 0 : case CADObject::SPLINE:
1329 : {
1330 0 : CADSpline * spline = new CADSpline();
1331 0 : CADSplineObject * cadSpline = static_cast<CADSplineObject *>(
1332 : readObject);
1333 :
1334 0 : spline->setScenario( cadSpline->dScenario );
1335 0 : spline->setDegree( cadSpline->dDegree );
1336 0 : if( spline->getScenario() == 2 )
1337 : {
1338 0 : spline->setFitTolerance( cadSpline->dfFitTol );
1339 : }
1340 0 : else if( spline->getScenario() == 1 )
1341 : {
1342 0 : spline->setRational( cadSpline->bRational );
1343 0 : spline->setClosed( cadSpline->bClosed );
1344 0 : spline->setWeight( cadSpline->bWeight );
1345 : }
1346 0 : for( double weight : cadSpline->adfCtrlPointsWeight )
1347 0 : spline->addControlPointsWeight( weight );
1348 :
1349 0 : for( const CADVector& pt : cadSpline->averFitPoints )
1350 0 : spline->addFitPoint( pt );
1351 :
1352 0 : for( const CADVector& pt : cadSpline->avertCtrlPoints )
1353 0 : spline->addControlPoint( pt );
1354 :
1355 0 : poGeometry = spline;
1356 0 : break;
1357 : }
1358 :
1359 4 : case CADObject::TEXT:
1360 : {
1361 4 : CADText * text = new CADText();
1362 4 : CADTextObject * cadText = static_cast<CADTextObject *>(
1363 : readObject);
1364 :
1365 4 : text->setPosition( cadText->vertInsetionPoint );
1366 4 : text->setTextValue( cadText->sTextValue );
1367 4 : text->setRotationAngle( cadText->dfRotationAng );
1368 4 : text->setObliqueAngle( cadText->dfObliqueAng );
1369 4 : text->setThickness( cadText->dfThickness );
1370 4 : text->setHeight( cadText->dfElevation );
1371 :
1372 4 : poGeometry = text;
1373 4 : break;
1374 : }
1375 :
1376 0 : case CADObject::SOLID:
1377 : {
1378 0 : CADSolid * solid = new CADSolid();
1379 0 : CADSolidObject * cadSolid = static_cast<CADSolidObject *>(
1380 : readObject);
1381 :
1382 0 : solid->setElevation( cadSolid->dfElevation );
1383 0 : solid->setThickness( cadSolid->dfThickness );
1384 0 : for( const CADVector& corner : cadSolid->avertCorners )
1385 0 : solid->addCorner( corner );
1386 0 : solid->setExtrusion( cadSolid->vectExtrusion );
1387 :
1388 0 : poGeometry = solid;
1389 0 : break;
1390 : }
1391 :
1392 0 : case CADObject::IMAGE:
1393 : {
1394 0 : CADImageObject * cadImage = static_cast<CADImageObject *>(
1395 : readObject);
1396 :
1397 0 : CADObject *pCADImageDefObject = GetObject( cadImage->hImageDef.getAsLong() );
1398 : unique_ptr<CADImageDefObject> cadImageDef(
1399 0 : dynamic_cast<CADImageDefObject *>( pCADImageDefObject ) );
1400 :
1401 0 : if(cadImageDef)
1402 : {
1403 0 : CADImage * image = new CADImage();
1404 0 : image->setClippingBoundaryType( cadImage->dClipBoundaryType );
1405 0 : image->setFilePath( cadImageDef->sFilePath );
1406 0 : image->setVertInsertionPoint( cadImage->vertInsertion );
1407 0 : CADVector imageSize( cadImage->dfSizeX, cadImage->dfSizeY );
1408 0 : image->setImageSize( imageSize );
1409 0 : CADVector imageSizeInPx( cadImageDef->dfXImageSizeInPx, cadImageDef->dfYImageSizeInPx );
1410 0 : image->setImageSizeInPx( imageSizeInPx );
1411 0 : CADVector pixelSizeInACADUnits( cadImageDef->dfXPixelSize, cadImageDef->dfYPixelSize );
1412 0 : image->setPixelSizeInACADUnits( pixelSizeInACADUnits );
1413 0 : if( CADImage::IsValidResolutionUnit( cadImageDef->dResUnits ) )
1414 : {
1415 0 : image->setResolutionUnits(
1416 0 : static_cast<CADImage::ResolutionUnit>( cadImageDef->dResUnits ) );
1417 : }
1418 0 : bool bTransparency = (cadImage->dDisplayProps & 0x08) != 0;
1419 0 : image->setOptions( bTransparency,
1420 0 : cadImage->bClipping,
1421 0 : cadImage->dBrightness,
1422 0 : cadImage->dContrast );
1423 0 : for( const CADVector& clipPt : cadImage->avertClippingPolygonVertices )
1424 : {
1425 0 : image->addClippingPoint( clipPt );
1426 : }
1427 :
1428 0 : poGeometry = image;
1429 : }
1430 : else
1431 : {
1432 0 : delete pCADImageDefObject;
1433 : }
1434 0 : break;
1435 : }
1436 :
1437 0 : case CADObject::MLINE:
1438 : {
1439 0 : CADMLine * mline = new CADMLine();
1440 0 : CADMLineObject * cadmLine = static_cast<CADMLineObject *>(
1441 : readObject);
1442 :
1443 0 : mline->setScale( cadmLine->dfScale );
1444 0 : mline->setOpened( cadmLine->dOpenClosed == 1 ? true : false );
1445 0 : for( const CADMLineVertex& vertex : cadmLine->avertVertices )
1446 0 : mline->addVertex( vertex.vertPosition );
1447 :
1448 0 : poGeometry = mline;
1449 0 : break;
1450 : }
1451 :
1452 2 : case CADObject::MTEXT:
1453 : {
1454 2 : CADMText * mtext = new CADMText();
1455 2 : CADMTextObject * cadmText = static_cast<CADMTextObject *>(
1456 : readObject);
1457 :
1458 2 : mtext->setTextValue( cadmText->sTextValue );
1459 2 : mtext->setXAxisAng( cadmText->vectXAxisDir.getX() ); //TODO: is this needed?
1460 :
1461 2 : mtext->setPosition( cadmText->vertInsertionPoint );
1462 2 : mtext->setExtrusion( cadmText->vectExtrusion );
1463 :
1464 2 : mtext->setHeight( cadmText->dfTextHeight );
1465 2 : mtext->setRectWidth( cadmText->dfRectWidth );
1466 2 : mtext->setExtents( cadmText->dfExtents );
1467 2 : mtext->setExtentsWidth( cadmText->dfExtentsWidth );
1468 :
1469 2 : poGeometry = mtext;
1470 2 : break;
1471 : }
1472 :
1473 0 : case CADObject::POLYLINE_PFACE:
1474 : {
1475 0 : CADPolylinePFace * polyline = new CADPolylinePFace();
1476 0 : CADPolylinePFaceObject * cadpolyPface = static_cast<CADPolylinePFaceObject *>(
1477 : readObject);
1478 :
1479 : // TODO: code can be much simplified if CADHandle will be used.
1480 : // to do so, == and ++ operators should be implemented.
1481 0 : unique_ptr<CADVertexPFaceObject> vertex;
1482 0 : auto dCurrentEntHandle = cadpolyPface->hVertices[0].getAsLong();
1483 0 : auto dLastEntHandle = cadpolyPface->hVertices[1].getAsLong();
1484 : while( true )
1485 : {
1486 0 : CADObject *pCADVertexPFaceObject = GetObject( dCurrentEntHandle );
1487 0 : vertex.reset( dynamic_cast<CADVertexPFaceObject *>(
1488 0 : pCADVertexPFaceObject ) );
1489 : /* TODO: this check is excessive, but if something goes wrong way -
1490 : * some part of geometries will be parsed. */
1491 0 : if( !vertex )
1492 : {
1493 0 : delete pCADVertexPFaceObject;
1494 0 : break;
1495 : }
1496 :
1497 0 : polyline->addVertex( vertex->vertPosition );
1498 :
1499 : /* FIXME: somehow one more vertex which isnot presented is read.
1500 : * so, checking the number of added vertices */
1501 : /*TODO: is this needed - check on real data
1502 : if ( polyline->hVertices.size() == cadpolyPface->nNumVertices )
1503 : {
1504 : delete( vertex );
1505 : break;
1506 : }*/
1507 :
1508 0 : if( vertex->stCed.bNoLinks )
1509 0 : ++dCurrentEntHandle;
1510 : else
1511 0 : dCurrentEntHandle = vertex->stChed.hNextEntity.getAsLong( vertex->stCed.hObjectHandle );
1512 :
1513 0 : if( dCurrentEntHandle == dLastEntHandle )
1514 : {
1515 0 : CADObject *pCADVertexPFaceObjectV = GetObject( dCurrentEntHandle );
1516 0 : vertex.reset( dynamic_cast<CADVertexPFaceObject *>(
1517 0 : pCADVertexPFaceObjectV) );
1518 0 : if(vertex)
1519 : {
1520 0 : polyline->addVertex( vertex->vertPosition );
1521 : }
1522 : else
1523 : {
1524 0 : delete pCADVertexPFaceObjectV;
1525 : }
1526 0 : break;
1527 : }
1528 0 : }
1529 :
1530 0 : poGeometry = polyline;
1531 0 : break;
1532 : }
1533 :
1534 0 : case CADObject::XLINE:
1535 : {
1536 0 : CADXLine * xline = new CADXLine();
1537 0 : CADXLineObject * cadxLine = static_cast<CADXLineObject *>(
1538 : readObject);
1539 :
1540 0 : xline->setVectVector( cadxLine->vectVector );
1541 0 : xline->setPosition( cadxLine->vertPosition );
1542 :
1543 0 : poGeometry = xline;
1544 0 : break;
1545 : }
1546 :
1547 0 : case CADObject::FACE3D:
1548 : {
1549 0 : CADFace3D * face = new CADFace3D();
1550 0 : CAD3DFaceObject * cad3DFace = static_cast<CAD3DFaceObject *>(
1551 : readObject);
1552 :
1553 0 : for( const CADVector& corner : cad3DFace->avertCorners )
1554 0 : face->addCorner( corner );
1555 0 : face->setInvisFlags( cad3DFace->dInvisFlags );
1556 :
1557 0 : poGeometry = face;
1558 0 : break;
1559 : }
1560 :
1561 0 : case CADObject::POLYLINE_MESH:
1562 : case CADObject::VERTEX_MESH:
1563 : case CADObject::VERTEX_PFACE_FACE:
1564 : default:
1565 0 : std::cerr << "Asked geometry has unsupported type.\n";
1566 0 : poGeometry = new CADUnknown();
1567 0 : break;
1568 : }
1569 :
1570 17 : if( poGeometry == nullptr )
1571 0 : return nullptr;
1572 :
1573 : // Applying color
1574 17 : if( readObject->stCed.nCMColor == 256 ) // BYLAYER CASE
1575 : {
1576 17 : CADLayer& oCurrentLayer = this->GetLayer( iLayerIndex );
1577 17 : poGeometry->setColor( getCADACIColor( oCurrentLayer.getColor() ) );
1578 : }
1579 0 : else if( readObject->stCed.nCMColor <= 255 &&
1580 0 : readObject->stCed.nCMColor >= 0 ) // Excessive check until BYBLOCK case will not be implemented
1581 : {
1582 0 : poGeometry->setColor( getCADACIColor( readObject->stCed.nCMColor ) );
1583 : }
1584 :
1585 : // Applying EED
1586 : // Casting object's EED to a vector of strings
1587 17 : vector<string> asEED;
1588 24 : for( auto citer = readObject->stCed.aEED.cbegin();
1589 31 : citer != readObject->stCed.aEED.cend(); ++citer )
1590 : {
1591 14 : string sEED = "";
1592 : // Detect the type of EED entity
1593 7 : switch( citer->acData[0] )
1594 : {
1595 2 : case 0: // String
1596 : {
1597 2 : if( citer->acData.size() > 1 )
1598 : {
1599 2 : unsigned char nStrSize = citer->acData[1];
1600 : // +2 = skip CodePage, no idea how to use it anyway
1601 :
1602 2 : if(nStrSize > 0)
1603 : {
1604 114 : for( size_t i = 0; i < nStrSize &&
1605 56 : i + 4 < citer->acData.size(); ++i )
1606 : {
1607 56 : sEED += citer->acData[i + 4];
1608 : }
1609 : }
1610 : }
1611 2 : break;
1612 : }
1613 0 : case 1: // Invalid
1614 : {
1615 0 : DebugMsg( "Error: EED obj type is 1, error in R2000::getGeometry()" );
1616 0 : break;
1617 : }
1618 0 : case 2: // { or }
1619 : {
1620 0 : if( citer->acData.size() > 1 )
1621 : {
1622 0 : sEED += citer->acData[1] == 0 ? '{' : '}';
1623 : }
1624 0 : break;
1625 : }
1626 0 : case 3: // Layer table ref
1627 : {
1628 : // FIXME: get CADHandle and return getAsLong() result.
1629 0 : sEED += "Layer table ref (handle):";
1630 0 : for( size_t i = 0; i < 8 && i + 1 < citer->acData.size(); ++i )
1631 : {
1632 0 : sEED += citer->acData[i + 1];
1633 : }
1634 0 : break;
1635 : }
1636 0 : case 4: // Binary chunk
1637 : {
1638 0 : if( citer->acData.size() > 1 )
1639 : {
1640 0 : unsigned char nChunkSize = citer->acData[1];
1641 0 : sEED += "Binary chunk (chars):";
1642 0 : if(nChunkSize > 0)
1643 : {
1644 0 : for( size_t i = 0; i < nChunkSize &&
1645 0 : i + 2 < citer->acData.size(); ++i )
1646 : {
1647 0 : sEED += citer->acData[i + 2];
1648 : }
1649 : }
1650 : else
1651 : {
1652 0 : sEED += "?";
1653 : }
1654 : }
1655 0 : break;
1656 : }
1657 0 : case 5: // Entity handle ref
1658 : {
1659 : // FIXME: Get CADHandle and return getAsLong() result.
1660 0 : sEED += "Entity handle ref (handle):";
1661 0 : for( size_t i = 0; i < 8 && i + 1 < citer->acData.size(); ++i )
1662 : {
1663 0 : sEED += citer->acData[i + 1];
1664 : }
1665 0 : break;
1666 : }
1667 0 : case 10:
1668 : case 11:
1669 : case 12:
1670 : case 13:
1671 : {
1672 0 : sEED += "Point: {";
1673 0 : double dfX = 0, dfY = 0, dfZ = 0;
1674 0 : if(citer->acData.size() > 24)
1675 : {
1676 0 : memcpy( & dfX, citer->acData.data() + 1, 8 );
1677 0 : memcpy( & dfY, citer->acData.data() + 9, 8 );
1678 0 : memcpy( & dfZ, citer->acData.data() + 17, 8 );
1679 : }
1680 0 : sEED += std::to_string( dfX );
1681 0 : sEED += ';';
1682 0 : sEED += std::to_string( dfY );
1683 0 : sEED += ';';
1684 0 : sEED += std::to_string( dfZ );
1685 0 : sEED += '}';
1686 0 : break;
1687 : }
1688 0 : case 40:
1689 : case 41:
1690 : case 42:
1691 : {
1692 0 : sEED += "Double:";
1693 0 : double dfVal = 0;
1694 0 : if(citer->acData.size() > 8)
1695 0 : memcpy( & dfVal, citer->acData.data() + 1, 8 );
1696 0 : sEED += std::to_string( dfVal );
1697 0 : break;
1698 : }
1699 5 : case 70:
1700 : {
1701 5 : sEED += "Short:";
1702 5 : int16_t dVal = 0;
1703 5 : if(citer->acData.size() > 2)
1704 5 : memcpy( & dVal, citer->acData.data() + 1, 2 );
1705 5 : sEED += std::to_string( dVal );
1706 5 : break;
1707 : }
1708 0 : case 71:
1709 : {
1710 0 : sEED += "Long Int:";
1711 0 : int32_t dVal = 0;
1712 0 : if(citer->acData.size() > 4)
1713 0 : memcpy( & dVal, citer->acData.data() + 1, 4 );
1714 0 : sEED += std::to_string( dVal );
1715 0 : break;
1716 : }
1717 0 : default:
1718 : {
1719 0 : DebugMsg( "Error in parsing geometry EED: undefined typecode: %d",
1720 0 : static_cast<int>(citer->acData[0]) );
1721 : }
1722 : }
1723 7 : asEED.emplace_back( sEED );
1724 : }
1725 :
1726 : // Getting block reference attributes.
1727 17 : if( dBlockRefHandle != 0 )
1728 : {
1729 0 : vector<CADAttrib> blockRefAttributes;
1730 0 : CADObject *pCADInsertObject = GetObject( dBlockRefHandle );
1731 : unique_ptr<CADInsertObject> spoBlockRef(
1732 0 : dynamic_cast<CADInsertObject *>( pCADInsertObject ) );
1733 :
1734 0 : if( spoBlockRef )
1735 : {
1736 0 : if( !spoBlockRef->hAttribs.empty() )
1737 : {
1738 0 : long dCurrentEntHandle = spoBlockRef->hAttribs[0].getAsLong();
1739 0 : long dLastEntHandle = spoBlockRef->hAttribs[0].getAsLong();
1740 :
1741 0 : while( spoBlockRef->bHasAttribs )
1742 : {
1743 0 : CADObject *pCADAttDefObj = GetObject( dCurrentEntHandle, true );
1744 :
1745 : CADEntityObject * attDefObj =
1746 0 : dynamic_cast<CADEntityObject *>( pCADAttDefObj );
1747 :
1748 0 : if( dCurrentEntHandle == dLastEntHandle )
1749 : {
1750 0 : if( attDefObj == nullptr )
1751 : {
1752 0 : delete pCADAttDefObj;
1753 0 : break;
1754 : }
1755 :
1756 0 : auto geometry = GetGeometry( iLayerIndex, dCurrentEntHandle );
1757 0 : CADAttrib * attrib = dynamic_cast<CADAttrib *>(geometry);
1758 0 : if( attrib )
1759 : {
1760 0 : blockRefAttributes.push_back( CADAttrib( * attrib ) );
1761 : }
1762 0 : delete geometry;
1763 0 : delete attDefObj;
1764 0 : break;
1765 : }
1766 :
1767 0 : if( attDefObj != nullptr )
1768 : {
1769 0 : if( attDefObj->stCed.bNoLinks )
1770 0 : ++dCurrentEntHandle;
1771 : else
1772 0 : dCurrentEntHandle = attDefObj->stChed.hNextEntity.getAsLong( attDefObj->stCed.hObjectHandle );
1773 :
1774 0 : auto geometry = GetGeometry( iLayerIndex, dCurrentEntHandle );
1775 0 : CADAttrib * attrib = dynamic_cast<CADAttrib *>(geometry);
1776 0 : if( attrib )
1777 : {
1778 0 : blockRefAttributes.push_back( CADAttrib( * attrib ) );
1779 : }
1780 0 : delete geometry;
1781 0 : delete attDefObj;
1782 : }
1783 : else
1784 : {
1785 0 : delete pCADAttDefObj;
1786 : }
1787 : }
1788 0 : poGeometry->setBlockAttributes( blockRefAttributes );
1789 : }
1790 : }
1791 : else
1792 : {
1793 0 : delete pCADInsertObject;
1794 : }
1795 : }
1796 :
1797 17 : poGeometry->setEED( asEED );
1798 17 : return poGeometry;
1799 : }
1800 :
1801 0 : CADBlockObject * DWGFileR2000::getBlock(unsigned int dObjectSize,
1802 : const CADCommonED& stCommonEntityData,
1803 : CADBuffer &buffer)
1804 : {
1805 0 : CADBlockObject * pBlock = new CADBlockObject();
1806 :
1807 0 : pBlock->setSize( dObjectSize );
1808 0 : pBlock->stCed = stCommonEntityData;
1809 :
1810 0 : pBlock->sBlockName = buffer.ReadTV();
1811 :
1812 0 : fillCommonEntityHandleData( pBlock, buffer);
1813 :
1814 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
1815 0 : pBlock->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "BLOCK" ) );
1816 :
1817 0 : return pBlock;
1818 : }
1819 :
1820 1 : CADEllipseObject * DWGFileR2000::getEllipse(unsigned int dObjectSize,
1821 : const CADCommonED& stCommonEntityData,
1822 : CADBuffer& buffer)
1823 : {
1824 1 : CADEllipseObject * ellipse = new CADEllipseObject();
1825 :
1826 1 : ellipse->setSize( dObjectSize );
1827 1 : ellipse->stCed = stCommonEntityData;
1828 :
1829 1 : CADVector vertPosition = buffer.ReadVector();
1830 :
1831 1 : ellipse->vertPosition = vertPosition;
1832 :
1833 1 : CADVector vectSMAxis = buffer.ReadVector();
1834 :
1835 1 : ellipse->vectSMAxis = vectSMAxis;
1836 :
1837 1 : CADVector vectExtrusion = buffer.ReadVector();
1838 :
1839 1 : ellipse->vectExtrusion = vectExtrusion;
1840 :
1841 1 : ellipse->dfAxisRatio = buffer.ReadBITDOUBLE();
1842 1 : ellipse->dfBegAngle = buffer.ReadBITDOUBLE();
1843 1 : ellipse->dfEndAngle = buffer.ReadBITDOUBLE();
1844 :
1845 1 : fillCommonEntityHandleData(ellipse, buffer);
1846 :
1847 1 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
1848 1 : ellipse->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ELLIPSE" ) );
1849 :
1850 1 : return ellipse;
1851 : }
1852 :
1853 0 : CADSolidObject * DWGFileR2000::getSolid(unsigned int dObjectSize,
1854 : const CADCommonED& stCommonEntityData,
1855 : CADBuffer &buffer)
1856 : {
1857 0 : CADSolidObject * solid = new CADSolidObject();
1858 :
1859 0 : solid->setSize( dObjectSize );
1860 0 : solid->stCed = stCommonEntityData;
1861 :
1862 0 : solid->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
1863 :
1864 0 : solid->dfElevation = buffer.ReadBITDOUBLE();
1865 :
1866 0 : CADVector oCorner;
1867 0 : for( size_t i = 0; i < 4; ++i )
1868 : {
1869 0 : oCorner.setX( buffer.ReadRAWDOUBLE() );
1870 0 : oCorner.setY( buffer.ReadRAWDOUBLE() );
1871 0 : solid->avertCorners.push_back( oCorner );
1872 : }
1873 :
1874 0 : if( buffer.ReadBIT() )
1875 : {
1876 0 : solid->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
1877 : }
1878 : else
1879 : {
1880 0 : CADVector vectExtrusion = buffer.ReadVector();
1881 0 : solid->vectExtrusion = vectExtrusion;
1882 : }
1883 :
1884 :
1885 0 : fillCommonEntityHandleData( solid, buffer);
1886 :
1887 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
1888 0 : solid->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "SOLID" ) );
1889 :
1890 0 : return solid;
1891 : }
1892 :
1893 1 : CADPointObject * DWGFileR2000::getPoint(unsigned int dObjectSize,
1894 : const CADCommonED& stCommonEntityData,
1895 : CADBuffer& buffer)
1896 : {
1897 1 : CADPointObject * point = new CADPointObject();
1898 :
1899 1 : point->setSize( dObjectSize );
1900 1 : point->stCed = stCommonEntityData;
1901 :
1902 1 : CADVector vertPosition = buffer.ReadVector();
1903 :
1904 1 : point->vertPosition = vertPosition;
1905 :
1906 1 : point->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
1907 :
1908 1 : if( buffer.ReadBIT() )
1909 : {
1910 1 : point->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
1911 : }
1912 : else
1913 : {
1914 0 : CADVector vectExtrusion = buffer.ReadVector();
1915 0 : point->vectExtrusion = vectExtrusion;
1916 : }
1917 :
1918 1 : point->dfXAxisAng = buffer.ReadBITDOUBLE();
1919 :
1920 1 : fillCommonEntityHandleData( point, buffer);
1921 :
1922 1 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
1923 1 : point->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POINT" ) );
1924 :
1925 1 : return point;
1926 : }
1927 :
1928 0 : CADPolyline3DObject * DWGFileR2000::getPolyLine3D(unsigned int dObjectSize,
1929 : const CADCommonED& stCommonEntityData,
1930 : CADBuffer &buffer)
1931 : {
1932 0 : CADPolyline3DObject * polyline = new CADPolyline3DObject();
1933 :
1934 0 : polyline->setSize( dObjectSize );
1935 0 : polyline->stCed = stCommonEntityData;
1936 :
1937 0 : polyline->SplinedFlags = buffer.ReadCHAR();
1938 0 : polyline->ClosedFlags = buffer.ReadCHAR();
1939 :
1940 0 : fillCommonEntityHandleData( polyline, buffer );
1941 :
1942 0 : polyline->hVertices.push_back( buffer.ReadHANDLE() ); // 1st vertex
1943 0 : polyline->hVertices.push_back( buffer.ReadHANDLE() ); // last vertex
1944 :
1945 0 : polyline->hSeqend = buffer.ReadHANDLE();
1946 :
1947 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
1948 0 : polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POLYLINE" ) );
1949 :
1950 0 : return polyline;
1951 : }
1952 :
1953 0 : CADRayObject * DWGFileR2000::getRay(unsigned int dObjectSize,
1954 : const CADCommonED& stCommonEntityData,
1955 : CADBuffer &buffer)
1956 : {
1957 0 : CADRayObject * ray = new CADRayObject();
1958 :
1959 0 : ray->setSize( dObjectSize );
1960 0 : ray->stCed = stCommonEntityData;
1961 :
1962 0 : CADVector vertPosition = buffer.ReadVector();
1963 :
1964 0 : ray->vertPosition = vertPosition;
1965 :
1966 0 : CADVector vectVector = buffer.ReadVector();
1967 0 : ray->vectVector = vectVector;
1968 :
1969 0 : fillCommonEntityHandleData( ray, buffer);
1970 :
1971 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
1972 0 : ray->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "RAY" ) );
1973 :
1974 0 : return ray;
1975 : }
1976 :
1977 0 : CADXLineObject * DWGFileR2000::getXLine(unsigned int dObjectSize,
1978 : const CADCommonED& stCommonEntityData,
1979 : CADBuffer &buffer)
1980 : {
1981 0 : CADXLineObject * xline = new CADXLineObject();
1982 :
1983 0 : xline->setSize( dObjectSize );
1984 0 : xline->stCed = stCommonEntityData;
1985 :
1986 0 : CADVector vertPosition = buffer.ReadVector();
1987 :
1988 0 : xline->vertPosition = vertPosition;
1989 :
1990 0 : CADVector vectVector = buffer.ReadVector();
1991 0 : xline->vectVector = vectVector;
1992 :
1993 0 : fillCommonEntityHandleData( xline, buffer);
1994 :
1995 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
1996 0 : xline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "XLINE" ) );
1997 :
1998 0 : return xline;
1999 : }
2000 :
2001 1 : CADLineObject * DWGFileR2000::getLine(unsigned int dObjectSize,
2002 : const CADCommonED& stCommonEntityData,
2003 : CADBuffer &buffer)
2004 : {
2005 1 : CADLineObject * line = new CADLineObject();
2006 :
2007 1 : line->setSize( dObjectSize );
2008 1 : line->stCed = stCommonEntityData;
2009 :
2010 1 : bool bZsAreZeros = buffer.ReadBIT();
2011 :
2012 1 : CADVector vertStart, vertEnd;
2013 1 : vertStart.setX( buffer.ReadRAWDOUBLE() );
2014 1 : vertEnd.setX( buffer.ReadBITDOUBLEWD(vertStart.getX() ) );
2015 1 : vertStart.setY( buffer.ReadRAWDOUBLE() );
2016 1 : vertEnd.setY( buffer.ReadBITDOUBLEWD(vertStart.getY() ) );
2017 :
2018 1 : if( !bZsAreZeros )
2019 : {
2020 0 : vertStart.setZ( buffer.ReadBITDOUBLE() );
2021 0 : vertEnd.setZ( buffer.ReadBITDOUBLEWD(vertStart.getZ() ) );
2022 : }
2023 :
2024 1 : line->vertStart = vertStart;
2025 1 : line->vertEnd = vertEnd;
2026 :
2027 1 : line->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
2028 :
2029 1 : if( buffer.ReadBIT() )
2030 : {
2031 1 : line->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
2032 : } else
2033 : {
2034 0 : CADVector vectExtrusion = buffer.ReadVector();
2035 0 : line->vectExtrusion = vectExtrusion;
2036 : }
2037 :
2038 1 : fillCommonEntityHandleData( line, buffer);
2039 :
2040 1 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2041 1 : line->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LINE" ) );
2042 1 : return line;
2043 : }
2044 :
2045 4 : CADTextObject * DWGFileR2000::getText(unsigned int dObjectSize,
2046 : const CADCommonED& stCommonEntityData,
2047 : CADBuffer &buffer)
2048 : {
2049 4 : CADTextObject * text = new CADTextObject();
2050 :
2051 4 : text->setSize( dObjectSize );
2052 4 : text->stCed = stCommonEntityData;
2053 :
2054 4 : text->DataFlags = buffer.ReadCHAR();
2055 :
2056 4 : if( !( text->DataFlags & 0x01 ) )
2057 : {
2058 0 : text->dfElevation = buffer.ReadRAWDOUBLE();
2059 : }
2060 :
2061 4 : CADVector vertInsetionPoint = buffer.ReadRAWVector();
2062 :
2063 4 : text->vertInsetionPoint = vertInsetionPoint;
2064 :
2065 4 : if( !( text->DataFlags & 0x02 ) )
2066 : {
2067 : double x, y;
2068 0 : x = buffer.ReadBITDOUBLEWD(vertInsetionPoint.getX() );
2069 0 : y = buffer.ReadBITDOUBLEWD(vertInsetionPoint.getY() );
2070 0 : CADVector vertAlignmentPoint( x, y );
2071 0 : text->vertAlignmentPoint = vertAlignmentPoint;
2072 : }
2073 :
2074 4 : if( buffer.ReadBIT() )
2075 : {
2076 4 : text->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
2077 : }
2078 : else
2079 : {
2080 0 : CADVector vectExtrusion = buffer.ReadVector();
2081 0 : text->vectExtrusion = vectExtrusion;
2082 : }
2083 :
2084 4 : text->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
2085 :
2086 4 : if( !( text->DataFlags & 0x04 ) )
2087 0 : text->dfObliqueAng = buffer.ReadRAWDOUBLE();
2088 4 : if( !( text->DataFlags & 0x08 ) )
2089 0 : text->dfRotationAng = buffer.ReadRAWDOUBLE();
2090 :
2091 4 : text->dfHeight = buffer.ReadRAWDOUBLE();
2092 :
2093 4 : if( !( text->DataFlags & 0x10 ) )
2094 0 : text->dfWidthFactor = buffer.ReadRAWDOUBLE();
2095 :
2096 4 : text->sTextValue = buffer.ReadTV();
2097 :
2098 4 : if( !( text->DataFlags & 0x20 ) )
2099 0 : text->dGeneration = buffer.ReadBITSHORT();
2100 4 : if( !( text->DataFlags & 0x40 ) )
2101 0 : text->dHorizAlign = buffer.ReadBITSHORT();
2102 4 : if( !( text->DataFlags & 0x80 ) )
2103 0 : text->dVertAlign = buffer.ReadBITSHORT();
2104 :
2105 4 : fillCommonEntityHandleData( text, buffer);
2106 :
2107 4 : text->hStyle = buffer.ReadHANDLE();
2108 :
2109 4 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2110 4 : text->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "TEXT" ) );
2111 :
2112 4 : return text;
2113 : }
2114 :
2115 0 : CADVertex3DObject * DWGFileR2000::getVertex3D(unsigned int dObjectSize,
2116 : const CADCommonED& stCommonEntityData,
2117 : CADBuffer &buffer)
2118 : {
2119 0 : CADVertex3DObject * vertex = new CADVertex3DObject();
2120 :
2121 0 : vertex->setSize( dObjectSize );
2122 0 : vertex->stCed = stCommonEntityData;
2123 :
2124 0 : /*unsigned char Flags = */buffer.ReadCHAR();
2125 :
2126 0 : CADVector vertPosition = buffer.ReadVector();
2127 0 : vertex->vertPosition = vertPosition;
2128 :
2129 0 : fillCommonEntityHandleData( vertex, buffer);
2130 :
2131 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2132 0 : vertex->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "VERTEX" ) );
2133 0 : return vertex;
2134 : }
2135 :
2136 3 : CADCircleObject * DWGFileR2000::getCircle(unsigned int dObjectSize,
2137 : const CADCommonED& stCommonEntityData,
2138 : CADBuffer &buffer)
2139 : {
2140 3 : CADCircleObject * circle = new CADCircleObject();
2141 :
2142 3 : circle->setSize( dObjectSize );
2143 3 : circle->stCed = stCommonEntityData;
2144 :
2145 3 : CADVector vertPosition = buffer.ReadVector();
2146 3 : circle->vertPosition = vertPosition;
2147 3 : circle->dfRadius = buffer.ReadBITDOUBLE();
2148 3 : circle->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
2149 :
2150 3 : if( buffer.ReadBIT() )
2151 : {
2152 3 : circle->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
2153 : }
2154 : else
2155 : {
2156 0 : CADVector vectExtrusion = buffer.ReadVector();
2157 0 : circle->vectExtrusion = vectExtrusion;
2158 : }
2159 :
2160 3 : fillCommonEntityHandleData( circle, buffer);
2161 :
2162 3 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2163 3 : circle->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "CIRCLE" ) );
2164 3 : return circle;
2165 : }
2166 :
2167 0 : CADEndblkObject * DWGFileR2000::getEndBlock(unsigned int dObjectSize,
2168 : const CADCommonED& stCommonEntityData,
2169 : CADBuffer &buffer)
2170 : {
2171 0 : CADEndblkObject * endblk = new CADEndblkObject();
2172 :
2173 0 : endblk->setSize( dObjectSize );
2174 0 : endblk->stCed = stCommonEntityData;
2175 :
2176 0 : fillCommonEntityHandleData( endblk, buffer);
2177 :
2178 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2179 0 : endblk->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ENDBLK" ) );
2180 0 : return endblk;
2181 : }
2182 :
2183 0 : CADPolyline2DObject * DWGFileR2000::getPolyline2D(unsigned int dObjectSize,
2184 : const CADCommonED& stCommonEntityData,
2185 : CADBuffer &buffer)
2186 : {
2187 0 : CADPolyline2DObject * polyline = new CADPolyline2DObject();
2188 :
2189 0 : polyline->setSize( dObjectSize );
2190 0 : polyline->stCed = stCommonEntityData;
2191 :
2192 0 : polyline->dFlags = buffer.ReadBITSHORT();
2193 0 : polyline->dCurveNSmoothSurfType = buffer.ReadBITSHORT();
2194 :
2195 0 : polyline->dfStartWidth = buffer.ReadBITDOUBLE();
2196 0 : polyline->dfEndWidth = buffer.ReadBITDOUBLE();
2197 :
2198 0 : polyline->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
2199 :
2200 0 : polyline->dfElevation = buffer.ReadBITDOUBLE();
2201 :
2202 0 : if( buffer.ReadBIT() )
2203 : {
2204 0 : polyline->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
2205 : }
2206 : else
2207 : {
2208 0 : CADVector vectExtrusion = buffer.ReadVector();
2209 0 : polyline->vectExtrusion = vectExtrusion;
2210 : }
2211 :
2212 0 : fillCommonEntityHandleData( polyline, buffer);
2213 :
2214 0 : polyline->hVertices.push_back( buffer.ReadHANDLE() ); // 1st vertex
2215 0 : polyline->hVertices.push_back( buffer.ReadHANDLE() ); // last vertex
2216 :
2217 0 : polyline->hSeqend = buffer.ReadHANDLE();
2218 :
2219 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2220 0 : polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POLYLINE" ) );
2221 0 : return polyline;
2222 : }
2223 :
2224 0 : CADAttribObject * DWGFileR2000::getAttributes(unsigned int dObjectSize,
2225 : const CADCommonED& stCommonEntityData,
2226 : CADBuffer &buffer)
2227 : {
2228 0 : CADAttribObject * attrib = new CADAttribObject();
2229 :
2230 0 : attrib->setSize( dObjectSize );
2231 0 : attrib->stCed = stCommonEntityData;
2232 0 : attrib->DataFlags = buffer.ReadCHAR();
2233 :
2234 0 : if( !( attrib->DataFlags & 0x01 ) )
2235 0 : attrib->dfElevation = buffer.ReadRAWDOUBLE();
2236 :
2237 : double x, y;
2238 :
2239 0 : CADVector vertInsetionPoint = buffer.ReadRAWVector();
2240 0 : attrib->vertInsetionPoint = vertInsetionPoint;
2241 :
2242 0 : if( !( attrib->DataFlags & 0x02 ) )
2243 : {
2244 0 : x = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getX() );
2245 0 : y = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getY() );
2246 0 : CADVector vertAlignmentPoint( x, y );
2247 0 : attrib->vertAlignmentPoint = vertAlignmentPoint;
2248 : }
2249 :
2250 0 : if( buffer.ReadBIT() )
2251 : {
2252 0 : attrib->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
2253 : }
2254 : else
2255 : {
2256 0 : CADVector vectExtrusion = buffer.ReadVector();
2257 0 : attrib->vectExtrusion = vectExtrusion;
2258 : }
2259 :
2260 0 : attrib->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
2261 :
2262 0 : if( !( attrib->DataFlags & 0x04 ) )
2263 0 : attrib->dfObliqueAng = buffer.ReadRAWDOUBLE();
2264 0 : if( !( attrib->DataFlags & 0x08 ) )
2265 0 : attrib->dfRotationAng = buffer.ReadRAWDOUBLE();
2266 0 : attrib->dfHeight = buffer.ReadRAWDOUBLE();
2267 0 : if( !( attrib->DataFlags & 0x10 ) )
2268 0 : attrib->dfWidthFactor = buffer.ReadRAWDOUBLE();
2269 0 : attrib->sTextValue = buffer.ReadTV();
2270 0 : if( !( attrib->DataFlags & 0x20 ) )
2271 0 : attrib->dGeneration = buffer.ReadBITSHORT();
2272 0 : if( !( attrib->DataFlags & 0x40 ) )
2273 0 : attrib->dHorizAlign = buffer.ReadBITSHORT();
2274 0 : if( !( attrib->DataFlags & 0x80 ) )
2275 0 : attrib->dVertAlign = buffer.ReadBITSHORT();
2276 :
2277 0 : attrib->sTag = buffer.ReadTV();
2278 0 : attrib->nFieldLength = buffer.ReadBITSHORT();
2279 0 : attrib->nFlags = buffer.ReadCHAR();
2280 :
2281 0 : fillCommonEntityHandleData( attrib, buffer);
2282 :
2283 0 : attrib->hStyle = buffer.ReadHANDLE();
2284 :
2285 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2286 0 : attrib->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ATTRIB" ) );
2287 0 : return attrib;
2288 : }
2289 :
2290 5 : CADAttdefObject * DWGFileR2000::getAttributesDefn(unsigned int dObjectSize,
2291 : const CADCommonED& stCommonEntityData,
2292 : CADBuffer &buffer)
2293 : {
2294 5 : CADAttdefObject * attdef = new CADAttdefObject();
2295 :
2296 5 : attdef->setSize( dObjectSize );
2297 5 : attdef->stCed = stCommonEntityData;
2298 5 : attdef->DataFlags = buffer.ReadCHAR();
2299 :
2300 5 : if( ( attdef->DataFlags & 0x01 ) == 0 )
2301 0 : attdef->dfElevation = buffer.ReadRAWDOUBLE();
2302 :
2303 5 : CADVector vertInsetionPoint = buffer.ReadRAWVector();
2304 5 : attdef->vertInsetionPoint = vertInsetionPoint;
2305 :
2306 5 : if( ( attdef->DataFlags & 0x02 ) == 0 )
2307 : {
2308 0 : double x = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getX() );
2309 0 : double y = buffer.ReadBITDOUBLEWD( vertInsetionPoint.getY() );
2310 0 : CADVector vertAlignmentPoint( x, y );
2311 0 : attdef->vertAlignmentPoint = vertAlignmentPoint;
2312 : }
2313 :
2314 5 : if( buffer.ReadBIT() )
2315 : {
2316 5 : attdef->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
2317 : }
2318 : else
2319 : {
2320 0 : CADVector vectExtrusion = buffer.ReadVector();
2321 0 : attdef->vectExtrusion = vectExtrusion;
2322 : }
2323 :
2324 5 : attdef->dfThickness = buffer.ReadBIT() ? 0.0f :
2325 0 : buffer.ReadBITDOUBLE();
2326 :
2327 5 : if( ( attdef->DataFlags & 0x04 ) == 0 )
2328 0 : attdef->dfObliqueAng = buffer.ReadRAWDOUBLE();
2329 5 : if( ( attdef->DataFlags & 0x08 ) == 0 )
2330 0 : attdef->dfRotationAng = buffer.ReadRAWDOUBLE();
2331 5 : attdef->dfHeight = buffer.ReadRAWDOUBLE();
2332 5 : if( ( attdef->DataFlags & 0x10 ) == 0 )
2333 0 : attdef->dfWidthFactor = buffer.ReadRAWDOUBLE();
2334 5 : attdef->sTextValue = buffer.ReadTV();
2335 5 : if( ( attdef->DataFlags & 0x20 ) == 0 )
2336 0 : attdef->dGeneration = buffer.ReadBITSHORT();
2337 5 : if( ( attdef->DataFlags & 0x40 ) == 0 )
2338 0 : attdef->dHorizAlign = buffer.ReadBITSHORT();
2339 5 : if( ( attdef->DataFlags & 0x80 ) == 0 )
2340 0 : attdef->dVertAlign = buffer.ReadBITSHORT();
2341 :
2342 5 : attdef->sTag = buffer.ReadTV();
2343 5 : attdef->nFieldLength = buffer.ReadBITSHORT();
2344 5 : attdef->nFlags = buffer.ReadCHAR();
2345 :
2346 5 : attdef->sPrompt = buffer.ReadTV();
2347 :
2348 5 : fillCommonEntityHandleData( attdef, buffer);
2349 :
2350 5 : attdef->hStyle = buffer.ReadHANDLE();
2351 :
2352 5 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2353 5 : attdef->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ATTRDEF" ) );
2354 5 : return attdef;
2355 : }
2356 :
2357 0 : CADLWPolylineObject * DWGFileR2000::getLWPolyLine(unsigned int dObjectSize,
2358 : const CADCommonED& stCommonEntityData,
2359 : CADBuffer &buffer)
2360 : {
2361 0 : CADLWPolylineObject * polyline = new CADLWPolylineObject();
2362 0 : polyline->setSize( dObjectSize );
2363 0 : polyline->stCed = stCommonEntityData;
2364 :
2365 0 : int verticesCount = 0, nBulges = 0, nNumWidths = 0;
2366 0 : short dataFlag = buffer.ReadBITSHORT();
2367 0 : if( dataFlag & 4 )
2368 0 : polyline->dfConstWidth = buffer.ReadBITDOUBLE();
2369 0 : if( dataFlag & 8 )
2370 0 : polyline->dfElevation = buffer.ReadBITDOUBLE();
2371 0 : if( dataFlag & 2 )
2372 0 : polyline->dfThickness = buffer.ReadBITDOUBLE();
2373 0 : if( dataFlag & 1 )
2374 : {
2375 0 : CADVector vectExtrusion = buffer.ReadVector();
2376 0 : polyline->vectExtrusion = vectExtrusion;
2377 : }
2378 :
2379 0 : verticesCount = buffer.ReadBITLONG();
2380 0 : if(verticesCount < 1)
2381 : {
2382 0 : delete polyline;
2383 0 : return nullptr;
2384 : }
2385 0 : if( verticesCount < 100000 )
2386 : {
2387 : // For some reason reserving huge amounts cause later segfaults
2388 : // whereas an exception would have been expected
2389 0 : polyline->avertVertices.reserve( static_cast<size_t>(verticesCount) );
2390 : }
2391 :
2392 0 : if( dataFlag & 16 )
2393 : {
2394 0 : nBulges = buffer.ReadBITLONG();
2395 0 : if(nBulges < 0)
2396 : {
2397 0 : delete polyline;
2398 0 : return nullptr;
2399 : }
2400 0 : if( nBulges < 100000 )
2401 : {
2402 0 : polyline->adfBulges.reserve( static_cast<size_t>(nBulges) );
2403 : }
2404 : }
2405 :
2406 : // TODO: tell ODA that R2000 contains nNumWidths flag
2407 0 : if( dataFlag & 32 )
2408 : {
2409 0 : nNumWidths = buffer.ReadBITLONG();
2410 0 : if(nNumWidths < 0)
2411 : {
2412 0 : delete polyline;
2413 0 : return nullptr;
2414 : }
2415 0 : if( nNumWidths < 100000 )
2416 : {
2417 0 : polyline->astWidths.reserve( static_cast<size_t>(nNumWidths) );
2418 : }
2419 : }
2420 :
2421 0 : if( dataFlag & 512 )
2422 : {
2423 0 : polyline->bClosed = true;
2424 : }
2425 : else
2426 : {
2427 0 : polyline->bClosed = false;
2428 : }
2429 :
2430 : // First of all, read first vertex.
2431 0 : CADVector vertex = buffer.ReadRAWVector();
2432 0 : polyline->avertVertices.push_back( vertex );
2433 :
2434 : // All the others are not raw doubles; bitdoubles with default instead,
2435 : // where default is previous point coords.
2436 : size_t prev;
2437 0 : for( int i = 1; i < verticesCount; ++i )
2438 : {
2439 0 : prev = size_t( i - 1 );
2440 0 : double x = buffer.ReadBITDOUBLEWD( polyline->avertVertices[prev].getX() );
2441 0 : double y = buffer.ReadBITDOUBLEWD( polyline->avertVertices[prev].getY() );
2442 0 : if( buffer.IsEOB() )
2443 : {
2444 0 : delete polyline;
2445 0 : return nullptr;
2446 : }
2447 0 : vertex.setX( x );
2448 0 : vertex.setY( y );
2449 0 : polyline->avertVertices.push_back( vertex );
2450 : }
2451 :
2452 0 : for( int i = 0; i < nBulges; ++i )
2453 : {
2454 0 : double dfBulgeValue = buffer.ReadBITDOUBLE();
2455 0 : polyline->adfBulges.push_back( dfBulgeValue );
2456 0 : if( buffer.IsEOB() )
2457 : {
2458 0 : delete polyline;
2459 0 : return nullptr;
2460 : }
2461 : }
2462 :
2463 0 : for( int i = 0; i < nNumWidths; ++i )
2464 : {
2465 0 : double dfStartWidth = buffer.ReadBITDOUBLE();
2466 0 : double dfEndWidth = buffer.ReadBITDOUBLE();
2467 0 : if( buffer.IsEOB() )
2468 : {
2469 0 : delete polyline;
2470 0 : return nullptr;
2471 : }
2472 0 : polyline->astWidths.push_back( make_pair( dfStartWidth, dfEndWidth ) );
2473 : }
2474 :
2475 0 : fillCommonEntityHandleData( polyline, buffer);
2476 :
2477 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2478 0 : polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "WPOLYLINE" ) );
2479 0 : return polyline;
2480 : }
2481 :
2482 0 : CADArcObject * DWGFileR2000::getArc(unsigned int dObjectSize,
2483 : const CADCommonED& stCommonEntityData,
2484 : CADBuffer &buffer)
2485 : {
2486 0 : CADArcObject * arc = new CADArcObject();
2487 :
2488 0 : arc->setSize( dObjectSize );
2489 0 : arc->stCed = stCommonEntityData;
2490 :
2491 0 : CADVector vertPosition = buffer.ReadVector();
2492 0 : arc->vertPosition = vertPosition;
2493 0 : arc->dfRadius = buffer.ReadBITDOUBLE();
2494 0 : arc->dfThickness = buffer.ReadBIT() ? 0.0f : buffer.ReadBITDOUBLE();
2495 :
2496 0 : if( buffer.ReadBIT() )
2497 : {
2498 0 : arc->vectExtrusion = CADVector( 0.0f, 0.0f, 1.0f );
2499 : }
2500 : else
2501 : {
2502 0 : CADVector vectExtrusion = buffer.ReadVector();
2503 0 : arc->vectExtrusion = vectExtrusion;
2504 : }
2505 :
2506 0 : arc->dfStartAngle = buffer.ReadBITDOUBLE();
2507 0 : arc->dfEndAngle = buffer.ReadBITDOUBLE();
2508 :
2509 0 : fillCommonEntityHandleData( arc, buffer);
2510 :
2511 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2512 0 : arc->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ARC" ) );
2513 0 : return arc;
2514 : }
2515 :
2516 0 : CADSplineObject * DWGFileR2000::getSpline(unsigned int dObjectSize,
2517 : const CADCommonED& stCommonEntityData,
2518 : CADBuffer &buffer)
2519 : {
2520 0 : CADSplineObject * spline = new CADSplineObject();
2521 0 : spline->setSize( dObjectSize );
2522 0 : spline->stCed = stCommonEntityData;
2523 0 : spline->dScenario = buffer.ReadBITLONG();
2524 0 : spline->dDegree = buffer.ReadBITLONG();
2525 :
2526 0 : if( spline->dScenario == 2 )
2527 : {
2528 0 : spline->dfFitTol = buffer.ReadBITDOUBLE();
2529 0 : CADVector vectBegTangDir = buffer.ReadVector();
2530 0 : spline->vectBegTangDir = vectBegTangDir;
2531 0 : CADVector vectEndTangDir = buffer.ReadVector();
2532 0 : spline->vectEndTangDir = vectEndTangDir;
2533 :
2534 0 : spline->nNumFitPts = buffer.ReadBITLONG();
2535 0 : if(spline->nNumFitPts < 0 || spline->nNumFitPts > 10 * 1024 * 1024)
2536 : {
2537 0 : delete spline;
2538 0 : return nullptr;
2539 : }
2540 0 : spline->averFitPoints.reserve( static_cast<size_t>(spline->nNumFitPts) );
2541 : }
2542 0 : else if( spline->dScenario == 1 )
2543 : {
2544 0 : spline->bRational = buffer.ReadBIT();
2545 0 : spline->bClosed = buffer.ReadBIT();
2546 0 : spline->bPeriodic = buffer.ReadBIT();
2547 0 : spline->dfKnotTol = buffer.ReadBITDOUBLE();
2548 0 : spline->dfCtrlTol = buffer.ReadBITDOUBLE();
2549 :
2550 0 : spline->nNumKnots = buffer.ReadBITLONG();
2551 0 : if(spline->nNumKnots < 0 || spline->nNumKnots > 10 * 1024 * 1024)
2552 : {
2553 0 : delete spline;
2554 0 : return nullptr;
2555 : }
2556 0 : spline->adfKnots.reserve( static_cast<size_t>(spline->nNumKnots) );
2557 :
2558 0 : spline->nNumCtrlPts = buffer.ReadBITLONG();
2559 0 : if(spline->nNumCtrlPts < 0 || spline->nNumCtrlPts > 10 * 1024 * 1024)
2560 : {
2561 0 : delete spline;
2562 0 : return nullptr;
2563 : }
2564 0 : spline->avertCtrlPoints.reserve( static_cast<size_t>(spline->nNumCtrlPts) );
2565 0 : if( spline->bWeight )
2566 0 : spline->adfCtrlPointsWeight.reserve( static_cast<size_t>(spline->nNumCtrlPts) );
2567 0 : spline->bWeight = buffer.ReadBIT();
2568 : }
2569 : #ifdef _DEBUG
2570 : else
2571 : {
2572 : DebugMsg( "Spline scenario != {1,2} read: error." );
2573 : }
2574 : #endif
2575 0 : for( long i = 0; i < spline->nNumKnots; ++i )
2576 : {
2577 0 : spline->adfKnots.push_back( buffer.ReadBITDOUBLE() );
2578 0 : if( buffer.IsEOB() )
2579 : {
2580 0 : delete spline;
2581 0 : return nullptr;
2582 : }
2583 : }
2584 :
2585 0 : for( long i = 0; i < spline->nNumCtrlPts; ++i )
2586 : {
2587 0 : CADVector vertex = buffer.ReadVector();
2588 0 : spline->avertCtrlPoints.push_back( vertex );
2589 0 : if( spline->bWeight )
2590 0 : spline->adfCtrlPointsWeight.push_back( buffer.ReadBITDOUBLE() );
2591 0 : if( buffer.IsEOB() )
2592 : {
2593 0 : delete spline;
2594 0 : return nullptr;
2595 : }
2596 : }
2597 :
2598 0 : for( long i = 0; i < spline->nNumFitPts; ++i )
2599 : {
2600 0 : CADVector vertex = buffer.ReadVector();
2601 0 : if( buffer.IsEOB() )
2602 : {
2603 0 : delete spline;
2604 0 : return nullptr;
2605 : }
2606 0 : spline->averFitPoints.push_back( vertex );
2607 : }
2608 :
2609 0 : fillCommonEntityHandleData( spline, buffer);
2610 :
2611 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2612 0 : spline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "SPLINE" ) );
2613 0 : return spline;
2614 : }
2615 :
2616 18 : CADEntityObject * DWGFileR2000::getEntity(int dObjectType,
2617 : unsigned int dObjectSize,
2618 : const CADCommonED& stCommonEntityData,
2619 : CADBuffer &buffer)
2620 : {
2621 : CADEntityObject * entity = new CADEntityObject(
2622 18 : static_cast<CADObject::ObjectType>(dObjectType) );
2623 :
2624 18 : entity->setSize( dObjectSize );
2625 18 : entity->stCed = stCommonEntityData;
2626 :
2627 18 : buffer.Seek(static_cast<size_t>(
2628 18 : entity->stCed.nObjectSizeInBits + 16), CADBuffer::BEG);
2629 :
2630 18 : fillCommonEntityHandleData( entity, buffer );
2631 :
2632 18 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2633 18 : entity->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "ENTITY" ) );
2634 18 : return entity;
2635 : }
2636 :
2637 0 : CADInsertObject * DWGFileR2000::getInsert(int dObjectType,
2638 : unsigned int dObjectSize,
2639 : const CADCommonED& stCommonEntityData,
2640 : CADBuffer &buffer)
2641 : {
2642 : CADInsertObject * insert = new CADInsertObject(
2643 0 : static_cast<CADObject::ObjectType>(dObjectType) );
2644 0 : insert->setSize( dObjectSize );
2645 0 : insert->stCed = stCommonEntityData;
2646 :
2647 0 : insert->vertInsertionPoint = buffer.ReadVector();
2648 0 : unsigned char dataFlags = buffer.Read2B();
2649 0 : double val41 = 1.0;
2650 0 : double val42 = 1.0;
2651 0 : double val43 = 1.0;
2652 0 : if( dataFlags == 0 )
2653 : {
2654 0 : val41 = buffer.ReadRAWDOUBLE();
2655 0 : val42 = buffer.ReadBITDOUBLEWD( val41 );
2656 0 : val43 = buffer.ReadBITDOUBLEWD( val41 );
2657 : }
2658 0 : else if( dataFlags == 1 )
2659 : {
2660 0 : val41 = 1.0;
2661 0 : val42 = buffer.ReadBITDOUBLEWD( val41 );
2662 0 : val43 = buffer.ReadBITDOUBLEWD( val41 );
2663 : }
2664 0 : else if( dataFlags == 2 )
2665 : {
2666 0 : val41 = buffer.ReadRAWDOUBLE();
2667 0 : val42 = val41;
2668 0 : val43 = val41;
2669 : }
2670 0 : insert->vertScales = CADVector( val41, val42, val43 );
2671 0 : insert->dfRotation = buffer.ReadBITDOUBLE();
2672 0 : insert->vectExtrusion = buffer.ReadVector();
2673 0 : insert->bHasAttribs = buffer.ReadBIT();
2674 :
2675 0 : fillCommonEntityHandleData( insert, buffer);
2676 :
2677 0 : insert->hBlockHeader = buffer.ReadHANDLE();
2678 0 : if( insert->bHasAttribs )
2679 : {
2680 0 : insert->hAttribs.push_back( buffer.ReadHANDLE() );
2681 0 : insert->hAttribs.push_back( buffer.ReadHANDLE() );
2682 0 : insert->hSeqend = buffer.ReadHANDLE();
2683 : }
2684 :
2685 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2686 0 : insert->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "INSERT" ) );
2687 :
2688 0 : return insert;
2689 : }
2690 :
2691 120 : CADDictionaryObject * DWGFileR2000::getDictionary(unsigned int dObjectSize,
2692 : CADBuffer &buffer)
2693 : {
2694 : /*
2695 : * FIXME: ODA has a lot of mistypes in spec. for this objects,
2696 : * it doesn't work for now (error begins in handles stream).
2697 : * Nonetheless, dictionary->sItemNames is 100% array,
2698 : * not a single obj as pointer by their docs.
2699 : */
2700 120 : CADDictionaryObject * dictionary = new CADDictionaryObject();
2701 :
2702 120 : if(!readBasicData(dictionary, dObjectSize, buffer))
2703 : {
2704 0 : delete dictionary;
2705 0 : return nullptr;
2706 : }
2707 :
2708 120 : dictionary->nNumItems = buffer.ReadBITLONG();
2709 120 : if(dictionary->nNumItems < 0)
2710 : {
2711 0 : delete dictionary;
2712 0 : return nullptr;
2713 : }
2714 120 : dictionary->dCloningFlag = buffer.ReadBITSHORT();
2715 120 : dictionary->dHardOwnerFlag = buffer.ReadCHAR();
2716 :
2717 890 : for( long i = 0; i < dictionary->nNumItems; ++i )
2718 : {
2719 770 : dictionary->sItemNames.push_back( buffer.ReadTV() );
2720 770 : if( buffer.IsEOB() )
2721 : {
2722 0 : delete dictionary;
2723 0 : return nullptr;
2724 : }
2725 : }
2726 :
2727 120 : dictionary->hParentHandle = buffer.ReadHANDLE();
2728 :
2729 232 : for( long i = 0; i < dictionary->nNumReactors; ++i )
2730 : {
2731 112 : dictionary->hReactors.push_back( buffer.ReadHANDLE() );
2732 112 : if( buffer.IsEOB() )
2733 : {
2734 0 : delete dictionary;
2735 0 : return nullptr;
2736 : }
2737 : }
2738 120 : dictionary->hXDictionary = buffer.ReadHANDLE();
2739 890 : for( long i = 0; i < dictionary->nNumItems; ++i )
2740 : {
2741 770 : dictionary->hItemHandles.push_back( buffer.ReadHANDLE() );
2742 770 : if( buffer.IsEOB() )
2743 : {
2744 0 : delete dictionary;
2745 0 : return nullptr;
2746 : }
2747 : }
2748 :
2749 120 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2750 120 : dictionary->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DICT" ) );
2751 :
2752 120 : return dictionary;
2753 : }
2754 :
2755 10 : CADLayerObject * DWGFileR2000::getLayerObject(unsigned int dObjectSize,
2756 : CADBuffer &buffer)
2757 : {
2758 10 : CADLayerObject * layer = new CADLayerObject();
2759 :
2760 10 : if(!readBasicData(layer, dObjectSize, buffer))
2761 : {
2762 0 : delete layer;
2763 0 : return nullptr;
2764 : }
2765 :
2766 10 : layer->sLayerName = buffer.ReadTV();
2767 10 : layer->b64Flag = buffer.ReadBIT() != 0;
2768 10 : layer->dXRefIndex = buffer.ReadBITSHORT();
2769 10 : layer->bXDep = buffer.ReadBIT() != 0;
2770 :
2771 10 : short dFlags = buffer.ReadBITSHORT();
2772 10 : layer->bFrozen = (dFlags & 0x01) != 0;
2773 10 : layer->bOn = (dFlags & 0x02) != 0;
2774 10 : layer->bFrozenInNewVPORT = (dFlags & 0x04) != 0;
2775 10 : layer->bLocked = (dFlags & 0x08) != 0;
2776 10 : layer->bPlottingFlag = (dFlags & 0x10) != 0;
2777 10 : layer->dLineWeight = dFlags & 0x03E0;
2778 10 : layer->dCMColor = buffer.ReadBITSHORT();
2779 10 : layer->hLayerControl = buffer.ReadHANDLE();
2780 10 : for( long i = 0; i < layer->nNumReactors; ++i )
2781 : {
2782 0 : layer->hReactors.push_back( buffer.ReadHANDLE() );
2783 0 : if( buffer.IsEOB() )
2784 : {
2785 0 : delete layer;
2786 0 : return nullptr;
2787 : }
2788 : }
2789 10 : layer->hXDictionary = buffer.ReadHANDLE();
2790 10 : layer->hExternalRefBlockHandle = buffer.ReadHANDLE();
2791 10 : layer->hPlotStyle = buffer.ReadHANDLE();
2792 10 : layer->hLType = buffer.ReadHANDLE();
2793 :
2794 : /*
2795 : * FIXME: ODA says that this handle should be null hard pointer. It is not.
2796 : * Also, after reading it dObjectSize is != actual read structure's size.
2797 : * Not used anyway, so no point to read it for now.
2798 : * It also means that CRC cannot be computed correctly.
2799 : */
2800 : // layer->hUnknownHandle = ReadHANDLE (pabySectionContent, nBitOffsetFromStart);
2801 :
2802 10 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2803 10 : layer->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LAYER" ) );
2804 10 : return layer;
2805 : }
2806 :
2807 8 : CADLayerControlObject * DWGFileR2000::getLayerControl(unsigned int dObjectSize,
2808 : CADBuffer &buffer)
2809 : {
2810 8 : CADLayerControlObject * layerControl = new CADLayerControlObject();
2811 :
2812 8 : if(!readBasicData(layerControl, dObjectSize, buffer))
2813 : {
2814 0 : delete layerControl;
2815 0 : return nullptr;
2816 : }
2817 :
2818 8 : layerControl->nNumEntries = buffer.ReadBITLONG();
2819 8 : if(layerControl->nNumEntries < 0)
2820 : {
2821 0 : delete layerControl;
2822 0 : return nullptr;
2823 : }
2824 8 : layerControl->hNull = buffer.ReadHANDLE();
2825 8 : layerControl->hXDictionary = buffer.ReadHANDLE();
2826 18 : for( long i = 0; i < layerControl->nNumEntries; ++i )
2827 : {
2828 10 : layerControl->hLayers.push_back( buffer.ReadHANDLE() );
2829 10 : if( buffer.IsEOB() )
2830 : {
2831 0 : delete layerControl;
2832 0 : return nullptr;
2833 : }
2834 : }
2835 :
2836 8 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2837 8 : layerControl->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LAYERCONTROL" ) );
2838 8 : return layerControl;
2839 : }
2840 :
2841 0 : CADBlockControlObject * DWGFileR2000::getBlockControl(unsigned int dObjectSize,
2842 : CADBuffer &buffer)
2843 : {
2844 0 : CADBlockControlObject * blockControl = new CADBlockControlObject();
2845 :
2846 0 : if(!readBasicData(blockControl, dObjectSize, buffer))
2847 : {
2848 0 : delete blockControl;
2849 0 : return nullptr;
2850 : }
2851 :
2852 0 : blockControl->nNumEntries = buffer.ReadBITLONG();
2853 0 : if(blockControl->nNumEntries < 0)
2854 : {
2855 0 : delete blockControl;
2856 0 : return nullptr;
2857 : }
2858 :
2859 0 : blockControl->hNull = buffer.ReadHANDLE();
2860 0 : blockControl->hXDictionary = buffer.ReadHANDLE();
2861 :
2862 0 : for( long i = 0; i < blockControl->nNumEntries + 2; ++i )
2863 : {
2864 0 : blockControl->hBlocks.push_back( buffer.ReadHANDLE() );
2865 0 : if( buffer.IsEOB() )
2866 : {
2867 0 : delete blockControl;
2868 0 : return nullptr;
2869 : }
2870 : }
2871 :
2872 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2873 0 : blockControl->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "BLOCKCONTROL" ) );
2874 0 : return blockControl;
2875 : }
2876 :
2877 8 : CADBlockHeaderObject * DWGFileR2000::getBlockHeader(unsigned int dObjectSize,
2878 : CADBuffer &buffer)
2879 : {
2880 8 : CADBlockHeaderObject * blockHeader = new CADBlockHeaderObject();
2881 :
2882 8 : if(!readBasicData(blockHeader, dObjectSize, buffer))
2883 : {
2884 0 : delete blockHeader;
2885 0 : return nullptr;
2886 : }
2887 :
2888 8 : blockHeader->sEntryName = buffer.ReadTV();
2889 8 : blockHeader->b64Flag = buffer.ReadBIT();
2890 8 : blockHeader->dXRefIndex = buffer.ReadBITSHORT();
2891 8 : blockHeader->bXDep = buffer.ReadBIT();
2892 8 : blockHeader->bAnonymous = buffer.ReadBIT();
2893 8 : blockHeader->bHasAtts = buffer.ReadBIT();
2894 8 : blockHeader->bBlkisXRef = buffer.ReadBIT();
2895 8 : blockHeader->bXRefOverlaid = buffer.ReadBIT();
2896 8 : blockHeader->bLoadedBit = buffer.ReadBIT();
2897 :
2898 8 : CADVector vertBasePoint = buffer.ReadVector();
2899 8 : blockHeader->vertBasePoint = vertBasePoint;
2900 8 : blockHeader->sXRefPName = buffer.ReadTV();
2901 : unsigned char Tmp;
2902 0 : do
2903 : {
2904 8 : Tmp = buffer.ReadCHAR();
2905 8 : blockHeader->adInsertCount.push_back( Tmp );
2906 8 : } while( Tmp != 0 );
2907 :
2908 8 : blockHeader->sBlockDescription = buffer.ReadTV();
2909 8 : blockHeader->nSizeOfPreviewData = buffer.ReadBITLONG();
2910 8 : if(blockHeader->nSizeOfPreviewData < 0)
2911 : {
2912 0 : delete blockHeader;
2913 0 : return nullptr;
2914 : }
2915 8 : for( long i = 0; i < blockHeader->nSizeOfPreviewData; ++i )
2916 : {
2917 0 : blockHeader->abyBinaryPreviewData.push_back( buffer.ReadCHAR() );
2918 0 : if( buffer.IsEOB() )
2919 : {
2920 0 : delete blockHeader;
2921 0 : return nullptr;
2922 : }
2923 : }
2924 :
2925 8 : blockHeader->hBlockControl = buffer.ReadHANDLE();
2926 8 : for( long i = 0; i < blockHeader->nNumReactors; ++i )
2927 : {
2928 0 : blockHeader->hReactors.push_back( buffer.ReadHANDLE() );
2929 0 : if( buffer.IsEOB() )
2930 : {
2931 0 : delete blockHeader;
2932 0 : return nullptr;
2933 : }
2934 : }
2935 8 : blockHeader->hXDictionary = buffer.ReadHANDLE();
2936 8 : blockHeader->hNull = buffer.ReadHANDLE();
2937 8 : blockHeader->hBlockEntity = buffer.ReadHANDLE();
2938 8 : if( !blockHeader->bBlkisXRef && !blockHeader->bXRefOverlaid )
2939 : {
2940 8 : blockHeader->hEntities.push_back( buffer.ReadHANDLE() ); // first
2941 8 : blockHeader->hEntities.push_back( buffer.ReadHANDLE() ); // last
2942 : }
2943 :
2944 8 : blockHeader->hEndBlk = buffer.ReadHANDLE();
2945 8 : for( size_t i = 0; i < blockHeader->adInsertCount.size() - 1; ++i )
2946 0 : blockHeader->hInsertHandles.push_back( buffer.ReadHANDLE() );
2947 8 : blockHeader->hLayout = buffer.ReadHANDLE();
2948 :
2949 8 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2950 8 : blockHeader->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "BLOCKHEADER" ) );
2951 8 : return blockHeader;
2952 : }
2953 :
2954 0 : CADLineTypeControlObject * DWGFileR2000::getLineTypeControl(unsigned int dObjectSize,
2955 : CADBuffer &buffer)
2956 : {
2957 0 : CADLineTypeControlObject * ltypeControl = new CADLineTypeControlObject();
2958 :
2959 0 : if(!readBasicData(ltypeControl, dObjectSize, buffer))
2960 : {
2961 0 : delete ltypeControl;
2962 0 : return nullptr;
2963 : }
2964 :
2965 0 : ltypeControl->nNumEntries = buffer.ReadBITLONG();
2966 0 : if(ltypeControl->nNumEntries < 0)
2967 : {
2968 0 : delete ltypeControl;
2969 0 : return nullptr;
2970 : }
2971 :
2972 0 : ltypeControl->hNull = buffer.ReadHANDLE();
2973 0 : ltypeControl->hXDictionary = buffer.ReadHANDLE();
2974 :
2975 : // hLTypes ends with BYLAYER and BYBLOCK
2976 0 : for( long i = 0; i < ltypeControl->nNumEntries + 2; ++i )
2977 : {
2978 0 : ltypeControl->hLTypes.push_back( buffer.ReadHANDLE() );
2979 0 : if( buffer.IsEOB() )
2980 : {
2981 0 : delete ltypeControl;
2982 0 : return nullptr;
2983 : }
2984 : }
2985 :
2986 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
2987 0 : ltypeControl->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LINETYPECTRL" ) );
2988 0 : return ltypeControl;
2989 : }
2990 :
2991 0 : CADLineTypeObject * DWGFileR2000::getLineType1(unsigned int dObjectSize, CADBuffer &buffer)
2992 : {
2993 0 : CADLineTypeObject * ltype = new CADLineTypeObject();
2994 :
2995 0 : if(!readBasicData(ltype, dObjectSize, buffer))
2996 : {
2997 0 : delete ltype;
2998 0 : return nullptr;
2999 : }
3000 :
3001 0 : ltype->sEntryName = buffer.ReadTV();
3002 0 : ltype->b64Flag = buffer.ReadBIT();
3003 0 : ltype->dXRefIndex = buffer.ReadBITSHORT();
3004 0 : ltype->bXDep = buffer.ReadBIT();
3005 0 : ltype->sDescription = buffer.ReadTV();
3006 0 : ltype->dfPatternLen = buffer.ReadBITDOUBLE();
3007 0 : ltype->dAlignment = buffer.ReadCHAR();
3008 0 : ltype->nNumDashes = buffer.ReadCHAR();
3009 :
3010 : CADDash dash;
3011 0 : for( size_t i = 0; i < ltype->nNumDashes; ++i )
3012 : {
3013 0 : dash.dfLength = buffer.ReadBITDOUBLE();
3014 0 : dash.dComplexShapecode = buffer.ReadBITSHORT();
3015 0 : dash.dfXOffset = buffer.ReadRAWDOUBLE();
3016 0 : dash.dfYOffset = buffer.ReadRAWDOUBLE();
3017 0 : dash.dfScale = buffer.ReadBITDOUBLE();
3018 0 : dash.dfRotation = buffer.ReadBITDOUBLE();
3019 0 : dash.dShapeflag = buffer.ReadBITSHORT(); // TODO: what to do with it?
3020 :
3021 0 : ltype->astDashes.push_back( dash );
3022 : }
3023 :
3024 0 : for( short i = 0; i < 256; ++i )
3025 0 : ltype->abyTextArea.push_back( buffer.ReadCHAR() );
3026 :
3027 0 : ltype->hLTControl = buffer.ReadHANDLE();
3028 :
3029 0 : for( long i = 0; i < ltype->nNumReactors; ++i )
3030 : {
3031 0 : ltype->hReactors.push_back( buffer.ReadHANDLE() );
3032 0 : if( buffer.IsEOB() )
3033 : {
3034 0 : delete ltype;
3035 0 : return nullptr;
3036 : }
3037 : }
3038 :
3039 0 : ltype->hXDictionary = buffer.ReadHANDLE();
3040 0 : ltype->hXRefBlock = buffer.ReadHANDLE();
3041 :
3042 : // TODO: shapefile for dash/shape (1 each). Does it mean that we have nNumDashes * 2 handles, or what?
3043 :
3044 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3045 0 : ltype->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "LINETYPE" ) );
3046 0 : return ltype;
3047 : }
3048 :
3049 0 : CADMLineObject * DWGFileR2000::getMLine(unsigned int dObjectSize,
3050 : const CADCommonED& stCommonEntityData,
3051 : CADBuffer &buffer)
3052 : {
3053 0 : CADMLineObject * mline = new CADMLineObject();
3054 :
3055 0 : mline->setSize( dObjectSize );
3056 0 : mline->stCed = stCommonEntityData;
3057 :
3058 0 : mline->dfScale = buffer.ReadBITDOUBLE();
3059 0 : mline->dJust = buffer.ReadCHAR();
3060 :
3061 0 : CADVector vertBasePoint = buffer.ReadVector();
3062 0 : mline->vertBasePoint = vertBasePoint;
3063 :
3064 0 : CADVector vectExtrusion = buffer.ReadVector();
3065 0 : mline->vectExtrusion = vectExtrusion;
3066 0 : mline->dOpenClosed = buffer.ReadBITSHORT();
3067 0 : mline->nLinesInStyle = buffer.ReadCHAR();
3068 0 : mline->nNumVertices = buffer.ReadBITSHORT();
3069 0 : if(mline->nNumVertices < 0)
3070 : {
3071 0 : delete mline;
3072 0 : return nullptr;
3073 : }
3074 :
3075 0 : for( short i = 0; i < mline->nNumVertices; ++i )
3076 : {
3077 0 : CADMLineVertex stVertex;
3078 :
3079 0 : CADVector vertPosition = buffer.ReadVector();
3080 0 : stVertex.vertPosition = vertPosition;
3081 :
3082 0 : CADVector vectDirection = buffer.ReadVector();
3083 0 : stVertex.vectDirection = vectDirection;
3084 :
3085 0 : CADVector vectMIterDirection = buffer.ReadVector();
3086 0 : stVertex.vectMIterDirection = vectMIterDirection;
3087 0 : if( buffer.IsEOB() )
3088 : {
3089 0 : delete mline;
3090 0 : return nullptr;
3091 : }
3092 0 : for( unsigned char j = 0; j < mline->nLinesInStyle; ++j )
3093 : {
3094 0 : CADLineStyle stLStyle;
3095 0 : stLStyle.nNumSegParams = buffer.ReadBITSHORT();
3096 0 : if( stLStyle.nNumSegParams > 0 ) // Or return null here?
3097 : {
3098 0 : for( short k = 0; k < stLStyle.nNumSegParams; ++k )
3099 0 : stLStyle.adfSegparms.push_back( buffer.ReadBITDOUBLE() );
3100 : }
3101 0 : stLStyle.nAreaFillParams = buffer.ReadBITSHORT();
3102 0 : if( stLStyle.nAreaFillParams > 0 )
3103 : {
3104 0 : for( short k = 0; k < stLStyle.nAreaFillParams; ++k )
3105 0 : stLStyle.adfAreaFillParameters.push_back( buffer.ReadBITDOUBLE() );
3106 : }
3107 :
3108 0 : stVertex.astLStyles.push_back( std::move(stLStyle) );
3109 0 : if( buffer.IsEOB() )
3110 : {
3111 0 : delete mline;
3112 0 : return nullptr;
3113 : }
3114 : }
3115 0 : mline->avertVertices.push_back( std::move(stVertex) );
3116 : }
3117 :
3118 0 : if( mline->stCed.bbEntMode == 0 )
3119 0 : mline->stChed.hOwner = buffer.ReadHANDLE();
3120 :
3121 0 : for( long i = 0; i < mline->stCed.nNumReactors; ++i )
3122 0 : mline->stChed.hReactors.push_back( buffer.ReadHANDLE() );
3123 :
3124 0 : mline->stChed.hXDictionary = buffer.ReadHANDLE();
3125 :
3126 0 : if( !mline->stCed.bNoLinks )
3127 : {
3128 0 : mline->stChed.hPrevEntity = buffer.ReadHANDLE();
3129 0 : mline->stChed.hNextEntity = buffer.ReadHANDLE();
3130 : }
3131 :
3132 0 : mline->stChed.hLayer = buffer.ReadHANDLE();
3133 :
3134 0 : if( mline->stCed.bbLTypeFlags == 0x03 )
3135 0 : mline->stChed.hLType = buffer.ReadHANDLE();
3136 :
3137 0 : if( mline->stCed.bbPlotStyleFlags == 0x03 )
3138 0 : mline->stChed.hPlotStyle = buffer.ReadHANDLE();
3139 :
3140 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3141 0 : mline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "MLINE" ) );
3142 0 : return mline;
3143 : }
3144 :
3145 0 : CADPolylinePFaceObject * DWGFileR2000::getPolylinePFace(unsigned int dObjectSize,
3146 : const CADCommonED& stCommonEntityData,
3147 : CADBuffer &buffer)
3148 : {
3149 0 : CADPolylinePFaceObject * polyline = new CADPolylinePFaceObject();
3150 :
3151 0 : polyline->setSize( dObjectSize );
3152 0 : polyline->stCed = stCommonEntityData;
3153 :
3154 0 : polyline->nNumVertices = buffer.ReadBITSHORT();
3155 0 : polyline->nNumFaces = buffer.ReadBITSHORT();
3156 :
3157 0 : fillCommonEntityHandleData( polyline, buffer);
3158 :
3159 0 : polyline->hVertices.push_back( buffer.ReadHANDLE() ); // 1st vertex
3160 0 : polyline->hVertices.push_back( buffer.ReadHANDLE() ); // last vertex
3161 :
3162 0 : polyline->hSeqend = buffer.ReadHANDLE();
3163 :
3164 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3165 0 : polyline->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "POLYLINEPFACE" ) );
3166 0 : return polyline;
3167 : }
3168 :
3169 0 : CADImageObject * DWGFileR2000::getImage(unsigned int dObjectSize,
3170 : const CADCommonED& stCommonEntityData,
3171 : CADBuffer &buffer)
3172 : {
3173 0 : CADImageObject * image = new CADImageObject();
3174 :
3175 0 : image->setSize( dObjectSize );
3176 0 : image->stCed = stCommonEntityData;
3177 :
3178 0 : image->dClassVersion = buffer.ReadBITLONG();
3179 :
3180 0 : CADVector vertInsertion = buffer.ReadVector();
3181 0 : image->vertInsertion = vertInsertion;
3182 :
3183 0 : CADVector vectUDirection = buffer.ReadVector();
3184 0 : image->vectUDirection = vectUDirection;
3185 :
3186 0 : CADVector vectVDirection = buffer.ReadVector();
3187 0 : image->vectVDirection = vectVDirection;
3188 :
3189 0 : image->dfSizeX = buffer.ReadRAWDOUBLE();
3190 0 : image->dfSizeY = buffer.ReadRAWDOUBLE();
3191 0 : image->dDisplayProps = buffer.ReadBITSHORT();
3192 :
3193 0 : image->bClipping = buffer.ReadBIT();
3194 0 : image->dBrightness = buffer.ReadCHAR();
3195 0 : image->dContrast = buffer.ReadCHAR();
3196 0 : image->dFade = buffer.ReadCHAR();
3197 0 : image->dClipBoundaryType = buffer.ReadBITSHORT();
3198 :
3199 0 : if( image->dClipBoundaryType == 1 )
3200 : {
3201 0 : CADVector vertPoint1 = buffer.ReadRAWVector();
3202 0 : image->avertClippingPolygonVertices.push_back( vertPoint1 );
3203 :
3204 0 : CADVector vertPoint2 = buffer.ReadRAWVector();
3205 0 : image->avertClippingPolygonVertices.push_back( vertPoint2 );
3206 : }
3207 : else
3208 : {
3209 0 : image->nNumberVerticesInClipPolygon = buffer.ReadBITLONG();
3210 0 : if(image->nNumberVerticesInClipPolygon < 0)
3211 : {
3212 0 : delete image;
3213 0 : return nullptr;
3214 : }
3215 :
3216 0 : for( long i = 0; i < image->nNumberVerticesInClipPolygon; ++i )
3217 : {
3218 0 : CADVector vertPoint = buffer.ReadRAWVector();
3219 0 : if( buffer.IsEOB() )
3220 : {
3221 0 : delete image;
3222 0 : return nullptr;
3223 : }
3224 0 : image->avertClippingPolygonVertices.push_back( vertPoint );
3225 : }
3226 : }
3227 :
3228 0 : fillCommonEntityHandleData( image, buffer);
3229 :
3230 0 : image->hImageDef = buffer.ReadHANDLE();
3231 0 : image->hImageDefReactor = buffer.ReadHANDLE();
3232 :
3233 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3234 0 : image->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "IMAGE" ) );
3235 :
3236 0 : return image;
3237 : }
3238 :
3239 0 : CAD3DFaceObject * DWGFileR2000::get3DFace(unsigned int dObjectSize,
3240 : const CADCommonED& stCommonEntityData,
3241 : CADBuffer &buffer)
3242 : {
3243 0 : CAD3DFaceObject * face = new CAD3DFaceObject();
3244 :
3245 0 : face->setSize( dObjectSize );
3246 0 : face->stCed = stCommonEntityData;
3247 :
3248 0 : face->bHasNoFlagInd = buffer.ReadBIT();
3249 0 : face->bZZero = buffer.ReadBIT();
3250 :
3251 : double x, y, z;
3252 :
3253 0 : CADVector vertex = buffer.ReadRAWVector();
3254 0 : if( !face->bZZero )
3255 : {
3256 0 : z = buffer.ReadRAWDOUBLE();
3257 0 : vertex.setZ( z );
3258 : }
3259 0 : face->avertCorners.push_back( vertex );
3260 0 : for( size_t i = 1; i < 4; ++i )
3261 : {
3262 0 : x = buffer.ReadBITDOUBLEWD( face->avertCorners[i - 1].getX() );
3263 0 : y = buffer.ReadBITDOUBLEWD( face->avertCorners[i - 1].getY() );
3264 0 : z = buffer.ReadBITDOUBLEWD( face->avertCorners[i - 1].getZ() );
3265 :
3266 0 : CADVector corner( x, y, z );
3267 0 : face->avertCorners.push_back( corner );
3268 : }
3269 :
3270 0 : if( !face->bHasNoFlagInd )
3271 0 : face->dInvisFlags = buffer.ReadBITSHORT();
3272 :
3273 0 : fillCommonEntityHandleData( face, buffer);
3274 :
3275 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3276 0 : face->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "3DFACE" ) );
3277 0 : return face;
3278 : }
3279 :
3280 0 : CADVertexMeshObject * DWGFileR2000::getVertexMesh(unsigned int dObjectSize,
3281 : const CADCommonED& stCommonEntityData,
3282 : CADBuffer &buffer)
3283 : {
3284 0 : CADVertexMeshObject * vertex = new CADVertexMeshObject();
3285 :
3286 0 : vertex->setSize( dObjectSize );
3287 0 : vertex->stCed = stCommonEntityData;
3288 :
3289 0 : /*unsigned char Flags = */buffer.ReadCHAR();
3290 0 : CADVector vertPosition = buffer.ReadVector();
3291 0 : vertex->vertPosition = vertPosition;
3292 :
3293 0 : fillCommonEntityHandleData( vertex, buffer);
3294 :
3295 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3296 0 : vertex->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "VERTEXMESH" ) );
3297 0 : return vertex;
3298 : }
3299 :
3300 0 : CADVertexPFaceObject * DWGFileR2000::getVertexPFace(unsigned int dObjectSize,
3301 : const CADCommonED& stCommonEntityData,
3302 : CADBuffer &buffer)
3303 : {
3304 0 : CADVertexPFaceObject * vertex = new CADVertexPFaceObject();
3305 :
3306 0 : vertex->setSize( dObjectSize );
3307 0 : vertex->stCed = stCommonEntityData;
3308 :
3309 0 : /*unsigned char Flags = */buffer.ReadCHAR();
3310 0 : CADVector vertPosition = buffer.ReadVector();
3311 0 : vertex->vertPosition = vertPosition;
3312 :
3313 0 : fillCommonEntityHandleData( vertex, buffer);
3314 :
3315 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3316 0 : vertex->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "VERTEXPFACE" ) );
3317 0 : return vertex;
3318 : }
3319 :
3320 2 : CADMTextObject * DWGFileR2000::getMText(unsigned int dObjectSize,
3321 : const CADCommonED& stCommonEntityData,
3322 : CADBuffer &buffer)
3323 : {
3324 2 : CADMTextObject * text = new CADMTextObject();
3325 :
3326 2 : text->setSize( dObjectSize );
3327 2 : text->stCed = stCommonEntityData;
3328 :
3329 2 : CADVector vertInsertionPoint = buffer.ReadVector();
3330 2 : text->vertInsertionPoint = vertInsertionPoint;
3331 :
3332 2 : CADVector vectExtrusion = buffer.ReadVector();
3333 2 : text->vectExtrusion = vectExtrusion;
3334 :
3335 2 : CADVector vectXAxisDir = buffer.ReadVector();
3336 2 : text->vectXAxisDir = vectXAxisDir;
3337 :
3338 2 : text->dfRectWidth = buffer.ReadBITDOUBLE();
3339 2 : text->dfTextHeight = buffer.ReadBITDOUBLE();
3340 2 : text->dAttachment = buffer.ReadBITSHORT();
3341 2 : text->dDrawingDir = buffer.ReadBITSHORT();
3342 2 : text->dfExtents = buffer.ReadBITDOUBLE();
3343 2 : text->dfExtentsWidth = buffer.ReadBITDOUBLE();
3344 2 : text->sTextValue = buffer.ReadTV();
3345 2 : text->dLineSpacingStyle = buffer.ReadBITSHORT();
3346 2 : text->dLineSpacingFactor = buffer.ReadBITDOUBLE();
3347 2 : text->bUnknownBit = buffer.ReadBIT();
3348 :
3349 2 : fillCommonEntityHandleData( text, buffer);
3350 :
3351 2 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3352 2 : text->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "MTEXT" ) );
3353 2 : return text;
3354 : }
3355 :
3356 0 : CADDimensionObject * DWGFileR2000::getDimension(short dObjectType,
3357 : unsigned int dObjectSize,
3358 : const CADCommonED& stCommonEntityData,
3359 : CADBuffer &buffer)
3360 : {
3361 0 : CADCommonDimensionData stCDD;
3362 :
3363 0 : CADVector vectExtrusion = buffer.ReadVector();
3364 0 : stCDD.vectExtrusion = vectExtrusion;
3365 :
3366 0 : CADVector vertTextMidPt = buffer.ReadRAWVector();
3367 0 : stCDD.vertTextMidPt = vertTextMidPt;
3368 :
3369 0 : stCDD.dfElevation = buffer.ReadBITDOUBLE();
3370 0 : stCDD.dFlags = buffer.ReadCHAR();
3371 :
3372 0 : stCDD.sUserText = buffer.ReadTV();
3373 0 : stCDD.dfTextRotation = buffer.ReadBITDOUBLE();
3374 0 : stCDD.dfHorizDir = buffer.ReadBITDOUBLE();
3375 :
3376 0 : stCDD.dfInsXScale = buffer.ReadBITDOUBLE();
3377 0 : stCDD.dfInsYScale = buffer.ReadBITDOUBLE();
3378 0 : stCDD.dfInsZScale = buffer.ReadBITDOUBLE();
3379 0 : stCDD.dfInsRotation = buffer.ReadBITDOUBLE();
3380 :
3381 0 : stCDD.dAttachmentPoint = buffer.ReadBITSHORT();
3382 0 : stCDD.dLineSpacingStyle = buffer.ReadBITSHORT();
3383 0 : stCDD.dfLineSpacingFactor = buffer.ReadBITDOUBLE();
3384 0 : stCDD.dfActualMeasurement = buffer.ReadBITDOUBLE();
3385 :
3386 0 : CADVector vert12Pt = buffer.ReadRAWVector();
3387 0 : stCDD.vert12Pt = vert12Pt;
3388 :
3389 0 : switch( dObjectType )
3390 : {
3391 0 : case CADObject::DIMENSION_ORDINATE:
3392 : {
3393 0 : CADDimensionOrdinateObject * dimension = new CADDimensionOrdinateObject();
3394 :
3395 0 : dimension->setSize( dObjectSize );
3396 0 : dimension->stCed = stCommonEntityData;
3397 0 : dimension->cdd = std::move(stCDD);
3398 :
3399 0 : CADVector vert10pt = buffer.ReadVector();
3400 0 : dimension->vert10pt = vert10pt;
3401 :
3402 0 : CADVector vert13pt = buffer.ReadVector();
3403 0 : dimension->vert13pt = vert13pt;
3404 :
3405 0 : CADVector vert14pt = buffer.ReadVector();
3406 0 : dimension->vert14pt = vert14pt;
3407 :
3408 0 : dimension->Flags2 = buffer.ReadCHAR();
3409 :
3410 0 : fillCommonEntityHandleData( dimension, buffer);
3411 :
3412 0 : dimension->hDimstyle = buffer.ReadHANDLE();
3413 0 : dimension->hAnonymousBlock = buffer.ReadHANDLE();
3414 :
3415 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3416 0 : dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
3417 0 : return dimension;
3418 : }
3419 :
3420 0 : case CADObject::DIMENSION_LINEAR:
3421 : {
3422 0 : CADDimensionLinearObject * dimension = new CADDimensionLinearObject();
3423 :
3424 0 : dimension->setSize( dObjectSize );
3425 0 : dimension->stCed = stCommonEntityData;
3426 0 : dimension->cdd = std::move(stCDD);
3427 :
3428 0 : CADVector vert13pt = buffer.ReadVector();
3429 0 : dimension->vert13pt = vert13pt;
3430 :
3431 0 : CADVector vert14pt = buffer.ReadVector();
3432 0 : dimension->vert14pt = vert14pt;
3433 :
3434 0 : CADVector vert10pt = buffer.ReadVector();
3435 0 : dimension->vert10pt = vert10pt;
3436 :
3437 0 : dimension->dfExtLnRot = buffer.ReadBITDOUBLE();
3438 0 : dimension->dfDimRot = buffer.ReadBITDOUBLE();
3439 :
3440 0 : fillCommonEntityHandleData( dimension, buffer);
3441 :
3442 0 : dimension->hDimstyle = buffer.ReadHANDLE();
3443 0 : dimension->hAnonymousBlock = buffer.ReadHANDLE();
3444 :
3445 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3446 0 : dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
3447 0 : return dimension;
3448 : }
3449 :
3450 0 : case CADObject::DIMENSION_ALIGNED:
3451 : {
3452 0 : CADDimensionAlignedObject * dimension = new CADDimensionAlignedObject();
3453 :
3454 0 : dimension->setSize( dObjectSize );
3455 0 : dimension->stCed = stCommonEntityData;
3456 0 : dimension->cdd = std::move(stCDD);
3457 :
3458 0 : CADVector vert13pt = buffer.ReadVector();
3459 0 : dimension->vert13pt = vert13pt;
3460 :
3461 0 : CADVector vert14pt = buffer.ReadVector();
3462 0 : dimension->vert14pt = vert14pt;
3463 :
3464 0 : CADVector vert10pt = buffer.ReadVector();
3465 0 : dimension->vert10pt = vert10pt;
3466 :
3467 0 : dimension->dfExtLnRot = buffer.ReadBITDOUBLE();
3468 :
3469 0 : fillCommonEntityHandleData( dimension, buffer);
3470 :
3471 0 : dimension->hDimstyle = buffer.ReadHANDLE();
3472 0 : dimension->hAnonymousBlock = buffer.ReadHANDLE();
3473 :
3474 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3475 0 : dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
3476 0 : return dimension;
3477 : }
3478 :
3479 0 : case CADObject::DIMENSION_ANG_3PT:
3480 : {
3481 0 : CADDimensionAngular3PtObject * dimension = new CADDimensionAngular3PtObject();
3482 :
3483 0 : dimension->setSize( dObjectSize );
3484 0 : dimension->stCed = stCommonEntityData;
3485 0 : dimension->cdd = std::move(stCDD);
3486 :
3487 0 : CADVector vert10pt = buffer.ReadVector();
3488 0 : dimension->vert10pt = vert10pt;
3489 :
3490 0 : CADVector vert13pt = buffer.ReadVector();
3491 0 : dimension->vert13pt = vert13pt;
3492 :
3493 0 : CADVector vert14pt = buffer.ReadVector();
3494 0 : dimension->vert14pt = vert14pt;
3495 :
3496 0 : CADVector vert15pt = buffer.ReadVector();
3497 0 : dimension->vert15pt = vert15pt;
3498 :
3499 0 : fillCommonEntityHandleData( dimension, buffer );
3500 :
3501 0 : dimension->hDimstyle = buffer.ReadHANDLE();
3502 0 : dimension->hAnonymousBlock = buffer.ReadHANDLE();
3503 :
3504 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3505 0 : dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
3506 0 : return dimension;
3507 : }
3508 :
3509 0 : case CADObject::DIMENSION_ANG_2LN:
3510 : {
3511 0 : CADDimensionAngular2LnObject * dimension = new CADDimensionAngular2LnObject();
3512 :
3513 0 : dimension->setSize( dObjectSize );
3514 0 : dimension->stCed = stCommonEntityData;
3515 0 : dimension->cdd = std::move(stCDD);
3516 :
3517 0 : CADVector vert16pt = buffer.ReadVector();
3518 0 : dimension->vert16pt = vert16pt;
3519 :
3520 0 : CADVector vert13pt = buffer.ReadVector();
3521 0 : dimension->vert13pt = vert13pt;
3522 :
3523 0 : CADVector vert14pt = buffer.ReadVector();
3524 0 : dimension->vert14pt = vert14pt;
3525 :
3526 0 : CADVector vert15pt = buffer.ReadVector();
3527 0 : dimension->vert15pt = vert15pt;
3528 :
3529 0 : CADVector vert10pt = buffer.ReadVector();
3530 0 : dimension->vert10pt = vert10pt;
3531 :
3532 0 : fillCommonEntityHandleData( dimension, buffer);
3533 :
3534 0 : dimension->hDimstyle = buffer.ReadHANDLE();
3535 0 : dimension->hAnonymousBlock = buffer.ReadHANDLE();
3536 :
3537 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3538 0 : dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
3539 0 : return dimension;
3540 : }
3541 :
3542 0 : case CADObject::DIMENSION_RADIUS:
3543 : {
3544 0 : CADDimensionRadiusObject * dimension = new CADDimensionRadiusObject();
3545 :
3546 0 : dimension->setSize( dObjectSize );
3547 0 : dimension->stCed = stCommonEntityData;
3548 0 : dimension->cdd = std::move(stCDD);
3549 :
3550 0 : CADVector vert10pt = buffer.ReadVector();
3551 0 : dimension->vert10pt = vert10pt;
3552 :
3553 0 : CADVector vert15pt = buffer.ReadVector();
3554 0 : dimension->vert15pt = vert15pt;
3555 :
3556 0 : dimension->dfLeaderLen = buffer.ReadBITDOUBLE();
3557 :
3558 0 : fillCommonEntityHandleData( dimension, buffer);
3559 :
3560 0 : dimension->hDimstyle = buffer.ReadHANDLE();
3561 0 : dimension->hAnonymousBlock = buffer.ReadHANDLE();
3562 :
3563 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3564 0 : dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
3565 0 : return dimension;
3566 : }
3567 :
3568 0 : case CADObject::DIMENSION_DIAMETER:
3569 : {
3570 0 : CADDimensionDiameterObject * dimension = new CADDimensionDiameterObject();
3571 :
3572 0 : dimension->setSize( dObjectSize );
3573 0 : dimension->stCed = stCommonEntityData;
3574 0 : dimension->cdd = std::move(stCDD);
3575 :
3576 0 : CADVector vert15pt = buffer.ReadVector();
3577 0 : dimension->vert15pt = vert15pt;
3578 :
3579 0 : CADVector vert10pt = buffer.ReadVector();
3580 0 : dimension->vert10pt = vert10pt;
3581 :
3582 0 : dimension->dfLeaderLen = buffer.ReadBITDOUBLE();
3583 :
3584 0 : fillCommonEntityHandleData( dimension, buffer);
3585 :
3586 0 : dimension->hDimstyle = buffer.ReadHANDLE();
3587 0 : dimension->hAnonymousBlock = buffer.ReadHANDLE();
3588 :
3589 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3590 0 : dimension->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "DIM" ) );
3591 0 : return dimension;
3592 : }
3593 : }
3594 0 : return nullptr;
3595 : }
3596 :
3597 0 : CADImageDefObject * DWGFileR2000::getImageDef(unsigned int dObjectSize,
3598 : CADBuffer &buffer)
3599 : {
3600 0 : CADImageDefObject * imagedef = new CADImageDefObject();
3601 :
3602 0 : if(!readBasicData(imagedef, dObjectSize, buffer))
3603 : {
3604 0 : delete imagedef;
3605 0 : return nullptr;
3606 : }
3607 :
3608 0 : imagedef->dClassVersion = buffer.ReadBITLONG();
3609 :
3610 0 : imagedef->dfXImageSizeInPx = buffer.ReadRAWDOUBLE();
3611 0 : imagedef->dfYImageSizeInPx = buffer.ReadRAWDOUBLE();
3612 :
3613 0 : imagedef->sFilePath = buffer.ReadTV();
3614 0 : imagedef->bIsLoaded = buffer.ReadBIT();
3615 :
3616 0 : imagedef->dResUnits = buffer.ReadCHAR();
3617 :
3618 0 : imagedef->dfXPixelSize = buffer.ReadRAWDOUBLE();
3619 0 : imagedef->dfYPixelSize = buffer.ReadRAWDOUBLE();
3620 :
3621 0 : imagedef->hParentHandle = buffer.ReadHANDLE();
3622 :
3623 0 : for( long i = 0; i < imagedef->nNumReactors; ++i )
3624 : {
3625 0 : imagedef->hReactors.push_back( buffer.ReadHANDLE() );
3626 0 : if( buffer.IsEOB() )
3627 : {
3628 0 : delete imagedef;
3629 0 : return nullptr;
3630 : }
3631 : }
3632 :
3633 0 : imagedef->hXDictionary = buffer.ReadHANDLE();
3634 :
3635 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3636 0 : imagedef->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "IMAGEDEF" ) );
3637 :
3638 0 : return imagedef;
3639 : }
3640 :
3641 0 : CADImageDefReactorObject * DWGFileR2000::getImageDefReactor(unsigned int dObjectSize, CADBuffer &buffer)
3642 : {
3643 0 : CADImageDefReactorObject * imagedefreactor = new CADImageDefReactorObject();
3644 :
3645 0 : if(!readBasicData(imagedefreactor, dObjectSize, buffer))
3646 : {
3647 0 : delete imagedefreactor;
3648 0 : return nullptr;
3649 : }
3650 :
3651 0 : imagedefreactor->dClassVersion = buffer.ReadBITLONG();
3652 :
3653 0 : imagedefreactor->hParentHandle =buffer.ReadHANDLE();
3654 :
3655 0 : for( long i = 0; i < imagedefreactor->nNumReactors; ++i )
3656 : {
3657 0 : imagedefreactor->hReactors.push_back( buffer.ReadHANDLE() );
3658 0 : if( buffer.IsEOB() )
3659 : {
3660 0 : delete imagedefreactor;
3661 0 : return nullptr;
3662 : }
3663 : }
3664 :
3665 0 : imagedefreactor->hXDictionary = buffer.ReadHANDLE();
3666 :
3667 0 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3668 0 : imagedefreactor->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "IMAGEDEFREFACTOR" ) );
3669 :
3670 0 : return imagedefreactor;
3671 : }
3672 :
3673 24 : CADXRecordObject * DWGFileR2000::getXRecord(unsigned int dObjectSize, CADBuffer &buffer)
3674 : {
3675 24 : CADXRecordObject * xrecord = new CADXRecordObject();
3676 :
3677 24 : if(!readBasicData(xrecord, dObjectSize, buffer))
3678 : {
3679 0 : delete xrecord;
3680 0 : return nullptr;
3681 : }
3682 :
3683 24 : xrecord->nNumDataBytes = buffer.ReadBITLONG();
3684 24 : if(xrecord->nNumDataBytes < 0)
3685 : {
3686 0 : delete xrecord;
3687 0 : return nullptr;
3688 : }
3689 1765 : for( long i = 0; i < xrecord->nNumDataBytes; ++i )
3690 : {
3691 1741 : xrecord->abyDataBytes.push_back( buffer.ReadCHAR() );
3692 1741 : if( buffer.IsEOB() )
3693 : {
3694 0 : delete xrecord;
3695 0 : return nullptr;
3696 : }
3697 : }
3698 :
3699 24 : xrecord->dCloningFlag = buffer.ReadBITSHORT();
3700 :
3701 24 : short dIndicatorNumber = buffer.ReadRAWSHORT();
3702 24 : if( dIndicatorNumber == 1 )
3703 : {
3704 0 : unsigned char nStringSize = buffer.ReadCHAR();
3705 0 : /* char dCodePage = */ buffer.ReadCHAR();
3706 0 : for( unsigned char i = 0; i < nStringSize; ++i )
3707 : {
3708 0 : buffer.ReadCHAR();
3709 : }
3710 : }
3711 24 : else if( dIndicatorNumber == 70 )
3712 : {
3713 0 : buffer.ReadRAWSHORT();
3714 : }
3715 24 : else if( dIndicatorNumber == 10 )
3716 : {
3717 0 : buffer.ReadRAWDOUBLE();
3718 0 : buffer.ReadRAWDOUBLE();
3719 0 : buffer.ReadRAWDOUBLE();
3720 : }
3721 24 : else if( dIndicatorNumber == 40 )
3722 : {
3723 0 : buffer.ReadRAWDOUBLE();
3724 : }
3725 :
3726 24 : xrecord->hParentHandle = buffer.ReadHANDLE();
3727 :
3728 48 : for( long i = 0; i < xrecord->nNumReactors; ++i )
3729 : {
3730 24 : xrecord->hReactors.push_back( buffer.ReadHANDLE() );
3731 24 : if( buffer.IsEOB() )
3732 : {
3733 0 : delete xrecord;
3734 0 : return nullptr;
3735 : }
3736 : }
3737 :
3738 24 : xrecord->hXDictionary = buffer.ReadHANDLE();
3739 :
3740 24 : size_t dObjectSizeBit = (dObjectSize + 4) * 8;
3741 24 : while( buffer.PositionBit() < dObjectSizeBit )
3742 : {
3743 0 : xrecord->hObjIdHandles.push_back( buffer.ReadHANDLE() );
3744 : }
3745 :
3746 24 : buffer.Seek((dObjectSize - 2) * 8, CADBuffer::BEG);
3747 24 : xrecord->setCRC( validateEntityCRC( buffer, dObjectSize - 2, "XRECORD" ) );
3748 :
3749 24 : return xrecord;
3750 : }
3751 :
3752 35 : void DWGFileR2000::fillCommonEntityHandleData(CADEntityObject * pEnt,
3753 : CADBuffer& buffer)
3754 : {
3755 35 : if( pEnt->stCed.bbEntMode == 0 )
3756 0 : pEnt->stChed.hOwner = buffer.ReadHANDLE();
3757 :
3758 : // TODO: Need some reasonable nNumReactors limits.
3759 35 : if(pEnt->stCed.nNumReactors < 0 || pEnt->stCed.nNumReactors > 5000)
3760 : {
3761 : // Something wrong occurred
3762 0 : return;
3763 : }
3764 35 : for( long i = 0; i < pEnt->stCed.nNumReactors; ++i )
3765 0 : pEnt->stChed.hReactors.push_back( buffer.ReadHANDLE() );
3766 :
3767 35 : pEnt->stChed.hXDictionary = buffer.ReadHANDLE();
3768 :
3769 35 : if( !pEnt->stCed.bNoLinks )
3770 : {
3771 27 : pEnt->stChed.hPrevEntity = buffer.ReadHANDLE();
3772 27 : pEnt->stChed.hNextEntity = buffer.ReadHANDLE();
3773 : }
3774 :
3775 35 : pEnt->stChed.hLayer = buffer.ReadHANDLE();
3776 :
3777 35 : if( pEnt->stCed.bbLTypeFlags == 0x03 )
3778 0 : pEnt->stChed.hLType = buffer.ReadHANDLE();
3779 :
3780 35 : if( pEnt->stCed.bbPlotStyleFlags == 0x03 )
3781 0 : pEnt->stChed.hPlotStyle = buffer.ReadHANDLE();
3782 : }
3783 :
3784 8 : DWGFileR2000::DWGFileR2000( CADFileIO * poFileIO ) :
3785 : CADFile( poFileIO ),
3786 8 : imageSeeker(0)
3787 : {
3788 8 : oHeader.addValue( CADHeader::OPENCADVER, CADVersions::DWG_R2000 );
3789 8 : }
3790 :
3791 8 : int DWGFileR2000::ReadSectionLocators()
3792 : {
3793 8 : char abyBuf[255] = { 0 };
3794 8 : int dImageSeeker = 0, SLRecordsCount = 0;
3795 8 : short dCodePage = 0;
3796 :
3797 8 : pFileIO->Rewind();
3798 8 : memset( abyBuf, 0, DWG_VERSION_STR_SIZE + 1 );
3799 8 : pFileIO->Read( abyBuf, DWG_VERSION_STR_SIZE );
3800 8 : oHeader.addValue( CADHeader::ACADVER, abyBuf );
3801 8 : memset( abyBuf, 0, 8 );
3802 8 : pFileIO->Read( abyBuf, 7 );
3803 8 : oHeader.addValue( CADHeader::ACADMAINTVER, abyBuf );
3804 : // TODO: code can be much simplified if CADHandle will be used.
3805 8 : pFileIO->Read( & dImageSeeker, 4 );
3806 8 : FromLSB(dImageSeeker);
3807 : // to do so, == and ++ operators should be implemented.
3808 8 : DebugMsg( "Image seeker read: %d\n", dImageSeeker );
3809 8 : imageSeeker = dImageSeeker;
3810 :
3811 8 : pFileIO->Seek( 2, CADFileIO::SeekOrigin::CUR ); // 19
3812 8 : pFileIO->Read( & dCodePage, 2 );
3813 8 : FromLSB(dCodePage);
3814 8 : oHeader.addValue( CADHeader::DWGCODEPAGE, dCodePage );
3815 :
3816 8 : DebugMsg( "DWG Code page: %d\n", dCodePage );
3817 :
3818 8 : pFileIO->Read( & SLRecordsCount, 4 ); // 21
3819 8 : FromLSB(SLRecordsCount);
3820 : // Last vertex is reached. read it and break reading.
3821 8 : DebugMsg( "Section locator records count: %d\n", SLRecordsCount );
3822 :
3823 56 : for( size_t i = 0; i < static_cast<size_t>(SLRecordsCount); ++i )
3824 : {
3825 48 : SectionLocatorRecord readRecord;
3826 48 : if( pFileIO->Read( & readRecord.byRecordNumber, 1 ) != 1 ||
3827 96 : pFileIO->Read( & readRecord.dSeeker, 4 ) != 4 ||
3828 48 : pFileIO->Read( & readRecord.dSize, 4 ) != 4 )
3829 : {
3830 0 : return CADErrorCodes::HEADER_SECTION_READ_FAILED;
3831 : }
3832 48 : FromLSB(readRecord.dSeeker);
3833 48 : FromLSB(readRecord.dSize);
3834 :
3835 48 : sectionLocatorRecords.push_back( readRecord );
3836 48 : DebugMsg( " Record #%d : %d %d\n", sectionLocatorRecords[i].byRecordNumber, sectionLocatorRecords[i].dSeeker,
3837 48 : sectionLocatorRecords[i].dSize );
3838 : }
3839 8 : if( sectionLocatorRecords.size() < 3 )
3840 0 : return CADErrorCodes::HEADER_SECTION_READ_FAILED;
3841 :
3842 8 : return CADErrorCodes::SUCCESS;
3843 : }
3844 :
3845 8 : CADDictionary DWGFileR2000::GetNOD()
3846 : {
3847 8 : CADDictionary stNOD;
3848 0 : unique_ptr<CADObject> pCADDictionaryObject( GetObject( oTables.GetTableHandle(
3849 16 : CADTables::NamedObjectsDict ).getAsLong() ) );
3850 :
3851 : CADDictionaryObject* spoNamedDictObj =
3852 8 : dynamic_cast<CADDictionaryObject*>( pCADDictionaryObject.get() );
3853 8 : if( !spoNamedDictObj )
3854 : {
3855 0 : return stNOD;
3856 : }
3857 :
3858 152 : for( size_t i = 0; i < spoNamedDictObj->sItemNames.size(); ++i )
3859 : {
3860 : unique_ptr<CADObject> spoDictRecord (
3861 144 : GetObject( spoNamedDictObj->hItemHandles[i].getAsLong() ) );
3862 :
3863 144 : if( spoDictRecord == nullptr )
3864 8 : continue; // Skip unread objects
3865 :
3866 136 : if( spoDictRecord->getType() == CADObject::DICTIONARY )
3867 : {
3868 : // TODO: add implementation of DICTIONARY reading
3869 : }
3870 24 : else if( spoDictRecord->getType() == CADObject::XRECORD )
3871 : {
3872 24 : CADXRecord * cadxRecord = new CADXRecord();
3873 : CADXRecordObject * cadxRecordObject =
3874 24 : static_cast<CADXRecordObject*>(spoDictRecord.get());
3875 :
3876 : string xRecordData( cadxRecordObject->abyDataBytes.begin(),
3877 48 : cadxRecordObject->abyDataBytes.end() );
3878 24 : cadxRecord->setRecordData( xRecordData );
3879 :
3880 24 : shared_ptr<CADDictionaryRecord> cadxRecordPtr(static_cast<CADDictionaryRecord*>(cadxRecord));
3881 :
3882 24 : stNOD.addRecord( make_pair( spoNamedDictObj->sItemNames[i], cadxRecordPtr ) );
3883 : }
3884 : }
3885 :
3886 8 : return stNOD;
3887 : }
3888 :
3889 229 : unsigned short DWGFileR2000::validateEntityCRC(CADBuffer& buffer,
3890 : unsigned int dObjectSize,
3891 : const char * entityName,
3892 : bool bSwapEndianness )
3893 : {
3894 229 : unsigned short CRC = static_cast<unsigned short>(buffer.ReadRAWSHORT());
3895 229 : if(bSwapEndianness)
3896 : {
3897 8 : SwapEndianness(CRC, sizeof (CRC));
3898 : }
3899 :
3900 229 : buffer.Seek(0, CADBuffer::BEG);
3901 229 : const unsigned short initial = 0xC0C1;
3902 : const unsigned short calculated =
3903 229 : CalculateCRC8(initial, static_cast<const char*>(buffer.GetRawBuffer()),
3904 : static_cast<int>(dObjectSize) );
3905 229 : if( CRC != calculated )
3906 : {
3907 0 : DebugMsg( "Invalid CRC for %s object\nCRC read:0x%X calculated:0x%X\n",
3908 : entityName, CRC, calculated );
3909 0 : return 0; // If CRC equal 0 - this is error
3910 : }
3911 229 : return CRC;
3912 : }
3913 :
3914 170 : bool DWGFileR2000::readBasicData(CADBaseControlObject *pBaseControlObject,
3915 : unsigned int dObjectSize,
3916 : CADBuffer &buffer)
3917 : {
3918 170 : pBaseControlObject->setSize( dObjectSize );
3919 170 : pBaseControlObject->nObjectSizeInBits = buffer.ReadRAWLONG();
3920 170 : pBaseControlObject->hObjectHandle = buffer.ReadHANDLE();
3921 170 : short dEEDSize = 0;
3922 340 : CADEed dwgEed;
3923 179 : while( ( dEEDSize = buffer.ReadBITSHORT() ) != 0 )
3924 : {
3925 9 : dwgEed.dLength = dEEDSize;
3926 9 : dwgEed.hApplication = buffer.ReadHANDLE();
3927 :
3928 9 : if(dEEDSize > 0)
3929 : {
3930 50 : for( short i = 0; i < dEEDSize; ++i )
3931 : {
3932 41 : dwgEed.acData.push_back( buffer.ReadCHAR() );
3933 : }
3934 : }
3935 :
3936 9 : pBaseControlObject->aEED.push_back( dwgEed );
3937 : }
3938 :
3939 170 : pBaseControlObject->nNumReactors = buffer.ReadBITLONG();
3940 : // TODO: Need reasonable nNumReactors limits.
3941 170 : if(pBaseControlObject->nNumReactors < 0 ||
3942 170 : pBaseControlObject->nNumReactors > 5000)
3943 : {
3944 0 : return false;
3945 : }
3946 170 : return true;
3947 : }
|