SilentEye 0.4.1

sef/encodeddata.cpp

Go to the documentation of this file.
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 }