00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef AKONADI_PROTOCOLHELPER_P_H
00021 #define AKONADI_PROTOCOLHELPER_P_H
00022
00023 #include <akonadi/cachepolicy.h>
00024 #include <akonadi/collection.h>
00025 #include <akonadi/collectionutils_p.h>
00026 #include <akonadi/item.h>
00027 #include <akonadi/itemfetchscope.h>
00028 #include <akonadi/sharedvaluepool_p.h>
00029
00030 #include <akonadi/private/imapparser_p.h>
00031 #include <akonadi/private/protocol_p.h>
00032
00033 #include <boost/bind.hpp>
00034 #include <algorithm>
00035
00036 namespace Akonadi {
00037
00038 struct ProtocolHelperValuePool
00039 {
00040 typedef Internal::SharedValuePool<QByteArray, QVector> FlagPool;
00041 typedef Internal::SharedValuePool<QString, QVector> MimeTypePool;
00042
00043 FlagPool flagPool;
00044 MimeTypePool mimeTypePool;
00045 QHash<Collection::Id, Collection> ancestorCollections;
00046 };
00047
00056 class ProtocolHelper
00057 {
00058 public:
00060 enum PartNamespace {
00061 PartGlobal,
00062 PartPayload,
00063 PartAttribute
00064 };
00065
00073 static int parseCachePolicy( const QByteArray &data, CachePolicy &policy, int start = 0 );
00074
00078 static QByteArray cachePolicyToByteArray( const CachePolicy &policy );
00079
00083 static void parseAncestors( const QByteArray &data, Entity *entity, int start = 0 );
00084
00091 static void parseAncestorsCached( const QByteArray &data, Entity *entity, Collection::Id parentCollection, ProtocolHelperValuePool *valuePool = 0, int start = 0 );
00092
00100 static int parseCollection( const QByteArray &data, Collection &collection, int start = 0 );
00101
00105 static QByteArray attributesToByteArray( const Entity &entity, bool ns = false );
00106
00110 static QByteArray encodePartIdentifier( PartNamespace ns, const QByteArray &label, int version = 0 );
00111
00115 static QByteArray decodePartIdentifier( const QByteArray &data, PartNamespace &ns );
00116
00121 template <typename T>
00122 static QByteArray entitySetToByteArray( const QList<T> &_objects, const QByteArray &command )
00123 {
00124 if ( _objects.isEmpty() )
00125 throw Exception( "No objects specified" );
00126
00127 typename T::List objects( _objects );
00128
00129 QByteArray rv;
00130 std::sort( objects.begin(), objects.end(), boost::bind( &T::id, _1 ) < boost::bind( &T::id, _2 ) );
00131 if ( objects.first().isValid() ) {
00132
00133 rv += " " AKONADI_CMD_UID " ";
00134 if ( !command.isEmpty() ) {
00135 rv += command;
00136 rv += ' ';
00137 }
00138 QList<typename T::Id> uids;
00139 foreach ( const T &object, objects )
00140 uids << object.id();
00141 ImapSet set;
00142 set.add( uids );
00143 rv += set.toImapSequenceSet();
00144 return rv;
00145 }
00146
00147
00148 if ( std::find_if( objects.constBegin(), objects.constEnd(),
00149 boost::bind( &QString::isEmpty, boost::bind( &T::remoteId, _1 ) ) )
00150 != objects.constEnd() )
00151 {
00152 throw Exception( "No remote identifier specified" );
00153 }
00154
00155
00156 if ( std::find_if( objects.constBegin(), objects.constEnd(),
00157 !boost::bind( static_cast<bool (*)(const T&)>( &CollectionUtils::hasValidHierarchicalRID ), _1 ) )
00158 == objects.constEnd() && objects.size() == 1 )
00159 {
00160
00161 rv += " " AKONADI_CMD_HRID " ";
00162 if ( !command.isEmpty() ) {
00163 rv += command;
00164 rv += ' ';
00165 }
00166 rv += '(' + hierarchicalRidToByteArray( objects.first() ) + ')';
00167 return rv;
00168 }
00169
00170
00171 QList<QByteArray> rids;
00172 foreach ( const T &object, objects ) {
00173 rids << ImapParser::quote( object.remoteId().toUtf8() );
00174 }
00175
00176 rv += " " AKONADI_CMD_RID " ";
00177 if ( !command.isEmpty() ) {
00178 rv += command;
00179 rv += ' ';
00180 }
00181 rv += '(';
00182 rv += ImapParser::join( rids, " " );
00183 rv += ')';
00184 return rv;
00185 }
00186
00191 template <typename T>
00192 static QByteArray entityIdToByteArray( const T &object, const QByteArray &command )
00193 {
00194 return entitySetToByteArray( typename T::List() << object, command );
00195 }
00196
00201 static QByteArray hierarchicalRidToByteArray( const Collection &col );
00202
00207 static QByteArray hierarchicalRidToByteArray( const Item &item );
00208
00212 static QByteArray itemFetchScopeToByteArray( const ItemFetchScope &fetchScope );
00213
00217 static void parseItemFetchResult( const QList<QByteArray> &lineTokens, Item &item, ProtocolHelperValuePool *valuePool = 0 );
00218 };
00219
00220 }
00221
00222 #endif