glc_bsrep.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00024 #include "glc_bsrep.h"
00025 #include "../glc_fileformatexception.h"
00026 #include "../glc_tracelog.h"
00027
00028
00029 const QString GLC_BSRep::m_Suffix("BSRep");
00030
00031
00032 const QUuid GLC_BSRep::m_Uuid("{d6f97789-36a9-4c2e-b667-0e66c27f839f}");
00033
00034
00035 const quint32 GLC_BSRep::m_Version= 102;
00036
00037
00038 QMutex GLC_BSRep::m_CompressionMutex;
00039
00040
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
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
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
00102
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
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
00179 QString GLC_BSRep::suffix()
00180 {
00181 return m_Suffix;
00182 }
00183
00185
00187
00188 void GLC_BSRep::setAbsoluteFileName(const QString& fileName)
00189 {
00190 m_FileInfo.setFile(fileName);
00191 if (m_FileInfo.suffix() != m_Suffix)
00192 {
00193 m_FileInfo.setFile(fileName + '.' + m_Suffix);
00194 }
00195
00196 }
00197
00198
00199 bool GLC_BSRep::save(const GLC_3DRep& rep)
00200 {
00201
00203 bool saveOk= open(QIODevice::WriteOnly);
00204 if (saveOk)
00205 {
00206 writeHeader(rep.lastModified());
00207
00208
00209 m_DataStream << rep.boundingBox();
00210
00211
00212
00213 if (m_UseCompression && (rep.faceCount() < 1000000))
00214 {
00215 m_DataStream << true;
00216 QByteArray uncompressedBuffer;
00217 {
00218 QBuffer buffer(&uncompressedBuffer);
00219 buffer.open(QIODevice::WriteOnly);
00220 QDataStream bufferStream(&buffer);
00221 bufferStream << rep;
00222 }
00223 m_DataStream << qCompress(uncompressedBuffer, m_CompressionLevel);
00224 }
00225 else
00226 {
00227 m_DataStream << false;
00228
00229
00230 m_DataStream << rep;
00231 }
00232
00233
00234 qint64 offset= sizeof(QUuid);
00235 offset+= sizeof(quint32);
00236
00237 m_pFile->seek(offset);
00238 bool writeOk= true;
00239 m_DataStream << writeOk;
00240
00241 saveOk= close();
00242 }
00243 return saveOk;
00244 }
00245
00246
00247
00248 bool GLC_BSRep::open(QIODevice::OpenMode mode)
00249 {
00250 bool openOk= m_FileInfo.exists();
00251 if (openOk || (mode == QIODevice::WriteOnly))
00252 {
00253 m_DataStream.setDevice(NULL);
00254 delete m_pFile;
00255 m_pFile= new QFile(m_FileInfo.filePath());
00256 openOk= m_pFile->open(mode);
00257 if (openOk)
00258 {
00259 m_DataStream.setDevice(m_pFile);
00260 }
00261 }
00262 else if (GLC_TraceLog::isEnable())
00263 {
00264 QStringList stringList("GLC_BSRep::open");
00265 stringList.append("File " + m_FileInfo.filePath() + " doesn't exists");
00266 GLC_TraceLog::addTrace(stringList);
00267 }
00268
00269 return openOk;
00270 }
00271
00272
00273 bool GLC_BSRep::close()
00274 {
00275 Q_ASSERT(m_pFile != NULL);
00276 Q_ASSERT(m_DataStream.device() != NULL);
00277 bool closeOk= m_DataStream.status() == QDataStream::Ok;
00278 m_DataStream.setDevice(NULL);
00279 m_pFile->close();
00280 delete m_pFile;
00281 m_pFile= NULL;
00282
00283 return closeOk;
00284 }
00285
00286
00287 void GLC_BSRep::writeHeader(const QDateTime& dateTime)
00288 {
00289 Q_ASSERT(m_pFile != NULL);
00290 Q_ASSERT(m_DataStream.device() != NULL);
00291
00292
00293
00294 m_DataStream << m_Uuid;
00295
00296 m_DataStream << m_Version;
00297 bool writeFinished= false;
00298 m_DataStream << writeFinished;
00299
00300
00301 m_DataStream.setVersion(QDataStream::Qt_4_6);
00302
00303
00304 m_DataStream << dateTime;
00305 }
00306
00307
00308 bool GLC_BSRep::headerIsOk()
00309 {
00310 Q_ASSERT(m_pFile != NULL);
00311 Q_ASSERT(m_DataStream.device() != NULL);
00312 Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);
00313
00314 QUuid uuid;
00315 quint32 version;
00316 bool writeFinished;
00317
00318 m_DataStream >> uuid;
00319 m_DataStream >> version;
00320 m_DataStream >> writeFinished;
00321
00322
00323 m_DataStream.setVersion(QDataStream::Qt_4_6);
00324
00325 bool headerOk= (uuid == m_Uuid) && (version == m_Version) && writeFinished;
00326
00327 return headerOk;
00328 }
00329
00330
00331 bool GLC_BSRep::timeStampOk(const QDateTime& timeStamp)
00332 {
00333 Q_ASSERT(m_pFile != NULL);
00334 Q_ASSERT(m_DataStream.device() != NULL);
00335 Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);
00336
00337 QDateTime dateTime;
00338 m_DataStream >> dateTime;
00339
00340 bool timeStampOk= !timeStamp.isValid() || (dateTime == timeStamp);
00341 return timeStampOk;
00342 }
00343