SilentEye 0.4.1
|
00001 // This file is part of SilentEye. 00002 // 00003 // SilentEye is free software: you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation, either version 3 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // SilentEye is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with SilentEye. If not, see <http://www.gnu.org/licenses/>. 00015 00016 #include <math.h> 00017 00018 #include "encodeddata.h" 00019 #include "silenteyeexception.h" 00020 00021 namespace SilentEyeFramework { 00022 00024 00029 EncodedData::EncodedData(Data::DataFormat format, bool compress) 00030 : _compressed(compress) 00031 { 00032 _swap = 2; 00033 _andOperator = andOperator(_swap); 00034 _arrayCount = 0; 00035 _bitCount = 0; 00036 _car = 0; 00037 _buffer.clear(); 00038 _data = new Data(format); 00039 _partialData = true; 00040 } 00041 00043 00048 EncodedData::EncodedData(const QByteArray bytes, Data::DataFormat format, bool compress) 00049 : _compressed(compress) 00050 { 00051 _swap = 2; 00052 _andOperator = andOperator(_swap); 00053 _arrayCount = 0; 00054 _bitCount = 0; 00055 _car = 0; 00056 if(format == Data::F_UNDEF) { 00057 _data = new Data(bytes, format); 00058 } else { 00059 _data = new Data(format, bytes); 00060 if (compress) 00061 _buffer = qCompress(_data->toByteArray(), 9); 00062 else 00063 _buffer = _data->toByteArray(); 00064 } 00065 00066 _partialData = false; 00067 } 00068 00070 00074 EncodedData::EncodedData(const quint32 value, bool compress) 00075 : _compressed(compress) 00076 { 00077 _swap = 2; 00078 _andOperator = andOperator(_swap); 00079 _arrayCount = 0; 00080 _bitCount = 0; 00081 _car = 0; 00082 00083 for(int i=0; i<=24; i+=8) 00084 { 00085 uchar car = (char)((value >> i)&255); 00086 _buffer.append(car); 00087 } 00088 00089 _data = new Data(Data::UINT32, _buffer); 00090 if (compress) 00091 _buffer = qCompress(_data->toByteArray(), 9); 00092 else 00093 _buffer = _data->toByteArray(); 00094 00095 _partialData = false; 00096 } 00097 00099 00104 EncodedData::EncodedData(const QString& str, Data::DataFormat format, bool compress) 00105 : _compressed(compress) 00106 { 00107 _swap = 2; 00108 _andOperator = andOperator(_swap); 00109 _arrayCount = 0; 00110 _bitCount = 0; 00111 _car = 0; 00112 00113 if(format == Data::UTF8) 00114 _data = new Data(format, str.toUtf8()); 00115 else if(format == Data::LATIN1) 00116 _data = new Data(format, str.toLatin1()); 00117 else 00118 _data = new Data(format, str.toAscii()); 00119 00120 00121 if (compress) 00122 _buffer = qCompress(_data->toByteArray(), 9); 00123 else 00124 _buffer = _data->toByteArray(); 00125 00126 _partialData = false; 00127 } 00128 00130 00134 EncodedData::EncodedData(QFile& file, bool compress) 00135 : _compressed(compress) 00136 { 00137 _swap = 2; 00138 _andOperator = andOperator(_swap); 00139 _arrayCount = 0; 00140 _bitCount = 0; 00141 _car = 0; 00142 file.open(QFile::ReadOnly); 00143 _buffer = file.readAll(); 00144 file.close(); 00145 00146 QString filePath = file.fileName(); 00147 _data = new Data(Data::FILE, _buffer, QDir::fromNativeSeparators(filePath).section("/", -1, -1)); 00148 if (compress) 00149 _buffer = qCompress(_data->toByteArray(), 9); 00150 else 00151 _buffer = _data->toByteArray(); 00152 00153 _partialData = false; 00154 } 00155 00157 EncodedData::~EncodedData() 00158 { 00159 if (!_data.isNull()) 00160 delete _data; 00161 } 00162 00164 void EncodedData::checkPartialData() 00165 { 00166 if(_partialData) 00167 { 00168 if (_compressed) 00169 _data = new Data(qUncompress(_buffer), _data->format()); 00170 else 00171 _data = new Data(_buffer, _data->format()); 00172 00173 _partialData = false; 00174 } 00175 } 00176 00178 00179 Data::DataFormat EncodedData::format() 00180 { 00181 checkPartialData(); 00182 return _data->format(); 00183 } 00184 00186 00187 bool EncodedData::isCompressed() const 00188 { 00189 return _compressed; 00190 } 00191 00193 00197 void EncodedData::setCompressed(const bool compress, const bool force) 00198 { 00199 if(force) 00200 { 00201 if(!_compressed && compress) 00202 { 00203 _buffer = qCompress(_buffer, 9); 00204 } 00205 else if(_compressed && !compress) 00206 { 00207 _buffer = qUncompress(_buffer); 00208 } 00209 } 00210 _compressed = compress; 00211 00212 } 00213 00215 00216 QByteArray EncodedData::bytes() 00217 { 00218 return _buffer; 00219 } 00220 00222 00223 quint32 EncodedData::size() const 00224 { 00225 return _buffer.size(); 00226 } 00227 00229 void EncodedData::clear() 00230 { 00231 _arrayCount = 0; 00232 _bitCount = 0; 00233 _car = 0; 00234 _buffer.clear(); 00235 Data::DataFormat format = Data::F_UNDEF; 00236 if(!_data.isNull()) 00237 { 00238 // format = _data->format(); 00239 delete _data; 00240 } 00241 _data = new Data(format); 00242 } 00243 00245 00246 void EncodedData::initialize(unsigned short int nbBits) 00247 { 00248 _swap = nbBits; 00249 _andOperator = andOperator(_swap); 00250 _arrayCount = 0; 00251 _bitCount = 0; 00252 if(_buffer.size()>0) 00253 _car = _buffer.at(0); 00254 } 00255 00257 00258 bool EncodedData::hasNext() 00259 { 00260 if(_buffer.size() == 0) 00261 return false; 00262 else 00263 return (_arrayCount < (unsigned int)_buffer.size()); 00264 } 00265 00267 00271 int EncodedData::read() 00272 { 00273 int val = 0; 00274 if(hasNext()) 00275 { 00276 int bitsLeft = 8 - _bitCount; 00277 if(bitsLeft < _swap) 00278 { 00279 val = _car & andOperator(bitsLeft); 00280 00281 int bitsRemaining = _swap - bitsLeft; 00282 if(_arrayCount < (unsigned int)_buffer.size() - 1) 00283 { 00284 _car = _buffer.at(_arrayCount + 1); 00285 val += ((_car & andOperator(bitsRemaining)) << bitsLeft); 00286 00287 _car = _car >> bitsRemaining; 00288 _bitCount = bitsRemaining; 00289 } 00290 _arrayCount++; 00291 } 00292 else 00293 { 00294 val = _car & _andOperator; 00295 00296 if(_bitCount + _swap >= 8) 00297 { 00298 _bitCount = 0; 00299 if(_arrayCount < (unsigned int)_buffer.size()-1) 00300 { 00301 _car = _buffer.at( _arrayCount+1 ); 00302 } 00303 _arrayCount++; 00304 } 00305 else 00306 { 00307 _car = _car >> _swap; 00308 _bitCount += _swap; 00309 } 00310 } 00311 } 00312 return val; 00313 } 00314 00316 00317 void EncodedData::append(int val) 00318 { 00319 _partialData = true; 00320 00321 int bitsLeft = 8 - _bitCount; 00322 int tempVal; 00323 if(bitsLeft < _swap) 00324 { 00325 tempVal = val; 00326 val = val & andOperator(bitsLeft); 00327 } 00328 00329 _car += (val << _bitCount); 00330 if(_bitCount + _swap >= 8) 00331 { 00332 _buffer.append(_car); 00333 _arrayCount++; 00334 _bitCount = 0; 00335 _car = 0; 00336 } 00337 else 00338 { 00339 _bitCount += _swap; 00340 } 00341 00342 if (bitsLeft < _swap) 00343 { 00344 int bitsRemaining = _swap - bitsLeft; 00345 val = tempVal >> bitsLeft; 00346 _car += val; 00347 _bitCount += bitsRemaining; 00348 } 00349 } 00350 00352 00353 quint32 EncodedData::toUInt32() 00354 { 00355 checkPartialData(); 00356 00357 quint32 value = 0; 00358 QByteArray bytes = _data->data(); 00359 for(int i=0; i<bytes.size() && i<4; i++) 00360 value += ((uchar)bytes.at(i))<<(i*8); 00361 00362 return value; 00363 } 00364 00366 00370 QString EncodedData::toString(Data::DataFormat format) 00371 { 00372 checkPartialData(); 00373 Data::DataFormat dataFormat = _data->format(); 00374 if(format!=Data::F_UNDEF) 00375 dataFormat = format; 00376 00377 int dataSize = size(); 00378 QByteArray bytes = _data->data(); 00379 if (dataSize>0 && bytes.size()==0) 00380 { 00381 throw SilentEyeException("Cannot uncompress data", 00382 "check other options and make sure the given image include a compressed message."); 00383 } 00384 if(dataFormat == Data::UTF8) 00385 return QString::fromUtf8(bytes.data()); 00386 else if(dataFormat == Data::LATIN1) 00387 return QString::fromLatin1(bytes.data()); 00388 else if(dataFormat == Data::ASCII) 00389 return QString::fromAscii(bytes.data()); 00390 else if(dataFormat == Data::FILE) 00391 return _data->name(); 00392 00393 return "unsupported format(" + QString::number(dataFormat) + ") for string conversion."; 00394 } 00395 00397 00398 QPointer<Data> EncodedData::toData() 00399 { 00400 checkPartialData(); 00401 return _data; 00402 } 00403 00405 00409 unsigned short int EncodedData::andOperator(unsigned short int nbBits) 00410 { 00411 return (int)pow(2, nbBits)-1; 00412 } 00413 00414 }