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= 103;
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
00184 quint32 GLC_BSRep::version()
00185 {
00186 return m_Version;
00187 }
00188
00190
00192
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
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
00214 m_DataStream << rep.boundingBox();
00215
00216
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
00234
00235 m_DataStream << rep;
00236 }
00237
00238
00239 qint64 offset= sizeof(QUuid);
00240 offset+= sizeof(quint32);
00241
00242 m_pFile->seek(offset);
00243 bool writeOk= true;
00244 m_DataStream << writeOk;
00245
00246 saveOk= close();
00247 }
00248 return saveOk;
00249 }
00250
00251
00252
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
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
00292 void GLC_BSRep::writeHeader(const QDateTime& dateTime)
00293 {
00294 Q_ASSERT(m_pFile != NULL);
00295 Q_ASSERT(m_DataStream.device() != NULL);
00296
00297
00298
00299 m_DataStream << m_Uuid;
00300
00301 m_DataStream << m_Version;
00302 bool writeFinished= false;
00303 m_DataStream << writeFinished;
00304
00305
00306 m_DataStream.setVersion(QDataStream::Qt_4_6);
00307
00308
00309 m_DataStream << dateTime;
00310 }
00311
00312
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
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
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