20 #include "protocolhelper_p.h"
22 #include "attributefactory.h"
23 #include "collectionstatistics.h"
25 #include "exception.h"
26 #include "itemserializer_p.h"
27 #include "itemserializerplugin.h"
29 #include <QtCore/QDateTime>
30 #include <QtCore/QFile>
31 #include <QtCore/QVarLengthArray>
34 #include <klocalizedstring.h>
36 using namespace Akonadi;
40 QVarLengthArray<QByteArray,16> params;
41 int end = Akonadi::ImapParser::parseParenthesizedList( data, params, start );
42 for (
int i = 0; i < params.count() - 1; i += 2 ) {
43 const QByteArray key = params[i];
44 const QByteArray value = params[i + 1];
46 if ( key ==
"INHERIT" )
48 else if ( key ==
"INTERVAL" )
50 else if ( key ==
"CACHETIMEOUT" )
52 else if ( key ==
"SYNCONDEMAND" )
54 else if ( key ==
"LOCALPARTS" ) {
55 QVarLengthArray<QByteArray,16> tmp;
57 Akonadi::ImapParser::parseParenthesizedList( value, tmp );
58 for (
int j=0; j<tmp.size(); j++ )
59 parts << QString::fromLatin1( tmp[j] );
68 QByteArray rv =
"CACHEPOLICY (";
72 rv +=
"INHERIT false";
74 rv +=
" CACHETIMEOUT " + QByteArray::number( policy.
cacheTimeout() );
75 rv +=
" SYNCONDEMAND " + ( policy.
syncOnDemand() ? QByteArray(
"true") : QByteArray(
"false") );
76 rv +=
" LOCALPARTS (" + policy.
localParts().join( QLatin1String(
" ") ).toLatin1() +
')';
83 ProtocolHelperValuePool *pool,
int start )
85 if ( !pool || parentCollection == -1 ) {
91 if ( pool->ancestorCollections.contains( parentCollection ) ) {
97 pool->ancestorCollections.insert( parentCollection, entity->
parentCollection() );
106 QVarLengthArray<QByteArray, 16> ancestors;
107 QVarLengthArray<QByteArray, 16> parentIds;
109 ImapParser::parseParenthesizedList( data, ancestors );
111 for (
int i = 0; i < ancestors.count(); ++i ) {
113 ImapParser::parseParenthesizedList( ancestors[ i ], parentIds );
114 if ( parentIds.size() != 2 )
118 if ( uid == rootCollectionId ) {
136 pos = ImapParser::parseNumber( data, colId, &ok, pos );
137 if ( !ok || colId <= 0 ) {
138 kDebug() <<
"Could not parse collection id from response:" << data;
143 pos = ImapParser::parseNumber( data, parentId, &ok, pos );
144 if ( !ok || parentId < 0 ) {
145 kDebug() <<
"Could not parse parent id from response:" << data;
153 QVarLengthArray<QByteArray,16> attributes;
154 pos = ImapParser::parseParenthesizedList( data, attributes, pos );
156 for (
int i = 0; i < attributes.count() - 1; i += 2 ) {
157 const QByteArray key = attributes[i];
158 const QByteArray value = attributes[i + 1];
160 if ( key ==
"NAME" ) {
161 collection.
setName( QString::fromUtf8( value ) );
162 }
else if ( key ==
"REMOTEID" ) {
163 collection.
setRemoteId( QString::fromUtf8( value ) );
164 }
else if ( key ==
"REMOTEREVISION" ) {
166 }
else if ( key ==
"RESOURCE" ) {
167 collection.
setResource( QString::fromUtf8( value ) );
168 }
else if ( key ==
"MIMETYPE" ) {
169 QVarLengthArray<QByteArray,16> ct;
170 ImapParser::parseParenthesizedList( value, ct );
172 for (
int j = 0; j < ct.size(); j++ )
173 ct2 << QString::fromLatin1( ct[j] );
175 }
else if ( key ==
"VIRTUAL" ) {
177 }
else if ( key ==
"MESSAGES" ) {
181 }
else if ( key ==
"UNSEEN" ) {
185 }
else if ( key ==
"SIZE" ) {
187 s.
setSize( value.toLongLong() );
189 }
else if ( key ==
"CACHEPOLICY" ) {
193 }
else if ( key ==
"ANCESTORS" ) {
213 return ImapParser::join( l,
" " );
218 const QByteArray versionString( version != 0 ?
'[' + QByteArray::number( version ) +
']' :
"" );
221 return label + versionString;
223 return "PLD:" + label + versionString;
225 return "ATR:" + label + versionString;
234 if ( data.startsWith(
"PLD:" ) ) {
236 return data.mid( 4 );
237 }
else if ( data.startsWith(
"ATR:" ) ) {
239 return data.mid( 4 );
249 return QByteArray(
"(0 \"\")");
253 return '(' + QByteArray::number( col.
id() ) +
' ' + ImapParser::quote( col.
remoteId().toUtf8() ) +
") " + parentHrid;
259 return '(' + QByteArray::number( item.
id() ) +
' ' + ImapParser::quote( item.
remoteId().toUtf8() ) +
") " + parentHrid;
267 command +=
" " AKONADI_PARAM_FULLPAYLOAD;
269 command +=
" " AKONADI_PARAM_ALLATTRIBUTES;
271 command +=
" " AKONADI_PARAM_CACHEONLY;
273 command +=
" " AKONADI_PARAM_CHECKCACHEDPARTSONLY;
275 command +=
" " "IGNOREERRORS";
279 command +=
" ANCESTORS 1";
282 command +=
" ANCESTORS INF";
289 command +=
" " AKONADI_PARAM_CHANGEDSINCE
" " + QByteArray::number( fetchScope.
fetchChangedSince().toTime_t() );
293 command +=
" " AKONADI_PARAM_EXTERNALPAYLOAD;
295 command +=
" (UID REMOTEID REMOTEREVISION COLLECTIONID FLAGS SIZE";
297 command +=
" DATETIME";
298 foreach (
const QByteArray &part, fetchScope.
payloadParts() )
300 foreach (
const QByteArray &part, fetchScope.
attributes() )
313 QString remoteRevision;
317 for (
int i = 0; i < lineTokens.count() - 1; i += 2 ) {
318 const QByteArray key = lineTokens.value( i );
319 const QByteArray value = lineTokens.value( i + 1 );
322 uid = value.toLongLong();
323 else if ( key ==
"REV" )
325 else if ( key ==
"REMOTEID" ) {
326 if ( !value.isEmpty() )
327 rid = QString::fromUtf8( value );
330 }
else if ( key ==
"REMOTEREVISION" ) {
331 remoteRevision = QString::fromUtf8( value );
332 }
else if ( key ==
"COLLECTIONID" ) {
334 }
else if ( key ==
"MIMETYPE" ) {
336 mimeType = valuePool->mimeTypePool.sharedValue( QString::fromLatin1( value ) );
338 mimeType = QString::fromLatin1( value );
342 if ( uid < 0 || rev < 0 || mimeType.isEmpty() ) {
343 kWarning() <<
"Broken fetch response: UID, RID, REV or MIMETYPE missing!";
352 item.setStorageCollectionId( cid );
357 for (
int i = 0; i < lineTokens.count() - 1; i += 2 ) {
358 const QByteArray key = lineTokens.value( i );
360 if ( key ==
"UID" || key ==
"REV" || key ==
"REMOTEID" ||
361 key ==
"MIMETYPE" || key ==
"COLLECTIONID" || key ==
"REMOTEREVISION" )
364 if ( key ==
"FLAGS" ) {
365 QList<QByteArray> flags;
366 ImapParser::parseParenthesizedList( lineTokens[i + 1], flags );
367 if ( !flags.isEmpty() ) {
369 convertedFlags.reserve( flags.size() );
370 foreach (
const QByteArray &flag, flags ) {
372 convertedFlags.insert( valuePool->flagPool.sharedValue( flag ) );
374 convertedFlags.insert( flag );
378 }
else if ( key ==
"CACHEDPARTS" ) {
379 QSet<QByteArray> partsSet;
380 QList<QByteArray> parts;
381 ImapParser::parseParenthesizedList( lineTokens[i + 1], parts );
382 foreach (
const QByteArray &part, parts ) {
383 partsSet.insert(part.mid(4));
385 item.setCachedPayloadParts( partsSet );
386 }
else if ( key ==
"SIZE" ) {
387 const quint64 size = lineTokens[i + 1].toLongLong();
389 }
else if ( key ==
"DATETIME" ) {
391 ImapParser::parseDateTime( lineTokens[i + 1], datetime );
393 }
else if ( key ==
"ANCESTORS" ) {
397 QByteArray plainKey( key );
400 ImapParser::splitVersionedKey( key, plainKey, version );
404 case ProtocolHelper::PartPayload:
406 bool isExternal =
false;
407 const QByteArray fileKey = lineTokens.value( i + 1 );
408 if ( fileKey ==
"[FILE]" ) {
416 case ProtocolHelper::PartAttribute:
420 if ( lineTokens.value( i + 1 ) ==
"[FILE]" ) {
422 QFile file( QString::fromUtf8( lineTokens.value( i + 1 ) ) );
423 if ( file.open( QFile::ReadOnly ) )
426 kWarning() <<
"Failed to open attribute file: " << lineTokens.value( i + 1 );
437 case ProtocolHelper::PartGlobal:
439 kWarning() <<
"Unknown item part type:" << key;
444 item.d_ptr->resetChangeLog();