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