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