[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdepim-runtime/akregator_port] plugins: Make RssItemSerializer private to the serializer plugin
From:       Frank Osterfeld <frank.osterfeld () kdab ! com>
Date:       2012-03-31 15:16:47
Message-ID: 20120331151647.2D7CBA60C4 () git ! kde ! org
[Download RAW message or body]

Git commit 85a2d096258e7f4f9de5f02941d9e05d037e0843 by Frank Osterfeld.
Committed on 24/02/2012 at 16:39.
Pushed by osterfeld into branch 'akregator_port'.

Make RssItemSerializer private to the serializer plugin

M  +35   -1    plugins/CMakeLists.txt
M  +1    -1    plugins/akonadi_serializer_rss.h
A  +49   -0    plugins/krss.proto
A  +49   -0    plugins/rssitemserializer.h     [License: LGPL (v2+)]
A  +182  -0    plugins/rssitemserializer_json.cpp     [License: LGPL (v2+)]
A  +201  -0    plugins/rssitemserializer_protobuf.cpp     [License: LGPL (v2+)]
A  +166  -0    plugins/rssitemserializer_qdatastream.cpp     [License: LGPL (v2+)]
A  +447  -0    plugins/rssitemserializer_xml.cpp     [License: LGPL (v2+)]
A  +52   -0    plugins/tests/CMakeLists.txt
A  +198  -0    plugins/tests/testxmlitemserializer.cpp     [License: LGPL (v2+)]
A  +44   -0    plugins/tests/testxmlitemserializer.h     [License: LGPL (v2+)]

http://commits.kde.org/kdepim-runtime/85a2d096258e7f4f9de5f02941d9e05d037e0843

diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index f807908..84f432d 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -1,9 +1,43 @@
+add_subdirectory( tests )
+
 set(akonadi_serializer_rss_SRCS
     akonadi_serializer_rss.cpp
 )
 
+if(KRSS_ENABLE_PROTOBUF_SERIALIZER)
+    WRAP_PROTO(krss_LIB_PROTOBUF_SRCS krss.proto)
+
+    set(akonadi_serializer_rss_SRCS
+        ${akonadi_serializer_rss_SRCS}
+        ${krss_LIB_PROTOBUF_SRCS}
+        rssitemserializer_protobuf.cpp
+    )
+    set(KRSS_EXTRA_LIBS ${PROTOBUF_LIBRARY})
+else(KRSS_ENABLE_PROTOBUF_SERIALIZER)
+if(KRSS_ENABLE_QDATASTREAM_SERIALIZER)
+    set(akonadi_serializer_rss_SRCS
+        ${akonadi_serializer_rss_SRCS}
+        rssitemserializer_qdatastream.cpp
+    )
+    set(KRSS_EXTRA_LIBS ${PROTOBUF_LIBRARY})
+else(KRSS_ENABLE_QDATASTREAM_SERIALIZER)
+if(KRSS_ENABLE_JSON_SERIALIZER)
+   set(akonadi_serializer_rss_SRCS
+       ${akonadi_serializer_rss_SRCS}
+       rssitemserializer_json.cpp
+   )
+   set(KRSS_EXTRA_LIBS qjson)
+else(KRSS_ENABLE_JSON_SERIALIZER)
+   set(akonadi_serializer_rss_SRCS
+       ${akonadi_serializer_rss_SRCS}
+       rssitemserializer_xml.cpp
+   )
+endif(KRSS_ENABLE_JSON_SERIALIZER)
+endif(KRSS_ENABLE_QDATASTREAM_SERIALIZER)
+endif(KRSS_ENABLE_PROTOBUF_SERIALIZER)
+
 kde4_add_plugin(akonadi_serializer_rss ${akonadi_serializer_rss_SRCS})
-target_link_libraries(akonadi_serializer_rss ${KDE4_KIO_LIBS} \
${KDEPIMLIBS_AKONADI_LIBS} krss) +target_link_libraries(akonadi_serializer_rss \
${KDE4_KIO_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_SYNDICATION_LIBS} krss)  
 install(TARGETS akonadi_serializer_rss DESTINATION ${PLUGIN_INSTALL_DIR})
 install(FILES akonadi_serializer_rss.desktop DESTINATION \
                "${DATA_INSTALL_DIR}/akonadi/plugins/serializer")
diff --git a/plugins/akonadi_serializer_rss.h b/plugins/akonadi_serializer_rss.h
index ce8a863..9089c29 100644
--- a/plugins/akonadi_serializer_rss.h
+++ b/plugins/akonadi_serializer_rss.h
@@ -18,7 +18,7 @@
 #ifndef AKONADI_SERIALIZER_RSS
 #define AKONADI_SERIALIZER_RSS
 
-#include <krss/rssitemserializer.h>
+#include "rssitemserializer.h"
 
 #include <akonadi/itemserializerplugin.h>
 
diff --git a/plugins/krss.proto b/plugins/krss.proto
new file mode 100644
index 0000000..4837532
--- /dev/null
+++ b/plugins/krss.proto
@@ -0,0 +1,49 @@
+package KRss.Protobuf;
+
+
+message ItemHeader {
+   repeated string tags = 1;
+   required int32 hash = 2;
+   required bool guidIsHash = 3;
+   required string guid = 4;
+   required string title = 5;
+   required string link = 6;
+   required int64 datePublished = 7;
+   required int64 dateUpdated = 8;
+   required string language = 9;
+   repeated Person authors = 10;
+   repeated Enclosure enclosures = 11;
+   repeated Category categories = 12;
+   required int32 commentsCount = 13;
+   required string commentsLink = 14;
+   required string commentsFeed = 15;
+   required string commentPostUri = 16;
+   repeated string additionalProperties = 17;
+}
+
+message ItemContent {
+   required string description = 1;
+   required string content = 2;	
+}
+
+message Person {
+   required string name = 1;
+   required string email = 2;
+   required string uri = 3;
+}
+
+message Enclosure {
+   required string url = 1;
+   required string title = 2;
+   required string type = 3;
+   required uint32 length = 4;
+   required uint32 duration = 5;  
+}
+
+message Category {
+   required string label = 1;
+   required string scheme = 2;
+   required string term = 3;
+}
+
+
diff --git a/plugins/rssitemserializer.h b/plugins/rssitemserializer.h
new file mode 100644
index 0000000..7dcaaed
--- /dev/null
+++ b/plugins/rssitemserializer.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the krss library
+ *
+ * Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KRSS_RSSITEMSERIALIZER_H
+#define KRSS_RSSITEMSERIALIZER_H
+
+class QByteArray;
+
+namespace KRss
+{
+
+class RssItem;
+
+class RssItemSerializer
+{
+public:
+
+    enum ItemPart {
+        Headers=0x01,
+        Content=0x02,
+        Full=Headers|Content
+    };
+
+    static void serialize( const KRss::RssItem& item, QByteArray& array, ItemPart \
part = Full ); +    static bool deserialize( KRss::RssItem& item, const QByteArray& \
array, ItemPart part = Full ); +};
+
+}
+
+#endif // KRSS_RSSITEMSERIALIZER_H
diff --git a/plugins/rssitemserializer_json.cpp b/plugins/rssitemserializer_json.cpp
new file mode 100644
index 0000000..87dba61
--- /dev/null
+++ b/plugins/rssitemserializer_json.cpp
@@ -0,0 +1,182 @@
+/*
+ * This file is part of the krss library
+ *
+ * Copyright (C) 2009 Frank Osterfeld <osterfeld@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "rssitemserializer.h"
+#include "rssitem.h"
+#include "category.h"
+#include "enclosure.h"
+#include "person.h"
+
+#include <KDateTime>
+#include <QMap>
+#include <QVariantMap>
+
+#include <qjson/parser.h>
+#include <qjson/serializer.h>
+
+using namespace boost;
+using namespace KRss;
+
+static QVariantMap serialize( const Enclosure& e ) {
+    QVariantMap h;
+    h.insert( QLatin1String( "duration" ), e.duration() );
+    h.insert( QLatin1String( "length" ), e.length() );
+    h.insert( QLatin1String( "title" ), e.title() );
+    h.insert( QLatin1String( "type" ), e.type() );
+    h.insert( QLatin1String( "url" ), e.url() );
+    return h;
+}
+
+static QVariantMap serialize( const Person& p ) {
+    QVariantMap h;
+    h.insert( QLatin1String( "email" ), p.email() );
+    h.insert( QLatin1String( "name" ), p.name() );
+    h.insert( QLatin1String( "uri" ), p.uri() );
+    return h;
+}
+
+static QVariantMap serialize( const Category& c ) {
+    QVariantMap h;
+    h.insert( QLatin1String( "label"), c.label() );
+    h.insert( QLatin1String( "scheme" ), c.scheme() );
+    h.insert( QLatin1String( "term" ), c.term() );
+    return h;
+}
+
+template <typename T>
+static QVariantList doSerialize( const QList<T>& l ) {
+    QVariantList list;
+    Q_FOREACH( const T& i, l )
+        list.append( serialize( i ) ); 
+    return list;
+}
+
+static Category deserializeCategory( const QVariantMap& h ) {
+    Category c;
+    c.setLabel( h.value( QLatin1String( "label" ) ).toString() );
+    c.setScheme( h.value( QLatin1String( "scheme" ) ).toString() );
+    c.setTerm( h.value( QLatin1String( "term" ) ).toString() );
+    return c;
+}
+
+
+static Enclosure deserializeEnclosure( const QVariantMap& h ) {
+    Enclosure e;
+    e.setDuration( h.value( QLatin1String( "duration" ) ).toInt() );
+    e.setLength( h.value( QLatin1String( "length" ) ).toInt() );
+    e.setTitle( h.value( QLatin1String( "title" ) ).toString() );
+    e.setType( h.value( QLatin1String( "type" ) ).toString() );
+    e.setUrl( h.value( QLatin1String( "url" ) ).toString() );
+    return e;
+}
+
+
+static Person deserializePerson( const QVariantMap& h ) {
+    Person p;
+    p.setEmail( h.value( QLatin1String( "email" ) ).toString() );
+    p.setName( h.value( QLatin1String( "name" ) ).toString() );
+    p.setUri( h.value( QLatin1String( "uri" ) ).toString() );
+    return p;
+}
+
+static QList<Person> deserializePersons( const QVariantList& h ) {
+    QList<Person> l;
+    Q_FOREACH( const QVariant& i, h )
+        l.push_back( deserializePerson( i.toMap() ) );
+    return l;
+}
+
+static QList<Category> deserializeCategories( const QVariantList& h ) {
+    QList<Category> l;
+    Q_FOREACH( const QVariant& i, h )
+        l.push_back( deserializeCategory( i.toMap() ) );
+    return l;
+}
+
+static QList<Enclosure> deserializeEnclosures( const QVariantList& h ) {
+    QList<Enclosure> l;
+    Q_FOREACH( const QVariant& i, h )
+        l.push_back( deserializeEnclosure( i.toMap() ) );
+    return l;
+}
+
+void RssItemSerializer::serialize( const RssItem& item, QByteArray& ba, ItemPart \
part ) { +    QVariantMap hash;
+    //hash.insert( QLatin1String( "hash" ), QVariant::fromValue( item.hash() ) );
+    hash.insert( QLatin1String( "guidIsHash" ), item.guidIsHash() );
+    hash.insert( QLatin1String( "title" ), item.title() );
+    hash.insert( QLatin1String( "link" ), item.link() );
+    hash.insert( QLatin1String( "description" ), item.description() );
+    hash.insert( QLatin1String( "content" ), item.content() );
+    hash.insert( QLatin1String( "language" ), item.language() );
+    hash.insert( QLatin1String( "datePublished" ), item.datePublished().toString() \
); +    hash.insert( QLatin1String( "dateUpdated" ), item.dateUpdated().toString() );
+    hash.insert( QLatin1String( "guid" ), item.guid() );
+    hash.insert( QLatin1String( "commentsCount" ), item.commentsCount() );
+    hash.insert( QLatin1String( "commentPostUri" ), item.commentPostUri() );
+    hash.insert( QLatin1String( "commentsFeed" ), item.commentsFeed() );
+    hash.insert( QLatin1String( "commentsLink" ), item.commentsLink() );
+    hash.insert( QLatin1String( "enclosures" ), QVariant( doSerialize( \
item.enclosures() ) ) ); +    hash.insert( QLatin1String( "categories" ), \
doSerialize( item.categories() ) ); +    hash.insert( QLatin1String( "authors" ), \
doSerialize( item.authors() ) ); +#if 0    
+    const QHash<QString, QString> ap = item.customProperties();
+    stream << static_cast<quint32>( ap.size() );
+    Q_FOREACH( const QString& key, ap.keys() )
+            stream << key << ap.value( key );
+#endif
+    QJSon::Serializer serializer;
+    ba = serializer.serialize( hash );
+    qDebug() << ba;
+}
+
+bool RssItemSerializer::deserialize( RssItem& item, const QByteArray& ba, ItemPart \
part ) { +    QJSon::Parser parser;
+    bool ok;
+    QVariantMap hash = parser.parse( ba, &ok ).toMap();
+    if ( !ok )
+        return false;
+    //item.setHash( hash.value( QLatin1String( "hash" ) ).value<qint64>() );
+    item.setGuidIsHash( hash.value( QLatin1String( "guidIsHash" ) ).toBool() );
+    item.setTitle( hash.value( QLatin1String( "title" ) ).toString() );
+    item.setLink( hash.value( QLatin1String( "link" ) ).toString() );
+    item.setDescription( hash.value( QLatin1String( "description" ) ).toString() );
+    item.setContent( hash.value( QLatin1String( "content" ) ).toString() );
+    item.setLanguage( hash.value( QLatin1String( "language" ) ).toString() );
+    item.setDatePublished( KDateTime::fromString( hash.value( QLatin1String( \
"datePublished" ) ).toString() ) ); +    item.setDateUpdated( KDateTime::fromString( \
hash.value( QLatin1String( "dateUpdated" ) ).toString() ) ); +    item.setGuid( \
hash.value( QLatin1String( "guid" ) ).toString() ); +    item.setCommentsCount( \
hash.value( QLatin1String( "commentsCount" ) ).toInt() ); +    \
item.setCommentPostUri( hash.value( QLatin1String( "commentPostUri" ) ).toString() ); \
+    item.setCommentsFeed( hash.value( QLatin1String( "commentsFeed" ) ).toString() \
); +    item.setCommentsLink( hash.value( QLatin1String( "commentsLink" ) \
).toString() ); +    item.setEnclosures( deserializeEnclosures( hash.value( \
QLatin1String( "enclosures" ) ).toList() ) ); +    item.setCategories( \
deserializeCategories( hash.value( QLatin1String( "categories" ) ).toList() ) ); +    \
item.setAuthors( deserializePersons( hash.value( QLatin1String( "authors" ) \
).toList() ) ); +    return true;
+}
+
+#undef READ
+#undef READ2
+#undef READSTRING
+#undef READSTRING2
+#undef READDATE
diff --git a/plugins/rssitemserializer_protobuf.cpp \
b/plugins/rssitemserializer_protobuf.cpp new file mode 100644
index 0000000..d779a8b
--- /dev/null
+++ b/plugins/rssitemserializer_protobuf.cpp
@@ -0,0 +1,201 @@
+/*
+ * This file is part of the krss library
+ *
+ * Copyright (C) 2009 Frank Osterfeld <osterfeld@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "rssitemserializer.h"
+#include "rssitem.h"
+#include "category.h"
+#include "enclosure.h"
+#include "person.h"
+
+#include "krss.pb.h"
+
+#include <KDateTime>
+
+#include <QString>
+
+#include <string>
+
+using namespace KRss;
+//TODO: in the plugin, do at init time:
+// GOOGLE_PROTOBUF_VERIFY_VERSION;
+//on plugin destruction, do
+//google::protobuf::ShutdownProtobufLibrary();
+
+
+static Protobuf::Person writePerson( const Person& o ) {
+    Protobuf::Person r;
+    r.set_name( o.name().toUtf8().constData() );
+    r.set_email(  o.email().toUtf8().constData() );
+    r.set_uri( o.uri().toUtf8().constData() );
+    return r;
+}
+
+static Protobuf::Enclosure writeEnclosure( const Enclosure& o ) {
+    Protobuf::Enclosure r;
+    r.set_url( o.url().toUtf8().constData() );
+    r.set_title( o.title().toUtf8().constData() );
+    r.set_type( o.type().toUtf8().constData() );
+    r.set_duration( o.duration() );
+    r.set_length( o.length() );
+    return r;
+}
+
+static Protobuf::Category writeCategory( const Category& o ) {
+    Protobuf::Category r;
+    r.set_label( o.label().toUtf8().constData() );
+    r.set_scheme(  o.scheme().toUtf8().constData() );
+    r.set_term( o.term().toUtf8().constData() );
+    return r;
+}
+
+void RssItemSerializer::serialize( const KRss::RssItem& item, QByteArray& array, \
ItemPart part ) const +{
+    const bool writeHeaders = part == Full || part == Headers;
+    const bool writeContent = part == Full || part == Content;
+
+    if ( writeHeaders ) {
+        Protobuf::ItemHeader header;
+
+        header.set_hash( item.hash() );
+        header.set_guidishash( item.guidIsHash() );
+        header.set_guid( item.guid().toUtf8().constData() );
+        header.set_title( item.title().toUtf8().constData() );
+        header.set_link( item.link().toUtf8().constData() );
+        header.set_datepublished( item.datePublished().toTime_t() );
+        header.set_dateupdated( item.dateUpdated().toTime_t() );
+        header.set_language( item.language().toUtf8().constData() );
+        Q_FOREACH( const Person& i, item.authors() )
+            *header.add_authors() = writePerson( i );
+        Q_FOREACH( const Enclosure& i, item.enclosures() )
+            *header.add_enclosures() = writeEnclosure( i );
+        Q_FOREACH( const Category& i, item.categories() )
+            *header.add_categories() = writeCategory( i );
+        header.set_commentscount( item.commentsCount() );
+        header.set_commentslink( item.commentsLink().toUtf8().constData() );
+        header.set_commentsfeed( item.commentsFeed().toUtf8().constData() );
+        header.set_commentposturi( item.commentPostUri().toUtf8().constData() );
+
+        std::string out;
+        header.SerializeToString( &out );
+        array.append( out.c_str(), out.size() );
+    }
+
+    if ( writeContent ) {
+        Protobuf::ItemContent content;
+
+        content.set_description( item.description().toUtf8().constData() );
+        content.set_content( item.content().toUtf8().constData() );
+
+        std::string out;
+        content.SerializeToString( &out );
+        array.append( out.c_str(), out.size() );
+    }
+}
+
+static Enclosure readEnclosure( const Protobuf::Enclosure& pe ) {
+    Enclosure enc;
+    enc.setUrl( QString::fromUtf8( pe.url().c_str() ) );
+    enc.setTitle( QString::fromUtf8( pe.title().c_str() ) );
+    enc.setType( QString::fromUtf8( pe.type().c_str() ) );
+    enc.setDuration( pe.duration() );
+    enc.setLength( pe.length() );
+    return enc;
+}
+
+static Category readCategory( const Protobuf::Category& pc ) {
+    Category cat;
+    cat.setLabel( QString::fromUtf8( pc.label().c_str() ) );
+    cat.setScheme( QString::fromUtf8( pc.scheme().c_str() ) );
+    cat.setTerm( QString::fromUtf8( pc.term().c_str() ) );
+    return cat;
+}
+
+
+static Person readPerson( const Protobuf::Person& pp ) {
+    Person p;
+    p.setName( QString::fromUtf8( pp.name().c_str() ) );
+    p.setEmail( QString::fromUtf8( pp.email().c_str() ) );
+    p.setUri( QString::fromUtf8( pp.uri().c_str() ) );
+    return p;
+}
+
+bool KRss::RssItemSerializer::deserialize( KRss::RssItem& item, const QByteArray& \
array, ItemPart part ) const +{
+    const bool readHeaders = part == Full || part == Headers;
+    const bool readContent = part == Full || part == Content;
+
+    //TODO: these ifs are wrong, the Full case must be handled differently (FullItem \
message) +
+    if ( readHeaders ) {
+        Protobuf::ItemHeader header;
+        const bool parsed = header.ParsePartialFromArray( array.constData(), \
array.size() ); +        if ( !parsed )
+            return false;
+        item.setHash( header.hash() );
+        item.setGuidIsHash( header.guidishash() );
+        item.setGuid( QString::fromUtf8( header.guid().c_str() ) );
+        item.setTitle( QString::fromUtf8( header.title().c_str() ) );
+        item.setLink( QString::fromUtf8( header.link().c_str() ) );
+        KDateTime published;
+        published.setTime_t( header.datepublished() );
+        item.setDatePublished( published );
+        KDateTime updated;
+        updated.setTime_t( header.dateupdated() );
+        item.setDateUpdated( updated );
+
+        QList<Enclosure> enclosures;
+        for ( int i = 0; i < header.enclosures_size(); ++i )
+            enclosures.append( readEnclosure( header.enclosures( i ) ) );
+        item.setEnclosures( enclosures );
+
+       QList<Category> categories;
+        for ( int i = 0; i < header.categories_size(); ++i )
+            categories.append( readCategory( header.categories( i ) ) );
+        item.setCategories( categories );
+
+        QList<Person> authors;
+        for ( int i = 0; i < header.authors_size(); ++i )
+            authors.append( readPerson( header.authors( i ) ) );
+        item.setAuthors( authors );
+
+        item.setCommentsCount( header.commentscount() );
+        item.setCommentsLink( QString::fromUtf8( header.commentslink().c_str() ) );
+        item.setCommentsFeed( QString::fromUtf8( header.commentsfeed().c_str() ) );
+        item.setCommentPostUri( QString::fromUtf8( header.commentposturi().c_str() ) \
); +    }
+
+    item.setHeadersLoaded( readHeaders );
+
+    if ( readContent ) {
+        Protobuf::ItemContent content;
+        const bool parsed = content.ParsePartialFromArray( array.constData(), \
array.size() ); +        if ( !parsed )
+            return false;
+        item.setDescription( QString::fromUtf8( content.description().c_str() ) );
+        item.setContent( QString::fromUtf8( content.content().c_str() ) );
+    }
+
+    item.setContentLoaded( readContent );
+
+    return true;
+}
+
diff --git a/plugins/rssitemserializer_qdatastream.cpp \
b/plugins/rssitemserializer_qdatastream.cpp new file mode 100644
index 0000000..b678056
--- /dev/null
+++ b/plugins/rssitemserializer_qdatastream.cpp
@@ -0,0 +1,166 @@
+/*
+ * This file is part of the krss library
+ *
+ * Copyright (C) 2009 Frank Osterfeld <osterfeld@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "rssitemserializer.h"
+#include "rssitem.h"
+#include "category.h"
+#include "enclosure.h"
+#include "person.h"
+
+#include <KDateTime>
+
+#include <QDataStream>
+
+using namespace KRss;
+
+void RssItemSerializer::serialize( const RssItem& item, QByteArray& ba, ItemPart \
part ) { +    QDataStream stream( &ba, QIODevice::WriteOnly );
+    const bool writeHeaders = ( part & Headers ) != 0;
+    const bool writeContent = ( part & Content ) != 0;
+
+    if ( writeHeaders ) {
+        stream << static_cast<qint64>( item.hash() )
+               << item.guidIsHash()
+               << item.title()
+               << item.datePublished().toString()
+               << item.dateUpdated().toString()
+               << item.guid();
+        stream << static_cast<quint32>( item.authors().count() );
+        Q_FOREACH( const Person& i, item.authors() )
+            stream << i.email() << i.name() << i.uri();
+    }
+    if ( writeContent ) {
+        stream << item.content()
+               << item.description()
+               << item.link()
+                << item.language()
+               << static_cast<qint32>( item.commentsCount() )
+               << item.commentPostUri()
+               << item.commentsFeed()
+               << item.commentsLink();
+        stream << static_cast<quint32>( item.enclosures().count() );
+        Q_FOREACH( const Enclosure& i, item.enclosures() )
+            stream << static_cast<qint32>( i.duration() ) << static_cast<qint32>( \
i.length() ) << i.title() << i.type() << i.url(); +        stream << \
static_cast<quint32>( item.categories().count() ); +        Q_FOREACH( const \
Category& i, item.categories() ) +            stream << i.label() << i.scheme() << \
i.term(); +        const QHash<QString, QString> ap = item.customProperties();
+        stream << static_cast<quint32>( ap.size() );
+        Q_FOREACH( const QString& key, ap.keys() )
+            stream << key << ap.value( key );
+    }
+}
+
+#define READSTRING(name) QString name; stream >> name; item.set##name( name );
+#define READSTRING2(name,target) QString name; stream >> name; target.set##name( \
name ); +#define READ(type,name) type name; stream >> name; item.set##name( name );
+#define READ2(type,name,target) type name; stream >> name; target.set##name( name );
+#define READDATE(name) QString name; stream >> name; item.set##name( \
KDateTime::fromString( name ) ); +
+bool RssItemSerializer::deserialize( RssItem& itemOut, const QByteArray& ba, \
ItemPart part ) { +    const bool readHeaders = ( part & Headers ) != 0;
+    const bool readContent = ( part & Content ) != 0;
+
+    QDataStream stream( ba );
+    RssItem item;
+    if ( readHeaders ) {
+        READ(qint64,Hash)
+        READ(bool,GuidIsHash)
+        READSTRING(Title)
+        READDATE(DatePublished)
+        READDATE(DateUpdated)
+        READSTRING(Guid)
+        quint32 authorCount;
+        stream >> authorCount;
+        QList<Person> authors;
+        for ( quint32 i = 0; i < authorCount; ++i ) {
+            Person auth;
+            READSTRING2(Email, auth)
+            READSTRING2(Name, auth)
+            READSTRING2(Uri, auth)
+            authors.append( auth );
+        }
+        item.setAuthors( authors );
+    }
+    if ( readContent ) {
+        READSTRING(Content)
+        READSTRING(Description)
+        READSTRING(Link)
+
+        READSTRING(Language)
+        READ(qint32,CommentsCount)
+        READSTRING(CommentPostUri)
+        READSTRING(CommentsFeed)
+        READSTRING(CommentsLink)
+        quint32 encCount;
+        stream >> encCount;
+        QList<Enclosure> enclosures;
+        for ( quint32 i = 0; i < encCount; ++i ) {
+            Enclosure enc;
+            READ2(qint32, Duration, enc)
+            READ2(qint32, Length, enc)
+            READSTRING2(Title, enc)
+            READSTRING2(Type, enc)
+            READSTRING2(Url, enc)
+            enclosures.append( enc );
+        }
+        item.setEnclosures( enclosures );
+
+        quint32 catCount = 0;
+        stream >> catCount;
+        QList<Category> categories;
+        for ( quint32 i = 0; i < catCount; ++i ) {
+            Category cat;
+            READSTRING2(Label, cat)
+            READSTRING2(Scheme, cat)
+            READSTRING2(Term, cat)
+            categories.append( cat );
+        }
+        item.setCategories( categories );
+
+
+        quint32 apCount;
+        stream >> apCount;
+        for ( quint32 i = 0; i < apCount; ++i ) {
+            QString key;
+            stream >> key;
+            QString value;
+            stream >> value;
+            item.setCustomProperty( key, value );
+        }
+    }
+    itemOut = item;
+
+    if ( readHeaders )
+        item.setHeadersLoaded( true );
+
+    if ( readContent )
+        item.setContentLoaded( true );
+
+    return true;
+}
+
+#undef READ
+#undef READ2
+#undef READSTRING
+#undef READSTRING2
+#undef READDATE
diff --git a/plugins/rssitemserializer_xml.cpp b/plugins/rssitemserializer_xml.cpp
new file mode 100644
index 0000000..e1136da
--- /dev/null
+++ b/plugins/rssitemserializer_xml.cpp
@@ -0,0 +1,447 @@
+/*
+ * This file is part of the krss library
+ *
+ * Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "rssitemserializer.h"
+#include <krss/category.h>
+#include <krss/enclosure.h>
+#include <krss/rssitem.h>
+#include <krss/person.h>
+
+#include <syndication/atom/constants.h>
+#include <syndication/constants.h>
+
+#include <KDateTime>
+
+#include <QHash>
+#include <QString>
+#include <QVariant>
+#include <QXmlStreamReader>
+#include <QXmlStreamWriter>
+
+using namespace KRss;
+
+namespace {
+
+enum TextMode {
+    PlainText,
+    Html
+};
+
+static QString krssNamespace()
+{
+    return QLatin1String("http://akregator.kde.org/krss#");
+}
+
+class Element
+{
+public:
+    Element( const QString& ns_, const QString& name_, const QVariant& defaultValue_ \
= QVariant() ) : ns( ns_ ), name( name_ ), qualifiedName( ns + QLatin1Char(':') + \
name ), defaultValue( defaultValue_ ) +    {
+    }
+
+    const QString ns;
+    const QString name;
+    const QString qualifiedName;
+    const QVariant defaultValue;
+
+    bool isNextIn( const QXmlStreamReader& reader ) const
+    {
+        return reader.isStartElement() && reader.name() == name && \
reader.namespaceUri() == ns; +    }
+
+    void writeStartElement( QXmlStreamWriter& writer ) const
+    {
+        if ( !ns.isNull() )
+            writer.writeStartElement( ns, name );
+        else
+            writer.writeStartElement( name );
+    }
+
+    void write( const QVariant& value , QXmlStreamWriter& writer, TextMode mode = \
PlainText ) const +    {
+        if ( value == defaultValue )
+            return;
+
+        if ( ns.isEmpty() )
+            writer.writeStartElement( name );
+        else
+            writer.writeStartElement( ns, name );
+        if ( mode == Html )
+        {
+            writer.writeAttribute( QLatin1String("type"), QLatin1String("html") );
+        }
+        const QVariant qv( value );
+        Q_ASSERT( qv.canConvert( QVariant::String ) );
+        writer.writeCharacters( qv.toString() );
+        writer.writeEndElement();
+    }
+};
+
+struct Elements
+{
+    Elements() : atomNS( Syndication::Atom::atom1Namespace() ),
+                 krssNS( krssNamespace() ),
+                 commentNS( Syndication::commentApiNamespace() ),
+                 title( atomNS, QLatin1String("title"), QString() ),
+                 summary( atomNS, QLatin1String("summary"), QString() ),
+                 content( atomNS, QLatin1String("content"), QString() ),
+                 link( atomNS, QLatin1String("link"), QString() ),
+                 language( atomNS, QLatin1String("language"), QString() ),
+                 guid( atomNS, QLatin1String("id"), QString() ),
+                 published( atomNS, QLatin1String("published"), \
KDateTime().toString( KDateTime::ISODate ) ), +                 updated( atomNS, \
QLatin1String("updated"), KDateTime().toString( KDateTime::ISODate ) ), +             \
commentsCount( Syndication::slashNamespace(), QLatin1String("comments"), -1 ), +      \
commentsFeed( commentNS, QLatin1String("commentRss"), QString() ), +                 \
commentPostUri( commentNS, QLatin1String("comment"), QString() ), +                 \
commentsLink( krssNS, QLatin1String("commentsLink"), QString() ), +                 \
hash( krssNS, QLatin1String("hash"), 0 ), +                 guidIsHash( krssNS, \
QLatin1String("idIsHash"), false ), +                 sourceFeedId( krssNS, \
QLatin1String("sourceFeedId"), -1 ), +                 name( atomNS, \
QLatin1String("name"), QString() ), +                 uri( atomNS, \
QLatin1String("uri"), QString() ), +                 email( atomNS, \
QLatin1String("email"), QString() ), +                 author( atomNS, \
QLatin1String("author"), QString() ), +                 category( atomNS, \
QLatin1String("category"), QString() ), +                 customProperty( krssNS, \
QLatin1String("customProperty"), QString() ), +                 key( krssNS, \
QLatin1String("key"), QString() ), +                 value( krssNS, \
QLatin1String("value"), QString() ), +                 entry( atomNS, \
QLatin1String("entry"), QString() ) +{}
+    const QString atomNS;
+    const QString krssNS;
+    const QString commentNS;
+    const Element title;
+    const Element summary;
+    const Element content;
+    const Element link;
+    const Element language;
+    const Element guid;
+    const Element published;
+    const Element updated;
+    const Element commentsCount;
+    const Element commentsFeed;
+    const Element commentPostUri;
+    const Element commentsLink;
+    const Element hash;
+    const Element guidIsHash;
+    const Element sourceFeedId;
+    const Element name;
+    const Element uri;
+    const Element email;
+    const Element author;
+    const Element category;
+    const Element customProperty;
+    const Element key;
+    const Element value;
+    const Element entry;
+    static const Elements instance;
+};
+
+const Elements Elements::instance;
+
+static void writeAttributeIfNotEmpty( const QString& ns, const QString& element, \
const QVariant& value, QXmlStreamWriter& writer ) +{
+    const QString text = value.toString();
+    if ( text.isEmpty() )
+        return;
+    writer.writeAttribute( ns, element, text );
+}
+
+static void writeAttributeIfNotEmpty( const QString& element, const QVariant& value, \
QXmlStreamWriter& writer ) +{
+    const QString text = value.toString();
+    if ( text.isEmpty() )
+        return;
+    writer.writeAttribute( element, text );
+}
+
+static void writeLink( const QString& url, QXmlStreamWriter& writer )
+{
+    if ( url.isEmpty() )
+        return;
+    Elements::instance.link.writeStartElement( writer );
+    writer.writeAttribute( QLatin1String("rel"), QLatin1String("alternate") );
+    writeAttributeIfNotEmpty( QLatin1String("href"), url, writer );
+    writer.writeEndElement();
+}
+
+static void writeCategory( const KRss::Category& category, QXmlStreamWriter& writer \
) +{
+    Elements::instance.category.writeStartElement( writer );
+    writeAttributeIfNotEmpty( QLatin1String("term"), category.term(), writer );
+    writeAttributeIfNotEmpty( QLatin1String("scheme"), category.scheme(), writer );
+    writeAttributeIfNotEmpty( QLatin1String("label"), category.label(), writer );
+    writer.writeEndElement();
+}
+
+static void writeAuthor( const KRss::Person& person, QXmlStreamWriter& writer )
+{
+    const QString atomNS = Syndication::Atom::atom1Namespace();
+    Elements::instance.author.writeStartElement( writer );
+    Elements::instance.name.write( person.name(), writer );
+    Elements::instance.uri.write( person.uri(), writer );
+    Elements::instance.email.write( person.email(), writer );
+    writer.writeEndElement();
+}
+
+static void writeEnclosure( const KRss::Enclosure& enclosure, QXmlStreamWriter& \
writer ) +{
+    Elements::instance.link.writeStartElement( writer );
+    writeAttributeIfNotEmpty( QLatin1String("rel"), QLatin1String("enclosure"), \
writer ); +    writeAttributeIfNotEmpty( QLatin1String("href"), enclosure.url(), \
writer ); +    writeAttributeIfNotEmpty( QLatin1String("title"), enclosure.title(), \
writer ); +    writeAttributeIfNotEmpty( QLatin1String("length"), enclosure.length(), \
writer ); +    writeAttributeIfNotEmpty( QLatin1String("type"), enclosure.type(), \
writer ); +    const uint duration = enclosure.duration();
+    if ( duration != 0 )
+        writer.writeAttribute( Syndication::itunesNamespace(), \
QLatin1String("duration"), QString::number( duration ) ); +    \
writer.writeEndElement(); +}
+
+static void writeItemHeaders( const KRss::RssItem& item, QXmlStreamWriter& writer )
+{
+    Elements::instance.title.write( item.title(), writer, Html );
+    writeLink( item.link(), writer );
+    Elements::instance.guid.write( item.guid(), writer );
+
+    const KDateTime updated = item.dateUpdated();
+    const KDateTime published = item.datePublished();
+    Elements::instance.published.write( published.toString( KDateTime::ISODate ), \
writer ); +    if ( updated.isValid() && updated != published )
+        Elements::instance.updated.write( updated.toString( KDateTime::ISODate ), \
writer ); +
+    Q_FOREACH( const KRss::Category& i, item.categories() )
+        writeCategory( i, writer );
+
+    Q_FOREACH( const KRss::Person& i, item.authors() )
+        writeAuthor( i, writer );
+
+    Q_FOREACH( const KRss::Enclosure& i, item.enclosures() )
+        writeEnclosure( i, writer );
+
+    Elements::instance.hash.write( item.hash(), writer );
+    Elements::instance.guidIsHash.write( item.guidIsHash(), writer );
+    Elements::instance.sourceFeedId.write( item.sourceFeedId(), writer );
+
+}
+
+static void writeItemContent( const KRss::RssItem& item, QXmlStreamWriter& writer )
+{
+    const QString description = item.description();
+    Elements::instance.summary.write( description, writer, Html );
+    const QString content = item.content();
+    if ( content != description )
+        Elements::instance.content.write( content, writer, Html );
+    Elements::instance.language.write( item.language(), writer );
+    Elements::instance.commentsFeed.write( item.commentsFeed(), writer );
+    Elements::instance.commentPostUri.write( item.commentPostUri(), writer );
+    Elements::instance.commentsCount.write( item.commentsCount(), writer );
+    Elements::instance.commentsLink.write( item.commentsLink(), writer );
+    const QHash<QString, QString> props = item.customProperties();
+    QHash<QString, QString>::const_iterator it = props.constBegin();
+    while ( it != props.constEnd() )
+    {
+        Elements::instance.customProperty.writeStartElement( writer );
+        Elements::instance.key.write( it.key(), writer );
+        Elements::instance.value.write( it.value(), writer );
+        writer.writeEndElement();
+        ++it;
+    }
+}
+
+static void writeItem( const KRss::RssItem& item, QXmlStreamWriter& writer, \
KRss::RssItemSerializer::ItemPart part ) +{
+    const QString atomNS = Syndication::Atom::atom1Namespace();
+    const QString commentNS = Syndication::commentApiNamespace();
+    const QString krssNS = krssNamespace();
+    writer.writeDefaultNamespace( atomNS );
+    writer.writeNamespace( commentNS, QLatin1String("comment") );
+    writer.writeNamespace( krssNS, QLatin1String("krss") );
+    writer.writeNamespace( Syndication::itunesNamespace(), QLatin1String("itunes") \
); +
+    Elements::instance.entry.writeStartElement( writer );
+    if ( ( part & RssItemSerializer::Headers ) != 0 )
+        writeItemHeaders( item, writer );
+    if ( ( part & RssItemSerializer::Content ) != 0 )
+        writeItemContent( item, writer );
+
+    writer.writeEndElement();   // Entry
+}
+
+static void readLink( KRss::RssItem& item, QXmlStreamReader& reader )
+{
+    const QXmlStreamAttributes attrs = reader.attributes();
+    const QString rel = attrs.value( QString(), QLatin1String("rel") ).toString();
+    if (  rel == QLatin1String("alternate") )
+    {
+        item.setLink( attrs.value( QString(), QLatin1String("href") ).toString() );
+    }
+    else if ( rel == QLatin1String("enclosure") )
+    {
+        KRss::Enclosure enc;
+        enc.setUrl( attrs.value( QString(), QLatin1String("href") ).toString() );
+        enc.setType( attrs.value( QString(), QLatin1String("type") ).toString() );
+        enc.setTitle( attrs.value( QString(), QLatin1String("title") ).toString() );
+        bool ok;
+        const uint length = attrs.value( QString(), QLatin1String("length") \
).toString().toUInt( &ok ); +        if ( ok )
+            enc.setLength( length );
+        const uint duration = attrs.value( Syndication::itunesNamespace(), \
QLatin1String("duration") ).toString().toUInt( &ok ); +        if ( ok )
+            enc.setDuration( duration );
+        QList<KRss::Enclosure> encs = item.enclosures();
+        encs.append( enc );
+        item.setEnclosures( encs );
+    }
+}
+
+static void readAuthor( KRss::RssItem& item, QXmlStreamReader& reader )
+{
+    KRss::Person author;
+    int depth = 1;
+    while ( !reader.atEnd() && depth > 0 )
+    {
+        reader.readNext();
+        if ( reader.isEndElement() )
+            --depth;
+        else if ( reader.isStartElement() )
+        {
+            if ( Elements::instance.name.isNextIn( reader ) )
+                author.setName( reader.readElementText() );
+            else if ( Elements::instance.uri.isNextIn( reader ) )
+                author.setUri( reader.readElementText() );
+            else if ( Elements::instance.email.isNextIn( reader ) )
+                author.setEmail( reader.readElementText() );
+        }
+
+    }
+    QList<KRss::Person> authors = item.authors();
+    authors.append( author );
+    item.setAuthors( authors );
+}
+
+static void readCategory( KRss::RssItem& item, QXmlStreamReader& reader )
+{
+    const QXmlStreamAttributes attrs = reader.attributes();
+    KRss::Category cat;
+    cat.setTerm( attrs.value( QString(), QLatin1String("term") ).toString() );
+    cat.setScheme( attrs.value( QString(), QLatin1String("scheme") ).toString() );
+    cat.setLabel( attrs.value( QString(), QLatin1String("label") ).toString() );
+    QList<KRss::Category> cats = item.categories();
+    cats.append( cat );
+    item.setCategories( cats );
+}
+
+static void readCustomProperty( KRss::RssItem& item, QXmlStreamReader& reader )
+{
+    QString key;
+    QString value;
+    int depth = 1;
+    while ( !reader.atEnd() && depth > 0 )
+    {
+        reader.readNext();
+        if ( reader.isEndElement() )
+            --depth;
+        else if ( reader.isStartElement() )
+        {
+            if ( Elements::instance.key.isNextIn( reader ) )
+                key = reader.readElementText();
+            else if ( Elements::instance.value.isNextIn( reader ) )
+                value = reader.readElementText();
+        }
+    }
+    item.setCustomProperty( key, value );
+}
+
+} // namespace
+
+void KRss::RssItemSerializer::serialize( const KRss::RssItem& item, QByteArray& \
array, ItemPart part ) +{
+    QXmlStreamWriter writer( &array );
+    writer.writeStartDocument();
+    ::writeItem( item, writer, part );
+    writer.writeEndDocument();
+}
+
+bool KRss::RssItemSerializer::deserialize( KRss::RssItem& item, const QByteArray& \
array, ItemPart part ) +{
+    QXmlStreamReader reader( array );
+    reader.setNamespaceProcessing( true );
+
+    const bool readHeaders = ( part & Headers ) != 0;
+    const bool readContent = ( part & Content ) != 0;
+
+    if ( readHeaders )
+        item.setHeadersLoaded( true );
+
+    if ( readContent )
+        item.setContentLoaded( true );
+
+    while ( !reader.atEnd() )
+    {
+        reader.readNext();
+        if ( reader.isStartElement() )
+        {
+            if ( readContent ) {
+                if ( Elements::instance.summary.isNextIn( reader )  )
+                    item.setDescription( reader.readElementText() );
+                else if ( Elements::instance.content.isNextIn( reader ) )
+                    item.setContent( reader.readElementText() );
+                else if ( Elements::instance.language.isNextIn( reader ) )
+                    item.setLanguage( reader.readElementText() );
+                else if ( Elements::instance.commentsLink.isNextIn( reader ) )
+                    item.setCommentsLink( reader.readElementText() );
+                else if ( Elements::instance.commentPostUri.isNextIn( reader ) )
+                    item.setCommentPostUri( reader.readElementText() );
+                else if ( Elements::instance.commentsCount.isNextIn( reader ) )
+                    item.setCommentsCount( reader.readElementText().toInt() );
+                else if ( Elements::instance.commentsFeed.isNextIn( reader ) )
+                    item.setCommentsFeed( reader.readElementText() );
+                else if ( Elements::instance.customProperty.isNextIn( reader ) )
+                    ::readCustomProperty( item, reader );
+            }
+            if ( readHeaders ) {
+                if ( Elements::instance.title.isNextIn( reader ) )
+                    item.setTitle( reader.readElementText() );
+                else if ( Elements::instance.guid.isNextIn( reader ) )
+                    item.setGuid( reader.readElementText() );
+                else if ( Elements::instance.hash.isNextIn( reader ) )
+                    item.setHash( reader.readElementText().toInt() );
+                else if ( Elements::instance.guidIsHash.isNextIn( reader ) )
+                    item.setGuidIsHash( QVariant( reader.readElementText() \
).toBool() ); +                else if ( Elements::instance.sourceFeedId.isNextIn( \
reader ) ) +                    item.setSourceFeedId( \
reader.readElementText().toInt() ); +                else if ( \
Elements::instance.link.isNextIn( reader ) ) +                    ::readLink( item, \
reader ); +                else if ( Elements::instance.author.isNextIn( reader ) )
+                    ::readAuthor( item, reader );
+                else if ( Elements::instance.category.isNextIn( reader ) )
+                    ::readCategory( item, reader );
+                else if ( Elements::instance.published.isNextIn( reader ) )
+                    item.setDatePublished( KDateTime::fromString( \
reader.readElementText(), KDateTime::ISODate ) ); +                else if ( \
Elements::instance.updated.isNextIn( reader ) ) +                    \
item.setDateUpdated( KDateTime::fromString( reader.readElementText(), \
KDateTime::ISODate ) ); +            }
+        }
+    }
+    return !reader.hasError();
+}
diff --git a/plugins/tests/CMakeLists.txt b/plugins/tests/CMakeLists.txt
new file mode 100644
index 0000000..bce1783
--- /dev/null
+++ b/plugins/tests/CMakeLists.txt
@@ -0,0 +1,52 @@
+set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}/..
+    ${CMAKE_CURRENT_SOURCE_DIR}/../krss
+)
+
+macro(add_simple_test _testName)
+  set(_targetName ${_testName})
+  set(_srcList ${ARGN})
+  kde4_add_unit_test(${_targetName} ${_srcList})
+  target_link_libraries(${_targetName} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} \
${QT_QTTEST_LIBRARY} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_SYNDICATION_LIBS} \
${KDE4_KDECORE_LIBS} krss) +endmacro(add_simple_test)
+
+set(testxmlitemserializer_SRCS
+    testxmlitemserializer.cpp
+)
+
+if(KRSS_ENABLE_PROTOBUF_SERIALIZER)
+    WRAP_PROTO(krss_LIB_PROTOBUF_SRCS krss.proto)
+
+    set(testxmlitemserializer_SRCS
+        ${testxmlitemserializer_SRCS}
+        ${krss_LIB_PROTOBUF_SRCS}
+        ${CMAKE_CURRENT_SOURCE_DIR}/../rssitemserializer_protobuf.cpp
+    )
+    set(KRSS_EXTRA_LIBS ${PROTOBUF_LIBRARY})
+else(KRSS_ENABLE_PROTOBUF_SERIALIZER)
+if(KRSS_ENABLE_QDATASTREAM_SERIALIZER)
+    set(testxmlitemserializer_SRCS
+        ${testxmlitemserializer_SRCS}
+        ${CMAKE_CURRENT_SOURCE_DIR}/../rssitemserializer_qdatastream.cpp
+    )
+    set(KRSS_EXTRA_LIBS ${PROTOBUF_LIBRARY})
+else(KRSS_ENABLE_QDATASTREAM_SERIALIZER)
+if(KRSS_ENABLE_JSON_SERIALIZER)
+   set(testxmlitemserializer_SRCS
+       ${testxmlitemserializer_SRCS}
+       ${CMAKE_CURRENT_SOURCE_DIR}/../rssitemserializer_json.cpp
+   )
+   set(KRSS_EXTRA_LIBS qjson)
+else(KRSS_ENABLE_JSON_SERIALIZER)
+   set(testxmlitemserializer_SRCS
+       ${testxmlitemserializer_SRCS}
+       ${CMAKE_CURRENT_SOURCE_DIR}/../rssitemserializer_xml.cpp
+   )
+endif(KRSS_ENABLE_JSON_SERIALIZER)
+endif(KRSS_ENABLE_QDATASTREAM_SERIALIZER)
+endif(KRSS_ENABLE_PROTOBUF_SERIALIZER)
+
+add_simple_test(testxmlitemserializer ${testxmlitemserializer_SRCS})
diff --git a/plugins/tests/testxmlitemserializer.cpp \
b/plugins/tests/testxmlitemserializer.cpp new file mode 100644
index 0000000..f333015
--- /dev/null
+++ b/plugins/tests/testxmlitemserializer.cpp
@@ -0,0 +1,198 @@
+/*
+ * This file is part of the krss library
+ *
+ * Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "testxmlitemserializer.h"
+
+#include <krss/enclosure.h>
+#include <krss/person.h>
+#include <krss/category.h>
+#include <krss/item.h>
+#include <krss/rssitem.h>
+#include "rssitemserializer.h"
+
+#include <KDateTime>
+
+#include <qtest_kde.h>
+
+#include <QDebug>
+#include <QByteArray>
+#include <QVariant>
+
+using namespace KRss;
+
+namespace {
+
+void printItem( const RssItem& item )
+{
+    QByteArray ba;
+    RssItemSerializer::serialize( item, ba );
+    qDebug() << ba.size() << ba;
+}
+
+void testItem( const RssItem& item )
+{
+    const bool headersLoaded = item.headersLoaded();
+    const bool contentLoaded = item.contentLoaded();
+    QByteArray ba;
+    RssItemSerializer::serialize( item, ba );
+    RssItem deserialized;
+    const bool success = RssItemSerializer::deserialize( deserialized, ba );
+    QVERIFY2( success, "Deserialization failed" );
+    deserialized.setContentLoaded( contentLoaded );
+    deserialized.setHeadersLoaded( headersLoaded );
+    if ( item != deserialized )
+    {
+        printItem( item );
+        printItem( deserialized );
+    }
+    QCOMPARE( item, deserialized );
+}
+
+}
+
+void TestXmlItemSerializer::testEmptyItem()
+{
+    ::testItem( RssItem() );
+}
+
+void TestXmlItemSerializer::testDates()
+{
+    RssItem item;
+    const KDateTime updated = KDateTime::currentLocalDateTime();
+    const KDateTime published = updated.addDays( -4 );
+    item.setDatePublished( published );
+    item.setDateUpdated( updated );
+    ::testItem( item );
+}
+
+void TestXmlItemSerializer::testSimpleItems()
+{
+    RssItem item;
+    item.setTitle( QLatin1String("Some title") );
+    item.setDescription( QLatin1String("Some description") );
+    item.setLink( QLatin1String("http://akregator.kde.org") );
+    item.setContent( QLatin1String("Content makes the world go round") );
+    item.setGuid( QLatin1String("http://uniqueid") );
+    item.setGuidIsHash( true );
+    item.setLanguage( QLatin1String("en") );
+    item.setHash( 5 );
+    ::testItem( item );
+    item.setHash( 0 );
+    ::testItem( item );
+}
+
+void TestXmlItemSerializer::testStatus()
+{
+#if 0
+    RssItem item;
+    item.setStatus( Read );
+    ::testItem( item );
+    item.setStatus( New );
+    ::testItem( item );
+    item.setStatus( Important );
+    ::testItem( item );
+    item.setStatus( Read | Important );
+    ::testItem( item );
+#endif
+}
+
+void TestXmlItemSerializer::testCustomProperties()
+{
+    RssItem item;
+    item.setGuid( QLatin1String("http://uniqueid") );
+    item.setTitle( QLatin1String("Some title") );
+    item.setDescription( QLatin1String("Some description") );
+    item.setLink( QLatin1String("http://akregator.kde.org") );
+    item.setCustomProperty( QLatin1String("foo"), QLatin1String("bar") );
+    item.setCustomProperty( QLatin1String("bar"), QLatin1String("foo") );
+    item.setCustomProperty( QLatin1String("foobar"), QString() );
+    ::testItem( item );
+}
+
+void TestXmlItemSerializer::testEnclosures()
+{
+    RssItem item;
+    item.setLink( QLatin1String("http://akregator.kde.org") );
+    Enclosure enc;
+    enc.setUrl( QLatin1String("http://akregator.kde.org/some.mp3") );
+    enc.setType( QLatin1String("audio/mpeg") );
+    enc.setTitle( QLatin1String("This is an enclosure!") );
+    enc.setLength( 123456789 );
+    Enclosure enc2 = enc;
+    enc.setDuration( 60 );
+    QList<Enclosure> encs;
+    encs.append( enc );
+    encs.append( enc2 );
+    item.setEnclosures( encs );
+    ::testItem( item );
+}
+
+void TestXmlItemSerializer::testCategories()
+{
+    Category cat;
+    cat.setTerm( QLatin1String("term1") );
+    cat.setScheme( QLatin1String("http://Blabla#") );
+    cat.setLabel( QLatin1String("Term 1") );
+    Category cat2;
+    cat2.setTerm( QLatin1String("Term2") );
+    cat2.setLabel( QLatin1String("Tada") );
+    QList<Category> cats;
+    cats.append( cat );
+    cats.append( cat2 );
+    cats.append( Category() );
+    RssItem item;
+    item.setCategories( cats );
+    ::testItem( item );
+}
+
+void TestXmlItemSerializer::testAuthors()
+{
+    Person a1;
+    a1.setName( QLatin1String("John Doe") );
+    Person a2;
+    a2.setName( QLatin1String("John Doe") );
+    a2.setUri( QLatin1String("http://doeweb.net/John") );
+    a2.setEmail( QLatin1String("joe@doeweb.net") );
+    Person a3;
+    QList<Person> authors;
+    authors.append( a1 );
+    authors.append( a2 );
+    authors.append( a3 );
+    RssItem item;
+    item.setAuthors( authors );
+    ::testItem( item );
+}
+
+void TestXmlItemSerializer::testComments()
+{
+    RssItem item;
+    item.setCommentsCount( 10 );
+    item.setCommentsLink( QLatin1String("http://heyho#comment") );
+    item.setCommentsFeed( QLatin1String("http://heyho/comments.rss") );
+    item.setCommentPostUri( QLatin1String("http://whatever") );
+    ::testItem( item );
+}
+
+
+QTEST_KDEMAIN( TestXmlItemSerializer, NoGUI )
+
+#include "testxmlitemserializer.moc"
diff --git a/plugins/tests/testxmlitemserializer.h \
b/plugins/tests/testxmlitemserializer.h new file mode 100644
index 0000000..427161c
--- /dev/null
+++ b/plugins/tests/testxmlitemserializer.h
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the kfeed library
+ *
+ * Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TESTXMLITEMSERIALIZER_H
+#define TESTXMLITEMSERIALIZER_H
+
+#include <QObject>
+
+class TestXmlItemSerializer : public QObject {
+    Q_OBJECT
+private:
+
+private Q_SLOTS:
+    void testEmptyItem();
+    void testSimpleItems();
+    void testEnclosures();
+    void testCategories();
+    void testAuthors();
+    void testComments();
+    void testDates();
+    void testStatus();
+    void testCustomProperties();
+};
+
+#endif // TESTXMLITEMSERIALIZER_H


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic