glc_bsrep.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021  *****************************************************************************/
00023 
00024 #include "glc_bsrep.h"
00025 #include "../glc_fileformatexception.h"
00026 #include "../glc_tracelog.h"
00027 
00028 // The binary rep suffix
00029 const QString GLC_BSRep::m_Suffix("BSRep");
00030 
00031 // The binary rep magic number
00032 const QUuid GLC_BSRep::m_Uuid("{d6f97789-36a9-4c2e-b667-0e66c27f839f}");
00033 
00034 // The binary rep version
00035 const quint32 GLC_BSRep::m_Version= 103;
00036 
00037 // Mutex used by compression
00038 QMutex GLC_BSRep::m_CompressionMutex;
00039 
00040 // Default constructor
00041 GLC_BSRep::GLC_BSRep(const QString& fileName, bool useCompression)
00042 : m_FileInfo()
00043 , m_pFile(NULL)
00044 , m_DataStream()
00045 , m_UseCompression(useCompression)
00046 , m_CompressionLevel(-1)
00047 {
00048         setAbsoluteFileName(fileName);
00049         m_DataStream.setVersion(QDataStream::Qt_4_6);
00050         m_DataStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
00051 }
00052 
00053 // Copy constructor
00054 GLC_BSRep::GLC_BSRep(const GLC_BSRep& binaryRep)
00055 : m_FileInfo(binaryRep.m_FileInfo)
00056 , m_pFile(NULL)
00057 , m_DataStream()
00058 , m_UseCompression(binaryRep.m_UseCompression)
00059 , m_CompressionLevel(binaryRep.m_CompressionLevel)
00060 {
00061         m_DataStream.setVersion(QDataStream::Qt_4_6);
00062         m_DataStream.setFloatingPointPrecision(binaryRep.m_DataStream.floatingPointPrecision());
00063 }
00064 
00065 GLC_BSRep::~GLC_BSRep()
00066 {
00067         delete m_pFile;
00068 }
00069 
00070 // Return true if the binary rep is up to date
00071 bool GLC_BSRep::isUsable(const QDateTime& timeStamp)
00072 {
00073         bool isUpToDate= false;
00074         if (open(QIODevice::ReadOnly))
00075         {
00076                 if (headerIsOk())
00077                 {
00078                         isUpToDate= timeStampOk(timeStamp);
00079                         isUpToDate= isUpToDate && close();
00080                 }
00081         }
00082         else
00083         {
00084                 QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
00085                 GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
00086                 close();
00087                 throw(fileFormatException);
00088         }
00089 
00090         if (!isUpToDate && GLC_TraceLog::isEnable())
00091         {
00092                 QStringList stringList("GLC_BSRep::isUsable");
00093                 stringList.append("File " + m_FileInfo.filePath() + " not Usable");
00094                 GLC_TraceLog::addTrace(stringList);
00095         }
00096         return isUpToDate;
00097 }
00098 
00100 // name Get Functions
00102 // Load the binary rep
00103 GLC_3DRep GLC_BSRep::loadRep()
00104 {
00105         GLC_3DRep loadedRep;
00106 
00107         if (open(QIODevice::ReadOnly))
00108         {
00109                 if (headerIsOk())
00110                 {
00111                         timeStampOk(QDateTime());
00112                         GLC_BoundingBox boundingBox;
00113                         m_DataStream >> boundingBox;
00114                         bool useCompression;
00115                         m_DataStream >> useCompression;
00116                         if (useCompression)
00117                         {
00118                                 QByteArray CompresseBuffer;
00119                                 m_DataStream >> CompresseBuffer;
00120                                 QByteArray uncompressedBuffer= qUncompress(CompresseBuffer);
00121                                 uncompressedBuffer.squeeze();
00122                                 CompresseBuffer.clear();
00123                                 CompresseBuffer.squeeze();
00124                                 QDataStream bufferStream(uncompressedBuffer);
00125                                 bufferStream >> loadedRep;
00126                         }
00127                         else
00128                         {
00129                                 m_DataStream >> loadedRep;
00130                         }
00131                         loadedRep.setFileName(m_FileInfo.filePath());
00132 
00133                         if (!close())
00134                         {
00135                                 QString message(QString("GLC_BSRep::loadRep An error occur when loading file ") + m_FileInfo.fileName());
00136                                 GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::WrongFileFormat);
00137                                 throw(fileFormatException);
00138                         }
00139                 }
00140                 else
00141                 {
00142                         QString message(QString("GLC_BSRep::loadRep File not supported ") + m_FileInfo.fileName());
00143                         GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotSupported);
00144                         close();
00145                         throw(fileFormatException);
00146                 }
00147         }
00148         else
00149         {
00150                 QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
00151                 GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
00152                 close();
00153                 throw(fileFormatException);
00154         }
00155 
00156 
00157         return loadedRep;
00158 }
00159 
00160 // Return the bounding box of the binary representation
00161 GLC_BoundingBox GLC_BSRep::boundingBox()
00162 {
00163         GLC_BoundingBox boundingBox;
00164 
00165         if (open(QIODevice::ReadOnly))
00166         {
00167                 if (headerIsOk())
00168                 {
00169                         timeStampOk(QDateTime());
00170 
00171                         m_DataStream >> boundingBox;
00172                 }
00173                 close();
00174         }
00175         return boundingBox;
00176 }
00177 
00178 // Return bsrep suffix
00179 QString GLC_BSRep::suffix()
00180 {
00181         return m_Suffix;
00182 }
00183 
00184 quint32 GLC_BSRep::version()
00185 {
00186         return m_Version;
00187 }
00188 
00190 //name Set Functions
00192 // Set the binary representation file name
00193 void GLC_BSRep::setAbsoluteFileName(const QString& fileName)
00194 {
00195         m_FileInfo.setFile(fileName);
00196         if (m_FileInfo.suffix() != m_Suffix)
00197         {
00198                 m_FileInfo.setFile(fileName + '.' + m_Suffix);
00199         }
00200 
00201 }
00202 
00203 // Save the GLC_3DRep in serialised binary
00204 bool GLC_BSRep::save(const GLC_3DRep& rep)
00205 {
00206 
00208         bool saveOk= open(QIODevice::WriteOnly);
00209         if (saveOk)
00210         {
00211                 writeHeader(rep.lastModified());
00212 
00213                 // Representation Bounding Box
00214                 m_DataStream << rep.boundingBox();
00215 
00216                 // Compression usage
00217 
00218                 if (m_UseCompression && (rep.faceCount() < 1000000))
00219                 {
00220                         m_DataStream << true;
00221                         QByteArray uncompressedBuffer;
00222                         {
00223                                 QBuffer buffer(&uncompressedBuffer);
00224                                 buffer.open(QIODevice::WriteOnly);
00225                                 QDataStream bufferStream(&buffer);
00226                                 bufferStream << rep;
00227                         }
00228                         m_DataStream << qCompress(uncompressedBuffer, m_CompressionLevel);
00229                 }
00230                 else
00231                 {
00232                         m_DataStream << false;
00233                         // Binary representation geometry
00234                         // Add the rep
00235                         m_DataStream << rep;
00236                 }
00237 
00238                 // Flag the file
00239                 qint64 offset= sizeof(QUuid);
00240                 offset+= sizeof(quint32);
00241 
00242                 m_pFile->seek(offset);
00243                 bool writeOk= true;
00244                 m_DataStream << writeOk;
00245                 // Close the file
00246                 saveOk= close();
00247         }
00248         return saveOk;
00249 }
00250 
00251 
00252 // Open the file
00253 bool GLC_BSRep::open(QIODevice::OpenMode mode)
00254 {
00255         bool openOk= m_FileInfo.exists();
00256         if (openOk || (mode == QIODevice::WriteOnly))
00257         {
00258                 m_DataStream.setDevice(NULL);
00259                 delete m_pFile;
00260                 m_pFile= new QFile(m_FileInfo.filePath());
00261                 openOk= m_pFile->open(mode);
00262                 if (openOk)
00263                 {
00264                         m_DataStream.setDevice(m_pFile);
00265                 }
00266         }
00267         else if (GLC_TraceLog::isEnable())
00268         {
00269                 QStringList stringList("GLC_BSRep::open");
00270                 stringList.append("File " + m_FileInfo.filePath() + " doesn't exists");
00271                 GLC_TraceLog::addTrace(stringList);
00272         }
00273 
00274         return openOk;
00275 }
00276 
00277 // Close the file
00278 bool GLC_BSRep::close()
00279 {
00280         Q_ASSERT(m_pFile != NULL);
00281         Q_ASSERT(m_DataStream.device() != NULL);
00282         bool closeOk= m_DataStream.status() == QDataStream::Ok;
00283         m_DataStream.setDevice(NULL);
00284         m_pFile->close();
00285         delete m_pFile;
00286         m_pFile= NULL;
00287 
00288         return closeOk;
00289 }
00290 
00291 // Write the header
00292 void GLC_BSRep::writeHeader(const QDateTime& dateTime)
00293 {
00294         Q_ASSERT(m_pFile != NULL);
00295         Q_ASSERT(m_DataStream.device() != NULL);
00296 
00297         // Binary representation Header
00298         // Add the magic number
00299         m_DataStream << m_Uuid;
00300         // Add the version
00301         m_DataStream << m_Version;
00302         bool writeFinished= false;
00303         m_DataStream << writeFinished;
00304 
00305         // Set the version of the data stream
00306         m_DataStream.setVersion(QDataStream::Qt_4_6);
00307 
00308         // Add the time stamp
00309         m_DataStream << dateTime;
00310 }
00311 
00312 // Check the header
00313 bool GLC_BSRep::headerIsOk()
00314 {
00315         Q_ASSERT(m_pFile != NULL);
00316         Q_ASSERT(m_DataStream.device() != NULL);
00317         Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);
00318 
00319         QUuid uuid;
00320         quint32 version;
00321         bool writeFinished;
00322 
00323         m_DataStream >> uuid;
00324         m_DataStream >> version;
00325         m_DataStream >> writeFinished;
00326 
00327         // Set the version of the data stream
00328         m_DataStream.setVersion(QDataStream::Qt_4_6);
00329 
00330         bool headerOk= (uuid == m_Uuid) && (version <= m_Version) && (version > 101) && writeFinished;
00331 
00332         return headerOk;
00333 }
00334 
00335 // Check the time Stamp
00336 bool GLC_BSRep::timeStampOk(const QDateTime& timeStamp)
00337 {
00338         Q_ASSERT(m_pFile != NULL);
00339         Q_ASSERT(m_DataStream.device() != NULL);
00340         Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);
00341 
00342         QDateTime dateTime;
00343         m_DataStream >> dateTime;
00344 
00345         bool timeStampOk= !timeStamp.isValid() || (dateTime == timeStamp);
00346         return timeStampOk;
00347 }
00348 

SourceForge.net Logo

©2005-2011 Laurent Ribon