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