/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see . **
******************************************************************************/
#include
#include
#include
#include
#include
#include "dwgreader15.h"
#include "drw_textcodec.h"
#include "../libdwgr.h"
#include "qgslogger.h"
bool dwgReader15::readMetaData()
{
QgsDebugMsg( "Entering." );
version = parent->getVersion();
decoder.setVersion( version, false );
if ( ! fileBuf->setPosition( 13 ) )
return false;
previewImagePos = fileBuf->getRawLong32();
QgsDebugMsg( QString( "previewImagePos (seekerImageData) = %1" ).arg( previewImagePos ) );
/* MEASUREMENT system variable 2 bytes*/
duint16 meas = fileBuf->getRawShort16();
QgsDebugMsg( QString( "MEASUREMENT (0 = English, 1 = Metric)= %1" ).arg( meas ) );
Q_UNUSED( meas );
duint16 cp = fileBuf->getRawShort16();
QgsDebugMsg( QString( "codepage= %1" ).arg( cp ) );
if ( cp == 29 ) //TODO RLZ: locate wath code page and correct this
decoder.setCodePage( "ANSI_1252", false );
if ( cp == 30 )
decoder.setCodePage( "ANSI_1252", false );
return true;
}
bool dwgReader15::readFileHeader()
{
QgsDebugMsg( "Entering." );
bool ret = true;
if ( ! fileBuf->setPosition( 21 ) )
return false;
duint32 count = fileBuf->getRawLong32();
QgsDebugMsg( QString( "count records=%1" ).arg( count ) );
for ( unsigned int i = 0; i < count; i++ )
{
duint8 rec = fileBuf->getRawChar8();
duint32 address = fileBuf->getRawLong32();
duint32 size = fileBuf->getRawLong32();
dwgSectionInfo si;
si.Id = rec;
si.size = size;
si.address = address;
if ( rec == 0 )
{
QgsDebugMsg( QString( "Section HEADERS address=%1 size=%2" ).arg( address ).arg( size ) );
sections[secEnum::HEADER] = si;
}
else if ( rec == 1 )
{
QgsDebugMsg( QString( "Section CLASSES address=%1 size=%2" ).arg( address ).arg( size ) );
sections[secEnum::CLASSES] = si;
}
else if ( rec == 2 )
{
QgsDebugMsg( QString( "Section OBJECTS (handles) address=%1 size=%2" ).arg( address ).arg( size ) );
sections[secEnum::HANDLES] = si;
}
else if ( rec == 3 )
{
QgsDebugMsg( QString( "Section UNKNOWN address=%1 size=%2" ).arg( address ).arg( size ) );
sections[secEnum::UNKNOWNS] = si;
}
else if ( rec == 4 )
{
QgsDebugMsg( QString( "Section R14DATA (AcDb::Template) address=%1 size=%2" ).arg( address ).arg( size ) );
sections[secEnum::TEMPLATE] = si;
}
else if ( rec == 5 )
{
QgsDebugMsg( QString( "Section R14REC5 (AcDb::AuxHeader) address=%1 size=%2" ).arg( address ).arg( size ) );
sections[secEnum::AUXHEADER] = si;
}
else
{
std::cerr << "\nUnsupported section number\n";
}
}
if ( ! fileBuf->isGood() )
return false;
QgsDebugMsg( QString( "position after read section locator records=%1, bit are=%2" ).arg( fileBuf->getPosition() ).arg( fileBuf->getBitPos() ) );
duint32 ckcrc = fileBuf->crc8( 0, 0, fileBuf->getPosition() );
QgsDebugMsg( QString( "file header crc8 0 result=%1" ).arg( ckcrc ) );
switch ( count )
{
case 3:
ckcrc = ckcrc ^ 0xA598;
break;
case 4:
ckcrc = ckcrc ^ 0x8101;
break;
case 5:
ckcrc = ckcrc ^ 0x3CC4;
break;
case 6:
ckcrc = ckcrc ^ 0x8461;
}
int headercrc = fileBuf->getRawShort16();
QgsDebugMsg( QString( "file header crc8 xor result=%1, file header CRC=%2" ).arg( ckcrc ).arg( headercrc ) );
Q_UNUSED( headercrc );
checkSentinel( fileBuf, secEnum::FILEHEADER, false );
QgsDebugMsg( QString( "position after read file header sentinel=%1, bit pos=%2" ).arg( fileBuf->getPosition() ).arg( fileBuf->getBitPos() ) );
QgsDebugMsg( "Leaving." );
return ret;
}
bool dwgReader15::readDwgHeader( DRW_Header &hdr )
{
QgsDebugMsg( "Entering." );
dwgSectionInfo si = sections[secEnum::HEADER];
if ( si.Id < 0 )//not found, ends
return false;
if ( !fileBuf->setPosition( si.address ) )
return false;
duint8 *tmpByteStr = new duint8[si.size];
fileBuf->getBytes( tmpByteStr, si.size );
dwgBuffer buff( tmpByteStr, si.size, &decoder );
QgsDebugMsg( "checksentinel" );
checkSentinel( &buff, secEnum::HEADER, true );
bool ret = dwgReader::readDwgHeader( hdr, &buff, &buff );
delete[]tmpByteStr;
return ret;
}
bool dwgReader15::readDwgClasses()
{
QgsDebugMsg( "Entering." );
dwgSectionInfo si = sections[secEnum::CLASSES];
if ( si.Id < 0 )//not found, ends
return false;
if ( !fileBuf->setPosition( si.address ) )
return false;
QgsDebugMsg( "classes section sentinel" );
checkSentinel( fileBuf, secEnum::CLASSES, true );
duint32 size = fileBuf->getRawLong32();
if ( size != ( si.size - 38 ) )
{
QgsDebugMsg( QString( "size is %1 and secSize - 38 are %1" ).arg( size ).arg( si.size - 38 ) );
}
duint8 *tmpByteStr = new duint8[size];
fileBuf->getBytes( tmpByteStr, size );
dwgBuffer buff( tmpByteStr, size, &decoder );
size--; //reduce 1 byte instead of check pos + bitPos
while ( size > buff.getPosition() )
{
DRW_Class *cl = new DRW_Class();
cl->parseDwg( version, &buff, &buff );
classesmap[cl->classNum] = cl;
}
int crc = fileBuf->getRawShort16();
QgsDebugMsg( QString( "crc=%1, classes section end sentinel" ).arg( crc ) );
Q_UNUSED( crc );
checkSentinel( fileBuf, secEnum::CLASSES, false );
bool ret = buff.isGood();
delete[]tmpByteStr;
return ret;
}
bool dwgReader15::readDwgHandles()
{
QgsDebugMsg( "Entering." );
dwgSectionInfo si = sections[secEnum::HANDLES];
if ( si.Id < 0 )//not found, ends
return false;
bool ret = dwgReader::readDwgHandles( fileBuf, si.address, si.size );
return ret;
}
/*********** objects ************************/
/**
* Reads all the object referenced in the object map section of the DWG file
* (using their object file offsets)
*/
bool dwgReader15::readDwgTables( DRW_Header &hdr )
{
bool ret = dwgReader::readDwgTables( hdr, fileBuf );
return ret;
}
/**
* Reads all the object referenced in the object map section of the DWG file
* (using their object file offsets)
*/
bool dwgReader15::readDwgBlocks( DRW_Interface &intfa )
{
bool ret = true;
ret = dwgReader::readDwgBlocks( intfa, fileBuf );
return ret;
}