KIMAP Library
imapset.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "imapset.h"
00021
00022 #include <QtCore/QSharedData>
00023
00024 using namespace KIMAP;
00025
00026 class ImapInterval::Private : public QSharedData
00027 {
00028 public:
00029 Private() :
00030 QSharedData(),
00031 begin( 0 ),
00032 end( 0 )
00033 {}
00034
00035 Private( const Private &other ) :
00036 QSharedData( other )
00037 {
00038 begin = other.begin;
00039 end = other.end;
00040 }
00041
00042 Id begin;
00043 Id end;
00044 };
00045
00046 class ImapSet::Private : public QSharedData
00047 {
00048 public:
00049 Private() : QSharedData() {}
00050 Private( const Private &other ) :
00051 QSharedData( other )
00052 {
00053 }
00054
00055 ImapInterval::List intervals;
00056 };
00057
00058
00059 ImapInterval::ImapInterval() :
00060 d( new Private )
00061 {
00062 }
00063
00064 ImapInterval::ImapInterval(const ImapInterval & other) :
00065 d( other.d )
00066 {
00067 }
00068
00069 ImapInterval::ImapInterval(Id begin, Id end) :
00070 d( new Private )
00071 {
00072 d->begin = begin;
00073 d->end = end;
00074 }
00075
00076 ImapInterval::~ ImapInterval()
00077 {
00078 }
00079
00080 ImapInterval& ImapInterval::operator =(const ImapInterval & other)
00081 {
00082 if ( this != & other )
00083 d = other.d;
00084 return *this;
00085 }
00086
00087 bool ImapInterval::operator ==(const ImapInterval & other) const
00088 {
00089 return ( d->begin == other.d->begin && d->end == other.d->end );
00090 }
00091
00092 ImapInterval::Id ImapInterval::size() const
00093 {
00094 if ( !d->begin && !d->end )
00095 return 0;
00096 return d->end - d->begin + 1;
00097 }
00098
00099 bool ImapInterval::hasDefinedBegin() const
00100 {
00101 return d->begin != 0;
00102 }
00103
00104 ImapInterval::Id ImapInterval::begin() const
00105 {
00106 return d->begin;
00107 }
00108
00109 bool ImapInterval::hasDefinedEnd() const
00110 {
00111 return d->end != 0;
00112 }
00113
00114 ImapInterval::Id ImapInterval::end() const
00115 {
00116 if ( hasDefinedEnd() )
00117 return d->end;
00118 return 0xFFFFFFFF;
00119 }
00120
00121 void ImapInterval::setBegin(Id value)
00122 {
00123 Q_ASSERT( value >= 0 );
00124 Q_ASSERT( value <= d->end || !hasDefinedEnd() );
00125 d->begin = value;
00126 }
00127
00128 void ImapInterval::setEnd(Id value)
00129 {
00130 Q_ASSERT( value >= 0 );
00131 Q_ASSERT( value >= d->begin || !hasDefinedBegin() );
00132 d->end = value;
00133 }
00134
00135 QByteArray ImapInterval::toImapSequence() const
00136 {
00137 if ( size() == 0 )
00138 return QByteArray();
00139 if ( size() == 1 )
00140 return QByteArray::number( d->begin );
00141 QByteArray rv;
00142 rv += QByteArray::number( d->begin ) + ':';
00143 if ( hasDefinedEnd() )
00144 rv += QByteArray::number( d->end );
00145 else
00146 rv += '*';
00147 return rv;
00148 }
00149
00150 ImapInterval ImapInterval::fromImapSequence( const QByteArray &sequence )
00151 {
00152 QList<QByteArray> values = sequence.split( ':' );
00153 if ( values.isEmpty() || values.size() > 2 ) {
00154 return ImapInterval();
00155 }
00156
00157 bool ok = false;
00158 Id begin = values[0].toLongLong(&ok);
00159
00160 if ( !ok ) {
00161 return ImapInterval();
00162 }
00163
00164 Id end;
00165
00166 if ( values.size() == 1 ) {
00167 end = begin;
00168 } else if ( values[1] == QByteArray( "*" ) ) {
00169 end = 0;
00170 } else {
00171 ok = false;
00172 end = values[1].toLongLong(&ok);
00173 if ( !ok ) {
00174 return ImapInterval();
00175 }
00176 }
00177
00178 return ImapInterval( begin, end );
00179 }
00180
00181 ImapSet::ImapSet() :
00182 d( new Private )
00183 {
00184 }
00185
00186 ImapSet::ImapSet( Id begin, Id end ) :
00187 d( new Private )
00188 {
00189 add( ImapInterval( begin, end ) );
00190 }
00191
00192 ImapSet::ImapSet( Id value ) :
00193 d( new Private )
00194 {
00195 add( QList<Id>() << value );
00196 }
00197
00198 ImapSet::ImapSet(const ImapSet & other) :
00199 d( other.d )
00200 {
00201 }
00202
00203 ImapSet::~ImapSet()
00204 {
00205 }
00206
00207 ImapSet & ImapSet::operator =(const ImapSet & other)
00208 {
00209 if ( this != &other )
00210 d = other.d;
00211 return *this;
00212 }
00213
00214 bool ImapSet::operator ==(const ImapSet &other) const
00215 {
00216 if ( d->intervals.size()!=other.d->intervals.size() ) {
00217 return false;
00218 }
00219
00220 foreach ( const ImapInterval &interval, d->intervals ) {
00221 if ( !other.d->intervals.contains( interval ) ) {
00222 return false;
00223 }
00224 }
00225
00226 return true;
00227 }
00228
00229 void ImapSet::add( Id value )
00230 {
00231 add( QList<Id>() << value );
00232 }
00233
00234 void ImapSet::add(const QList<Id> & values)
00235 {
00236 QList<Id> vals = values;
00237 qSort( vals );
00238 for( int i = 0; i < vals.count(); ++i ) {
00239 const int begin = vals[i];
00240 Q_ASSERT( begin >= 0 );
00241 if ( i == vals.count() - 1 ) {
00242 d->intervals << ImapInterval( begin, begin );
00243 break;
00244 }
00245 do {
00246 ++i;
00247 Q_ASSERT( vals[i] >= 0 );
00248 if ( vals[i] != (vals[i - 1] + 1) ) {
00249 --i;
00250 break;
00251 }
00252 } while ( i < vals.count() - 1 );
00253 d->intervals << ImapInterval( begin, vals[i] );
00254 }
00255 }
00256
00257 void ImapSet::add(const ImapInterval & interval)
00258 {
00259 d->intervals << interval;
00260 }
00261
00262 QByteArray ImapSet::toImapSequenceSet() const
00263 {
00264 QList<QByteArray> rv;
00265 foreach ( const ImapInterval &interval, d->intervals ) {
00266 rv << interval.toImapSequence();
00267 }
00268
00269 QByteArray result;
00270
00271 if ( !rv.isEmpty() ) {
00272 result = rv.first();
00273 QList<QByteArray>::ConstIterator it = rv.constBegin();
00274 ++it;
00275 for ( ; it != rv.constEnd(); ++it ) {
00276 result += ',' + (*it);
00277 }
00278 }
00279
00280 return result;
00281 }
00282
00283 ImapSet ImapSet::fromImapSequenceSet( const QByteArray &sequence )
00284 {
00285 ImapSet result;
00286
00287 QList<QByteArray> intervals = sequence.split( ',' );
00288
00289 foreach( const QByteArray &interval, intervals ) {
00290 if ( !interval.isEmpty() ) {
00291 result.add( ImapInterval::fromImapSequence( interval ) );
00292 }
00293 }
00294
00295 return result;
00296 }
00297
00298 ImapInterval::List ImapSet::intervals() const
00299 {
00300 return d->intervals;
00301 }
00302
00303 bool ImapSet::isEmpty() const
00304 {
00305 return d->intervals.isEmpty();
00306 }
00307
00308 QDebug& operator<<( QDebug &d, const ImapInterval &interval )
00309 {
00310 d << interval.toImapSequence();
00311 return d;
00312 }
00313
00314 QDebug& operator<<( QDebug &d, const ImapSet &set )
00315 {
00316 d << set.toImapSequenceSet();
00317 return d;
00318 }
00319