00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "itemserializer_p.h"
00022 #include "item.h"
00023 #include "itemserializerplugin.h"
00024 #include "typepluginloader_p.h"
00025
00026
00027 #include <QtCore/QBuffer>
00028 #include <QtCore/QFile>
00029 #include <QtCore/QIODevice>
00030 #include <QtCore/QString>
00031
00032 #include <string>
00033
00034 Q_DECLARE_METATYPE( std::string )
00035
00036 namespace Akonadi {
00037
00038 DefaultItemSerializerPlugin::DefaultItemSerializerPlugin()
00039 {
00040 Item::addToLegacyMapping<QByteArray>( QLatin1String( "application/octet-stream" ) );
00041 }
00042
00043 bool DefaultItemSerializerPlugin::deserialize( Item& item, const QByteArray& label, QIODevice& data, int )
00044 {
00045 if ( label != Item::FullPayload )
00046 return false;
00047
00048 item.setPayload( data.readAll() );
00049 return true;
00050 }
00051
00052 void DefaultItemSerializerPlugin::serialize( const Item& item, const QByteArray& label, QIODevice& data, int& )
00053 {
00054 Q_ASSERT( label == Item::FullPayload );
00055 Q_UNUSED( label );
00056 data.write( item.payload<QByteArray>() );
00057 }
00058
00059 bool StdStringItemSerializerPlugin::deserialize( Item& item, const QByteArray& label, QIODevice& data, int )
00060 {
00061 if ( label != Item::FullPayload )
00062 return false;
00063 std::string str;
00064 {
00065 const QByteArray ba = data.readAll();
00066 str.assign( ba.data(), ba.size() );
00067 }
00068 item.setPayload( str );
00069 return true;
00070 }
00071
00072 void StdStringItemSerializerPlugin::serialize( const Item& item, const QByteArray& label, QIODevice& data, int& )
00073 {
00074 Q_ASSERT( label == Item::FullPayload );
00075 Q_UNUSED( label );
00076 const std::string str = item.payload<std::string>();
00077 data.write( QByteArray::fromRawData( str.data(), str.size() ) );
00078 }
00079
00080
00081 void ItemSerializer::deserialize( Item& item, const QByteArray& label, const QByteArray& data, int version, bool external )
00082 {
00083 if ( external ) {
00084 QFile file( QString::fromUtf8(data) );
00085 if ( file.open( QIODevice::ReadOnly ) ) {
00086 deserialize( item, label, file, version );
00087 file.close();
00088 }
00089 } else {
00090 QBuffer buffer;
00091 buffer.setData( data );
00092 buffer.open( QIODevice::ReadOnly );
00093 buffer.seek( 0 );
00094 deserialize( item, label, buffer, version );
00095 buffer.close();
00096 }
00097 }
00098
00099
00100 void ItemSerializer::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version )
00101 {
00102 if ( !TypePluginLoader::defaultPluginForMimeType( item.mimeType() )->deserialize( item, label, data, version ) ) {
00103 kWarning() << "Unable to deserialize payload part:" << label;
00104 data.seek( 0 );
00105 kWarning() << "Payload data was: " << data.readAll();
00106 }
00107 }
00108
00109
00110 void ItemSerializer::serialize( const Item& item, const QByteArray& label, QByteArray& data, int &version )
00111 {
00112 QBuffer buffer;
00113 buffer.setBuffer( &data );
00114 buffer.open( QIODevice::WriteOnly );
00115 buffer.seek( 0 );
00116 serialize( item, label, buffer, version );
00117 buffer.close();
00118 }
00119
00120
00121 void ItemSerializer::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version )
00122 {
00123 if ( !item.hasPayload() )
00124 return;
00125 ItemSerializerPlugin * plugin = TypePluginLoader::pluginForMimeTypeAndClass( item.mimeType(), item.availablePayloadMetaTypeIds() );
00126 plugin->serialize( item, label, data, version );
00127 }
00128
00129 void ItemSerializer::apply( Item &item, const Item &other )
00130 {
00131 if ( !other.hasPayload() )
00132 return;
00133
00134 ItemSerializerPlugin *plugin = TypePluginLoader::pluginForMimeTypeAndClass( item.mimeType(), item.availablePayloadMetaTypeIds() );
00135
00136 ItemSerializerPluginV2 *pluginV2 = dynamic_cast<ItemSerializerPluginV2*>( plugin );
00137 if ( pluginV2 ) {
00138 pluginV2->apply( item, other );
00139 return;
00140 }
00141
00142
00143 foreach ( const QByteArray &part, other.loadedPayloadParts() ) {
00144 QByteArray partData;
00145 QBuffer buffer;
00146 buffer.setBuffer( &partData );
00147 buffer.open( QIODevice::ReadWrite );
00148 buffer.seek( 0 );
00149 int version;
00150 serialize( other, part, buffer, version );
00151 buffer.seek( 0 );
00152 deserialize( item, part, buffer, version );
00153 }
00154 }
00155
00156 QSet<QByteArray> ItemSerializer::parts( const Item & item )
00157 {
00158 if ( !item.hasPayload() )
00159 return QSet<QByteArray>();
00160 return TypePluginLoader::pluginForMimeTypeAndClass( item.mimeType(), item.availablePayloadMetaTypeIds() )->parts( item );
00161 }
00162
00163 QSet<QByteArray> ItemSerializer::availableParts( const Item & item )
00164 {
00165 if ( !item.hasPayload() )
00166 return QSet<QByteArray>();
00167 ItemSerializerPlugin *plugin = TypePluginLoader::pluginForMimeTypeAndClass( item.mimeType(), item.availablePayloadMetaTypeIds() );
00168 ItemSerializerPluginV2 *pluginV2 = dynamic_cast<ItemSerializerPluginV2*>( plugin );
00169
00170 if ( pluginV2 )
00171 return pluginV2->availableParts( item );
00172
00173 if (item.hasPayload())
00174 return QSet<QByteArray>();
00175
00176 return QSet<QByteArray>() << Item::FullPayload;
00177 }
00178
00179 Item ItemSerializer::convert( const Item & item, int mtid )
00180 {
00181 kDebug() << "asked to convert a" << item.mimeType() << "item to format" << ( mtid ? QMetaType::typeName( mtid ) : "<legacy>" );
00182 if ( !item.hasPayload() ) {
00183 kDebug() << " -> but item has no payload!";
00184 return Item();
00185 }
00186
00187 if ( ItemSerializerPlugin * const plugin = TypePluginLoader::pluginForMimeTypeAndClass( item.mimeType(), QVector<int>( 1, mtid ), TypePluginLoader::NoDefault ) ) {
00188 kDebug() << " -> found a plugin that feels responsible, trying serialising the payload";
00189 QBuffer buffer;
00190 buffer.open( QIODevice::ReadWrite );
00191 int version;
00192 serialize( item, Item::FullPayload, buffer, version );
00193 buffer.seek( 0 );
00194 kDebug() << " -> serialized payload into" << buffer.size() << "bytes" << endl
00195 << " -> going to deserialize";
00196 Item newItem;
00197 if ( plugin->deserialize( newItem, Item::FullPayload, buffer, version ) ) {
00198 kDebug() << " -> conversion successful";
00199 return newItem;
00200 } else {
00201 kDebug() << " -> conversion FAILED";
00202 }
00203 } else {
00204 kDebug() << " -> found NO plugin that feels responsible";
00205 }
00206 return Item();
00207 }
00208
00209 }