Bug Summary

File:dwgbuffer.cpp
Warning:line 520, column 29
The result of left shift is undefined because the right operand '45' is not smaller than 32, the capacity of 'int'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dwgbuffer.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/runner/work/LibreCAD/LibreCAD/libraries/libdxfrw -fcoverage-compilation-dir=/home/runner/work/LibreCAD/LibreCAD/libraries/libdxfrw -resource-dir /usr/lib/llvm-18/lib/clang/18 -D _REENTRANT -D MUPARSER_STATIC -D QT_NO_DEBUG -I . -I ../../../Qt/6.9.0/gcc_64/mkspecs/linux-g++ -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=gnu++1z -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/runner/work/LibreCAD/LibreCAD/out/2025-05-09-020939-6317-1 -x c++ src/intern/dwgbuffer.cpp
1/******************************************************************************
2** libDXFrw - Library to read/write DXF files (ascii & binary) **
3** **
4** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com **
5** **
6** This library is free software, licensed under the terms of the GNU **
7** General Public License as published by the Free Software Foundation, **
8** either version 2 of the License, or (at your option) any later version. **
9** You should have received a copy of the GNU General Public License **
10** along with this program. If not, see <http://www.gnu.org/licenses/>. **
11******************************************************************************/
12
13
14#include "dwgbuffer.h"
15#include "../libdwgr.h"
16#include "drw_textcodec.h"
17#include "drw_dbg.h"
18//#include <bitset>
19/*#include <fstream>
20#include <algorithm>
21#include <sstream>
22#include "dwgreader.h"*/
23//#include "dxfwriter.h"
24
25
26//#define FIRSTHANDLE 48
27
28/*enum sections {
29 secUnknown,
30 secHeader,
31 secTables,
32 secBlocks,
33 secEntities,
34 secObjects
35};*/
36
37static unsigned int crctable[256]= {
380x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
390xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
400xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
410x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
420xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
430x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
440x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
450xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
460xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
470x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
480x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
490xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
500x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
510xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
520xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
530x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
540xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
550x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
560x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
570xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
580x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
590xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
600xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
610x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
620x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
630x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
640x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
650x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
660x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
670x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
680x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
690x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040 };
70
71static unsigned int crc32Table[256] ={
720x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
730x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
740x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
750x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
760x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
770x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
780x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
790x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
800x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
810x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
820x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
830x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
840x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
850x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
860x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
870x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
880xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
890xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
900xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
910xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
920xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
930xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
940xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
950xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
960x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
970x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
980x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
990x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
1000xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
1010xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1020xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
1030xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
104
105union typeCast {
106 char buf[8];
107 duint16 i16;
108 duint32 i32;
109 duint64 i64;
110 ddouble64 d64;
111};
112
113bool dwgFileStream::setPos(duint64 p){
114 if (p >= sz)
115 return false;
116
117 stream->seekg(p);
118 return stream->good();
119}
120
121bool dwgFileStream::read(duint8* s, duint64 n){
122 stream->read (reinterpret_cast<char*>(s),n);
123 return stream->good();
124}
125
126bool dwgCharStream::setPos(duint64 p){
127 if (p > size()) {
128 isOk = false;
129 return false;
130 }
131
132 pos = p;
133 return true;
134}
135
136bool dwgCharStream::read(duint8* s, duint64 n){
137 if ( n > (sz - pos) ) {
138 isOk = false;
139 return false;
140 }
141 for (duint64 i=0; i<n; i++){
142 s[i]= stream[pos++];
143 }
144 return true;
145}
146
147dwgBuffer::dwgBuffer(duint8 *buf, duint64 size, DRW_TextCodec *dc)
148 :decoder{dc}
149 ,filestr{new dwgCharStream(buf, size)}
150 ,maxSize{size}
151{}
152
153dwgBuffer::dwgBuffer(std::ifstream *stream, DRW_TextCodec *dc)
154 :decoder{dc}
155 ,filestr{new dwgFileStream(stream)}
156 ,maxSize{filestr->size()}
157{}
158
159dwgBuffer::dwgBuffer( const dwgBuffer& org )
160 :decoder{org.decoder}
161 ,filestr{org.filestr->clone()}
162 ,maxSize{filestr->size()}
163 ,currByte{org.currByte}
164 ,bitPos{org.bitPos}
165{}
166
167dwgBuffer& dwgBuffer::operator=( const dwgBuffer& org ){
168 filestr.reset( org.filestr->clone());
169 decoder = org.decoder;
170 maxSize = filestr->size();
171 currByte = org.currByte;
172 bitPos = org.bitPos;
173 return *this;
174}
175
176/**Gets the current byte position in buffer **/
177duint64 dwgBuffer::getPosition() const{
178 if (bitPos != 0)
179 return filestr->getPos() -1;
180 return filestr->getPos();
181 }
182
183/**Sets the buffer position in pos byte, reset the bit position **/
184bool dwgBuffer::setPosition(duint64 pos){
185 bitPos = 0;
186/* if (pos>=maxSize)
187 return false;*/
188 return filestr->setPos(pos);
189// return true;
190}
191
192//RLZ: Fails if ... ???
193void dwgBuffer::setBitPos(duint8 pos){
194 if (pos>7)
195 return;
196 if (pos != 0 && bitPos == 0){
197 duint8 buffer;
198 filestr->read (&buffer,1);
199 currByte = buffer;
200 }
201 if (pos == 0 && bitPos != 0){//reset current byte
202 filestr->setPos(filestr->getPos()-1);
203 }
204 bitPos = pos;
205}
206
207bool dwgBuffer::moveBitPos(dint32 size){
208 if (size == 0) return true;
209
210 dint32 b= size + bitPos;
211 filestr->setPos(getPosition() + (b >> 3) );
212 bitPos = b & 7;
213
214 if (bitPos != 0){
215 filestr->read (&currByte,1);
216 }
217 return filestr->good();
218}
219
220/**Reads one Bit returns a char with value 0/1 (B) **/
221duint8 dwgBuffer::getBit(){
222 duint8 buffer;
223 duint8 ret = 0;
224 if (bitPos == 0){
225 filestr->read (&buffer,1);
226 currByte = buffer;
227 }
228
229 ret = (currByte >> (7 - bitPos) & 1);
230 bitPos +=1;
231 if (bitPos == 8)
232 bitPos = 0;
233
234 return ret;
235}
236
237/**Reads one Bit returns a bool value 0==false 1==true (B) **/
238bool dwgBuffer::getBoolBit(){
239 return (getBit() != 0);
240}
241
242/**Reads two Bits returns a char (BB) **/
243duint8 dwgBuffer::get2Bits(){
244 duint8 buffer;
245 duint8 ret = 0;
246 if (bitPos == 0){
247 filestr->read (&buffer,1);
248 currByte = buffer;
249 }
250
251 bitPos +=2;
252 if (bitPos < 9)
253 ret = currByte >>(8 - bitPos);
254 else {//read one bit per byte
255 ret = currByte << 1;
256 filestr->read (&buffer,1);
257 currByte = buffer;
258 bitPos = 1;
259 ret = ret | currByte >> 7;
260 }
261 if (bitPos == 8)
262 bitPos = 0;
263 ret = ret & 3;
264 return ret;
265}
266
267/**Reads thee Bits returns a char (3B) **/
268//RLZ: todo verify this
269duint8 dwgBuffer::get3Bits(){
270 duint8 buffer;
271 duint8 ret = 0;
272 if (bitPos == 0){
273 filestr->read (&buffer,1);
274 currByte = buffer;
275 }
276
277 bitPos +=3;
278 if (bitPos < 9)
279 ret = currByte >>(8 - bitPos);
280 else {//read one bit per byte
281 ret = currByte << 1;
282 filestr->read (&buffer,1);
283 currByte = buffer;
284 bitPos = 1;
285 ret = ret | currByte >> 7;
286 }
287 if (bitPos == 8)
288 bitPos = 0;
289 ret = ret & 7;
290 return ret;
291}
292
293/**Reads tree Bits returns a char (3B) for R24 **/
294//to be written
295
296/**Reads compressed Short (max. 16 + 2 bits) little-endian order, returns a UNsigned 16 bits (BS) **/
297duint16 dwgBuffer::getBitShort(){
298 duint8 b = get2Bits();
299 if (b == 0)
300 return getRawShort16();
301 else if (b== 1)
302 return getRawChar8();
303 else if (b == 2)
304 return 0;
305 else
306 return 256;
307}
308/**Reads compressed Short (max. 16 + 2 bits) little-endian order, returns a signed 16 bits (BS) **/
309dint16 dwgBuffer::getSBitShort(){
310 duint8 b = get2Bits();
311 if (b == 0)
312 return static_cast<dint16>(getRawShort16());
313 else if (b== 1)
314 return static_cast<dint16>(getRawChar8());
315 else if (b == 2)
316 return 0;
317 else
318 return 256;
319}
320
321/**Reads compressed 32 bits Int (max. 32 + 2 bits) little-endian order, returns a signed 32 bits (BL) **/
322//to be written
323dint32 dwgBuffer::getBitLong(){
324 dint8 b = get2Bits();
325 if (b == 0)
326 return getRawLong32();
327 else if (b== 1)
328 return getRawChar8();
329 else //if (b == 2)
330 return 0;
331}
332
333/**Reads compressed 64 bits Int (max. 56 + 3 bits) little-endian order, returns a unsigned 64 bits (BLL) **/
334duint64 dwgBuffer::getBitLongLong(){
335 dint8 b = get3Bits();
336 duint64 ret=0;
337 for (duint8 i=0; i<b; i++){
338 ret = ret << 8;
339 ret |= getRawChar8();
340 }
341 return ret;
342}
343
344/**Reads compressed Double (max. 64 + 2 bits) returns a floating point double of 64 bits (BD) **/
345double dwgBuffer::getBitDouble(){
346 dint8 b = get2Bits();
347 if (b == 1)
348 return 1.0;
349 else if (b == 0){
350 duint8 buffer[8];
351 if (bitPos != 0) {
352 for (int i = 0; i < 8; i++)
353 buffer[i] = getRawChar8();
354 } else {
355 filestr->read (buffer,8);
356 }
357 double* ret = reinterpret_cast<double*>( buffer );
358 return *ret;
359 }
360 // if (b == 2)
361 return 0.0;
362}
363
364/**Reads 3 compressed Double (max. 64 + 2 bits) returns a DRW_Coord of floating point double of 64 bits (3BD) **/
365DRW_Coord dwgBuffer::get3BitDouble(){
366 DRW_Coord crd;
367 crd.x = getBitDouble();
368 crd.y = getBitDouble();
369 crd.z = getBitDouble();
370 return crd;
371}
372
373/**Reads raw char 8 bits returns a unsigned char (RC) **/
374duint8 dwgBuffer::getRawChar8(){
375 duint8 ret=0;
376 duint8 buffer=0;
377 filestr->read (&buffer,1);
378 if (bitPos == 0)
379 return buffer;
380 else {
381 ret = currByte << bitPos;
382 currByte = buffer;
383 ret = ret | (currByte >>(8 - bitPos));
384 }
385 return ret;
386}
387
388/**Reads raw short 16 bits little-endian order, returns a unsigned short (RS) **/
389duint16 dwgBuffer::getRawShort16(){
390 duint8 buffer[2]={0,0};
391 duint16 ret=0;
392
393 filestr->read (buffer,2);
394 if (bitPos == 0) {
395 /* no offset directly swap bytes for little-endian */
396 ret = (buffer[1] << 8) | (buffer[0] & 0x00FF);
397 } else {
398 ret = (buffer[0] << 8) | (buffer[1] & 0x00FF);
399 /* apply offset */
400 ret = ret >> (8 - bitPos);
401 ret = ret | (currByte << (8 + bitPos));
402 currByte = buffer[1];
403 /* swap bytes for little-endian */
404 ret = (ret << 8) | (ret >> 8);
405 }
406 return ret;
407}
408
409/**Reads raw double IEEE standard 64 bits returns a double (RD) **/
410double dwgBuffer::getRawDouble(){
411 duint8 buffer[8];
412 memset(buffer,0,sizeof(buffer));
413 if (bitPos == 0)
414 filestr->read (buffer,8);
415 else {
416 for (int i = 0; i < 8; i++)
417 buffer[i] = getRawChar8();
418 }
419 double* nOffset = reinterpret_cast<double*>( buffer );
420 return *nOffset;
421}
422
423/**Reads 2 raw double IEEE standard 64 bits returns a DRW_Coord of floating point double 64 bits (2RD) **/
424DRW_Coord dwgBuffer::get2RawDouble(){
425 DRW_Coord crd;
426 crd.x = getRawDouble();
427 crd.y = getRawDouble();
428 return crd;
429}
430
431
432/**Reads raw int 32 bits little-endian order, returns a unsigned (RL) **/
433duint32 dwgBuffer::getRawLong32(){
434 duint16 tmp1 = getRawShort16();
435 duint16 tmp2 = getRawShort16();
436 duint32 ret = (tmp2 << 16) | (tmp1 & 0x0000FFFF);
437
438 return ret;
439}
440
441/**Reads raw int 64 bits little-endian order, returns a unsigned long long (RLL) **/
442duint64 dwgBuffer::getRawLong64(){
443 duint32 tmp1 = getRawLong32();
444 duint64 tmp2 = getRawLong32();
445 duint64 ret = (tmp2 << 32) | (tmp1 & 0x00000000FFFFFFFF);
446
447 return ret;
448}
449
450/**Reads modular unsigner int, char based, compressed form, little-endian order, returns a unsigned (U-MC) **/
451duint32 dwgBuffer::getUModularChar(){
452 std::vector<duint8> buffer;
453 duint32 result =0;
454 for (int i=0; i<4;i++){
455 duint8 b= getRawChar8();
456 buffer.push_back(b & 0x7F);
457 if (! (b & 0x80))
458 break;
459 }
460 int offset = 0;
461 for (unsigned int i=0; i<buffer.size();i++){
462 result += buffer[i] << offset;
463 offset +=7;
464 }
465//RLZ: WARNING!!! needed to verify on read handles
466 //result = result & 0x7F;
467 return result;
468}
469
470/**Reads modular int, char based, compressed form, little-endian order, returns a signed int (MC) **/
471dint32 dwgBuffer::getModularChar(){
472 bool negative = false;
473 std::vector<dint8> buffer;
474 dint32 result =0;
475 for (int i=0; i<4;i++){
476 duint8 b= getRawChar8();
477 buffer.push_back(b & 0x7F);
478 if (! (b & 0x80))
479 break;
480 }
481 dint8 b= buffer.back();
482 if (b & 0x40) {
483 negative = true;
484 buffer.pop_back();
485 buffer.push_back(b & 0x3F);
486 }
487
488 int offset = 0;
489 for (unsigned int i=0; i<buffer.size();i++){
490 result += buffer[i] << offset;
491 offset +=7;
492 }
493 if (negative)
494 result = -result;
495 return result;
496}
497
498/**Reads modular int, short based, compressed form, little-endian order, returns a unsigned (MC) **/
499dint32 dwgBuffer::getModularShort(){
500// bool negative = false;
501 std::vector<dint16> buffer;
502 dint32 result =0;
503 for (int i=0; i<2;i++){
1
Loop condition is true. Entering loop body
504 duint16 b= getRawShort16();
505 buffer.push_back(b & 0x7FFF);
506 if (! (b & 0x8000))
2
Assuming the condition is true
3
Taking true branch
507 break;
4
Execution continues on line 518
508 }
509
510 //only positive ?
511/* dint8 b= buffer.back();
512 if (! (b & 0x40)) {
513 negative = true;
514 buffer.pop_back();
515 buffer.push_back(b & 0x3F);
516 }*/
517
518 int offset = 0;
519 for (unsigned int i=0; i<buffer.size();i++){
5
Assuming the condition is true
6
Loop condition is true. Entering loop body
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
9
Assuming the condition is true
10
Loop condition is true. Entering loop body
12
Assuming the condition is true
13
Loop condition is true. Entering loop body
520 result += buffer[i] << offset;
14
The result of left shift is undefined because the right operand '45' is not smaller than 32, the capacity of 'int'
521 offset +=15;
11
The value 45 is assigned to 'offset'
522 }
523/* if (negative)
524 result = -result;*/
525 return result;
526}
527
528dwgHandle dwgBuffer::getHandle(){ //H
529 dwgHandle hl;
530 duint8 data = getRawChar8();
531 hl.code = (data >> 4) & 0x0F;
532 hl.size = data & 0x0F;
533 hl.ref=0;
534 for (int i=0; i< hl.size;i++){
535 hl.ref = (hl.ref << 8) | getRawChar8();
536 }
537 return hl;
538}
539
540dwgHandle dwgBuffer::getOffsetHandle(duint32 href){ //H
541 dwgHandle hl = getHandle();
542 if (hl.code > 5){
543 if (hl.code == 0x0C)
544 hl.ref = href - hl.ref;
545 else if (hl.code == 0x0A)
546 hl.ref = href + hl.ref;
547 else if (hl.code == 0x08)
548 hl.ref = href - 1;
549 else if (hl.code == 0x06)
550 hl.ref = href + 1;
551//all are soft pointer reference change to 7 (without offset)
552 hl.code = 7;
553 }
554 return hl;
555}
556
557//internal until 2004
558std::string dwgBuffer::get8bitStr(){
559 duint16 textSize = getBitShort();
560 if (textSize == 0)
561 return std::string();
562 duint8 *tmpBuffer = new duint8[textSize];
563 bool good = getBytes(tmpBuffer, textSize);
564 if (!good)
565 return std::string();
566
567/* filestr->read (buffer,textSize);
568 if (!filestr->good())
569 return std::string();
570
571 duint8 tmp;
572 if (bitPos != 0){
573 for (int i=0; i<textSize;i++){
574 tmp = buffer[i];
575 buffer[i] = (currByte << bitPos) | (tmp >> (8 - bitPos));
576 currByte = tmp;
577 }
578 }*/
579 std::string str(reinterpret_cast<char*>(tmpBuffer), textSize);
580 delete[]tmpBuffer;
581
582 return str;
583}
584
585//internal since 2007 //pending: are 2 bytes null terminated??
586//nullTerm = true if string are 2 bytes null terminated from the stream
587std::string dwgBuffer::get16bitStr(duint16 textSize, bool nullTerm){
588 if (textSize == 0)
589 return std::string();
590 textSize *=2;
591 duint16 ts = textSize;
592 if (nullTerm)
593 ts += 2;
594 duint8 *tmpBuffer = new duint8[textSize + 2];
595 bool good = getBytes(tmpBuffer, ts);
596 if (!good)
597 return std::string();
598 if (!nullTerm) {
599 tmpBuffer[textSize] = '\0';
600 tmpBuffer[textSize + 1] = '\0';
601 }
602 std::string str(reinterpret_cast<char*>(tmpBuffer), ts);
603 delete[]tmpBuffer;
604
605 return str;
606}
607
608//T 8 bit text converted from codepage to utf8
609std::string dwgBuffer::getCP8Text(){
610 std::string strData;
611 strData = get8bitStr();//RLZ correct these function
612 if (!decoder)
613 return strData;
614
615 return decoder->toUtf8(strData);
616}
617
618//TU unicode 16 bit (UCS) text converted to utf8
619/**Reads 2-bytes char (UCS2, NULL terminated) and convert to std::string (only for Latin-1)
620 ts= total input size in bytes.
621**/
622std::string dwgBuffer::getUCSStr(duint16 ts){
623 std::string strData;
624 if (ts<4) //at least 1 char
625 return std::string();
626 strData = get16bitStr(ts/2, false);
627 if (!decoder)
628 return strData;
629
630 return decoder->toUtf8(strData);
631}
632
633//TU unicode 16 bit (UCS) text converted to utf8
634//nullTerm = true if string are 2 bytes null terminated from the stream
635std::string dwgBuffer::getUCSText(bool nullTerm){
636 std::string strData;
637 duint16 ts = getBitShort();
638 if (ts == 0)
639 return std::string();
640
641 strData = get16bitStr(ts, nullTerm);
642 if (!decoder)
643 return strData;
644
645 return decoder->toUtf8(strData);
646}
647
648//RLZ: read a T or TU if version is 2007+
649//nullTerm = true if string are 2 bytes null terminated from the stream
650std::string dwgBuffer::getVariableText(DRW::Version v, bool nullTerm){//TV
651 if (v > DRW::AC1018)
652 return getUCSText(nullTerm);
653 return getCP8Text();
654}
655duint16 dwgBuffer::getObjType(DRW::Version v){//OT
656 if (v > DRW::AC1021) {
657 duint8 b = get2Bits();
658 if (b == 0)
659 return getRawChar8();
660 else if (b== 1){
661 return (getRawChar8() + 0x01F0);
662 } else //b == 2
663 return getRawShort16();
664 }
665 return getBitShort();
666}
667
668/* Bit Extrusion
669* For R2000+, this is a single bit, If the single bit is 1,
670* the extrusion value is assumed to be 0,0,1 and no explicit
671* extrusion is stored. If the single bit is 0, then it will
672* be followed by 3BD.
673* For R13-R14 this is 3BD.
674*/
675DRW_Coord dwgBuffer::getExtrusion(bool b_R2000_style) {
676 DRW_Coord ext(0.0,0.0,1.0);
677 if ( b_R2000_style )
678 /* If the bit is one, the extrusion value is assumed to be 0,0,1*/
679 if ( getBit() == 1 )
680 return ext;
681 /*R13-R14 or bit == 0*/
682 ext.x = getBitDouble();
683 ext.y = getBitDouble();
684 ext.z = getBitDouble();
685 return ext;
686}
687
688/**Reads compressed Double with default (max. 64 + 2 bits) returns a floating point double of 64 bits (DD) **/
689double dwgBuffer::getDefaultDouble(double d){
690 dint8 b = get2Bits();
691 if (b == 0)
692 return d;
693 else if (b == 1){
694 duint8 buffer[4];
695 char *tmp=nullptr;
696 if (bitPos != 0) {
697 for (int i = 0; i < 4; i++)
698 buffer[i] = getRawChar8();
699 } else {
700 filestr->read (buffer,4);
701 }
702 tmp = reinterpret_cast<char*>(&d);
703 for (int i = 0; i < 4; i++)
704 tmp[i] = buffer[i];
705 double ret = *reinterpret_cast<double*>( tmp );
706 return ret;
707 } else if (b == 2){
708 duint8 buffer[6];
709 char *tmp=nullptr;
710 if (bitPos != 0) {
711 for (int i = 0; i < 6; i++)
712 buffer[i] = getRawChar8();
713 } else {
714 filestr->read (buffer,6);
715 }
716 tmp = reinterpret_cast<char*>(&d);
717 for (int i = 2; i < 6; i++)
718 tmp[i-2] = buffer[i];
719 tmp[4] = buffer[0];
720 tmp[5] = buffer[1];
721 double ret = *reinterpret_cast<double*>( tmp );
722 return ret;
723 }
724 // if (b == 3) return a full raw double
725 return getRawDouble();
726}
727
728
729/* BitThickness
730* For R13-R14, this is a BD.
731* For R2000+, this is a single bit, If the bit is one,
732* the thickness value is assumed to be 0.0, if not a BD follow
733*/
734double dwgBuffer::getThickness(bool b_R2000_style) {
735 if ( b_R2000_style )
736 /* If the bit is one, the thickness value is assumed to be 0.0.*/
737 if ( getBit() == 1 )
738 return 0.0;
739 /*R13-R14 or bit == 0*/
740 return getBitDouble();
741}
742
743/* CmColor (CMC)
744* For R15 and earlier call directly BS as ACIS color.
745* For R2004+, can be CMC or ENC
746* RGB value, first 4bits 0xC0 => ByLayer, 0xC1 => ByBlock, 0xC2 => RGB, 0xC3 => last 4 are ACIS
747*/
748duint32 dwgBuffer::getCmColor(DRW::Version v) {
749 if (v < DRW::AC1018) //2000-
750 return getSBitShort();
751 duint16 idx = getBitShort();
752 duint32 rgb = getBitLong();
753 duint8 cb = getRawChar8();
754 duint8 type = rgb >> 24;
755 DRW_DBG("\ntype COLOR: ")DRW_dbg::getInstance()->print("\ntype COLOR: "); DRW_DBGH(type)DRW_dbg::getInstance()->printH(type);
756 DRW_DBG("\nindex COLOR: ")DRW_dbg::getInstance()->print("\nindex COLOR: "); DRW_DBGH(idx)DRW_dbg::getInstance()->printH(idx);
757 DRW_DBG("\nRGB COLOR: ")DRW_dbg::getInstance()->print("\nRGB COLOR: "); DRW_DBGH(rgb)DRW_dbg::getInstance()->printH(rgb);
758 DRW_DBG("\nbyte COLOR: ")DRW_dbg::getInstance()->print("\nbyte COLOR: "); DRW_DBGH(cb)DRW_dbg::getInstance()->printH(cb);
759 if (cb&1){
760 std::string colorName = getVariableText(v, false);
761 DRW_DBG("\ncolorName: ")DRW_dbg::getInstance()->print("\ncolorName: "); DRW_DBG(colorName)DRW_dbg::getInstance()->print(colorName);
762 }
763 if (cb&2){
764 std::string bookName = getVariableText(v, false);
765 DRW_DBG("\nbookName: ")DRW_dbg::getInstance()->print("\nbookName: "); DRW_DBG(bookName)DRW_dbg::getInstance()->print(bookName);
766 }
767 switch (type) {
768 case 0xC0:
769 return 256;//ByLayer
770 case 0xC1:
771 return 0;//ByBlock
772 case 0xC2:
773 return 256;//RGB RLZ TODO
774 case 0xC3:
775 return rgb&0xFF;//ACIS
776 default:
777 break;
778 }
779 //check cb if strings follows RLZ TODO
780 return 256; //default return ByLayer
781}
782
783/* EnColor (ENC)
784* For R15 and earlier call directly BS as ACIS color.
785* For R2004+, can be CMC or ENC
786* RGB value, first 4bits 0xC0 => ByLayer, 0xC1 => ByBlock, 0xC2 => RGB, 0xC3 => last 4 are ACIS
787*/
788duint32 dwgBuffer::getEnColor(DRW::Version v) {
789 if (v < DRW::AC1018) //2000-
790 return getSBitShort();
791 duint32 rgb = 0;
792 duint32 cb = 0;
793 duint16 idx = getBitShort();
794 DRW_DBG("idx reads COLOR: ")DRW_dbg::getInstance()->print("idx reads COLOR: "); DRW_DBGH(idx)DRW_dbg::getInstance()->printH(idx);
795 duint16 flags = idx>>8;
796 idx = idx & 0x1FF; //RLZ: warning this is correct?
797 DRW_DBG("\nflag COLOR: ")DRW_dbg::getInstance()->print("\nflag COLOR: "); DRW_DBGH(flags)DRW_dbg::getInstance()->printH(flags);
798 DRW_DBG(", index COLOR: ")DRW_dbg::getInstance()->print(", index COLOR: "); DRW_DBGH(idx)DRW_dbg::getInstance()->printH(idx);
799// if (flags & 0x80) {
800// rgb = getBitLong();
801// DRW_DBG("\nRGB COLOR: "); DRW_DBGH(rgb);
802// }
803 if (flags & 0x20) {
804 cb = getBitLong();
805 DRW_DBG("\nTransparency COLOR: ")DRW_dbg::getInstance()->print("\nTransparency COLOR: "); DRW_DBGH(cb)DRW_dbg::getInstance()->printH(cb);
806 }
807 if (flags & 0x40)
808 DRW_DBG("\nacdbColor COLOR are present")DRW_dbg::getInstance()->print("\nacdbColor COLOR are present"
)
;
809 else {
810 if (flags & 0x80) {
811 rgb = getBitLong();
812 DRW_DBG("\nRGB COLOR: ")DRW_dbg::getInstance()->print("\nRGB COLOR: "); DRW_DBGH(rgb)DRW_dbg::getInstance()->printH(rgb);
813 }
814 }
815
816/* if (flags & 0x80)
817 return getBitLong();*/
818
819 return idx; //default return ByLayer
820}
821
822
823/**Reads raw short 16 bits big-endian order, returns a unsigned short crc & size **/
824duint16 dwgBuffer::getBERawShort16(){
825 char buffer[2];
826 buffer[0] = getRawChar8();
827 buffer[1] = getRawChar8();
828 duint16 size = (buffer[0] << 8) | (buffer[1] & 0xFF);
829 return size;
830}
831
832/* reads "size" bytes and stores in "buf" return false if fail */
833bool dwgBuffer::getBytes(unsigned char *buf, duint64 size){
834 duint8 tmp;
835 filestr->read (buf,size);
836 if (!filestr->good())
837 return false;
838
839 if (bitPos != 0){
840 for (duint64 i=0; i<size;i++){
841 tmp = buf[i];
842 buf[i] = (currByte << bitPos) | (tmp >> (8 - bitPos));
843 currByte = tmp;
844 }
845 }
846 return true;
847}
848
849duint16 dwgBuffer::crc8(duint16 dx,dint32 start,dint32 end){
850 duint64 pos = filestr->getPos();
851 filestr->setPos(start);
852 int n = end-start;
853 duint8 *tmpBuf = new duint8[n];
854 duint8 *p = tmpBuf;
855 filestr->read (tmpBuf,n);
856 filestr->setPos(pos);
857 if (!filestr->good())
858 return 0;
859
860 duint8 al;
861
862 while (n-- > 0) {
863 al = (duint8)((*p) ^ ((dint8)(dx & 0xFF)));
864 dx = (dx>>8) & 0xFF;
865 dx = dx ^ crctable[al & 0xFF];
866 p++;
867 }
868 delete[]tmpBuf;
869 return(dx);
870}
871
872duint32 dwgBuffer::crc32(duint32 seed,dint32 start,dint32 end){
873 duint64 pos = filestr->getPos();
874 filestr->setPos(start);
875 int n = end-start;
876 duint8 *tmpBuf = new duint8[n];
877 duint8 *p = tmpBuf;
878 filestr->read (tmpBuf,n);
879 filestr->setPos(pos);
880 if (!filestr->good())
881 return 0;
882
883 duint32 invertedCrc = ~seed;
884 while (n-- > 0) {
885 duint8 data = *p++;
886 invertedCrc = (invertedCrc >> 8) ^ crc32Table[(invertedCrc ^ data) & 0xff];
887 }
888 delete[]tmpBuf;
889 return ~invertedCrc;
890}
891
892
893/*std::string dwgBuffer::getBytes(int size){
894 char buffer[size];
895 char tmp;
896 filestr->read (buffer,size);
897 if (!filestr->good())
898 return NULL;
899
900 if (bitPos != 0){
901 for (int i=0; i<=size;i++){
902 tmp = buffer[i];
903 buffer[i] = (currByte << bitPos) | (tmp >> (8 - bitPos));
904 currByte = tmp;
905 }
906 }
907 std::string st;
908 for (int i=0; i<size;i++) {
909 st.push_back(buffer[i]);
910 }
911 return st;
912// return std::string(buffer);
913}*/
914