• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.5 API Reference
  • KDE Home
  • Contact Us
 

akonadi

item_p.h
00001 /*
00002     Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #ifndef AKONADI_ITEM_P_H
00021 #define AKONADI_ITEM_P_H
00022 
00023 #include <QtCore/QDateTime>
00024 #include <QtCore/QMap>
00025 #include <QtCore/QVarLengthArray>
00026 
00027 #include "entity_p.h"
00028 #include "itempayloadinternals_p.h"
00029 
00030 #include <boost/bind.hpp>
00031 
00032 #include <memory>
00033 #include <algorithm>
00034 #include <cassert>
00035 #include <vector>
00036 
00037 namespace Akonadi {
00038 
00039 namespace _detail {
00040 
00041     template <typename T>
00042     class clone_ptr {
00043         T * t;
00044     public:
00045         clone_ptr() : t( 0 ) {}
00046         explicit clone_ptr( T * t ) : t( t ) {}
00047         clone_ptr( const clone_ptr & other ) : t ( other.t ? other.t->clone() : 0 ) {}
00048         ~clone_ptr() { delete t; }
00049         clone_ptr & operator=( const clone_ptr & other ) {
00050             if ( this != &other ) {
00051                 clone_ptr copy( other );
00052                 swap( copy );
00053             }
00054             return *this;
00055         }
00056         void swap( clone_ptr & other ) {
00057             using std::swap;
00058             swap( t, other.t );
00059         }
00060         T * operator->() const { return get(); }
00061         T & operator*() const { assert( get() != 0 ); return *get(); }
00062         T * get() const { return t; }
00063         T * release() { T * const r = t; t = 0; return r; }
00064         void reset( T * other=0 ) { delete t; t = other; }
00065 
00066     private:
00067         struct _save_bool { void f() {}; };
00068         typedef void (_save_bool::*save_bool)();
00069     public:
00070         operator save_bool () const { return get() ? &_save_bool::f : 0 ; }
00071     };
00072 
00073     template <typename T>
00074     inline void swap( clone_ptr<T> & lhs, clone_ptr<T> & rhs ) {
00075         lhs.swap( rhs );
00076     }
00077 
00078     template <typename T, size_t N>
00079     class VarLengthArray {
00080         QVarLengthArray<T,N> impl; // ###should be replaced by self-written container that doesn't waste so much space
00081     public:
00082         typedef T value_type;
00083         typedef T* iterator;
00084         typedef const T* const_iterator;
00085         typedef T* pointer;
00086         typedef const T* const_pointer;
00087         typedef T & reference;
00088         typedef const T & const_reference;
00089 
00090         explicit VarLengthArray( int size=0 ) : impl( size ) {}
00091         // compiler-generated dtor, copy ctor, copy assignment are ok
00092         // swap() makes little sense
00093 
00094         void push_back( const T & t ) { impl.append( t ); }
00095         int capacity() const          { return impl.capacity(); }
00096         void clear()                  { impl.clear(); }
00097         size_t size() const           { return impl.count(); }
00098         bool empty() const            { return impl.isEmpty(); }
00099         void pop_back()               { return impl.removeLast(); }
00100         void reserve( size_t n )      { impl.reserve( n ); }
00101         void resize( size_t n )       { impl.resize( n ); }
00102 
00103         iterator begin()              { return impl.data(); }
00104         iterator end()                { return impl.data() + impl.size(); }
00105         const_iterator begin()  const { return impl.data(); }
00106         const_iterator end()    const { return impl.data() + impl.size(); }
00107         const_iterator cbegin() const { return begin(); }
00108         const_iterator cend()   const { return end(); }
00109 
00110         reference       front()       { return *impl.data(); }
00111         reference       back()        { return *(impl.data()+impl.size()); }
00112         const_reference front() const { return *impl.data(); }
00113         const_reference back()  const { return *(impl.data()+impl.size()); }
00114 
00115         reference       operator[]( size_t n )       { return impl[n]; }
00116         const_reference operator[]( size_t n ) const { return impl[n]; }
00117     };
00118 
00119     struct TypedPayload {
00120         clone_ptr<PayloadBase> payload;
00121         int sharedPointerId;
00122         int metaTypeId;
00123     };
00124 
00125     struct BySharedPointerAndMetaTypeID : std::unary_function<TypedPayload,bool> {
00126         const int spid;
00127         const int mtid;
00128         BySharedPointerAndMetaTypeID( int spid, int mtid ) : spid( spid ), mtid( mtid ) {}
00129         bool operator()( const TypedPayload & tp ) const {
00130             return ( mtid == -1 || mtid == tp.metaTypeId )
00131                 && ( spid == -1 || spid == tp.sharedPointerId ) ;
00132         }
00133     };
00134 
00135 }
00136 
00137 } // namespace Akonadi
00138 
00139 namespace std {
00140     template <>
00141     inline void swap<Akonadi::_detail::TypedPayload>( Akonadi::_detail::TypedPayload & lhs, Akonadi::_detail::TypedPayload & rhs ) {
00142         lhs.payload.swap( rhs.payload );
00143         swap( lhs.sharedPointerId, rhs.sharedPointerId );
00144         swap( lhs.metaTypeId, rhs.metaTypeId );
00145     }
00146 }
00147 
00148 namespace Akonadi {
00149 //typedef _detail::VarLengthArray<_detail::TypedPayload,2> PayloadContainer;
00150 typedef std::vector<_detail::TypedPayload> PayloadContainer;
00151 }
00152 
00153 // disable Q_FOREACH on PayloadContainer (b/c it likes to take copies and clone_ptr doesn't like that)
00154 template <>
00155 class QForeachContainer<Akonadi::PayloadContainer> {};
00156 
00157 namespace Akonadi {
00158 
00159 
00163 class ItemPrivate : public EntityPrivate
00164 {
00165   public:
00166     ItemPrivate( Item::Id id = -1 )
00167       : EntityPrivate( id ),
00168         mLegacyPayload(),
00169         mPayloads(),
00170         mConversionInProgress( false ),
00171         mRevision( -1 ),
00172         mCollectionId( -1 ),
00173         mSize( 0 ),
00174         mModificationTime(),
00175         mFlagsOverwritten( false ),
00176         mSizeChanged( false ),
00177         mClearPayload( false )
00178     {
00179     }
00180 
00181 #if 0
00182     ItemPrivate( const ItemPrivate &other )
00183         : EntityPrivate( other )
00184     {
00185       mFlags = other.mFlags;
00186       mRevision = other.mRevision;
00187       mSize = other.mSize;
00188       mModificationTime = other.mModificationTime;
00189       mMimeType = other.mMimeType;
00190       mLegacyPayload = other.mLegacyPayload;
00191       mPayloads = other.mPayloads;
00192       mConversionInProgress = false;
00193       mAddedFlags = other.mAddedFlags;
00194       mDeletedFlags = other.mDeletedFlags;
00195       mFlagsOverwritten = other.mFlagsOverwritten;
00196       mSizeChanged = other.mSizeChanged;
00197       mCollectionId = other.mCollectionId;
00198       mClearPayload = other.mClearPayload;
00199     }
00200 #endif
00201 
00202     ~ItemPrivate()
00203     {
00204     }
00205 
00206     void resetChangeLog()
00207     {
00208       mFlagsOverwritten = false;
00209       mAddedFlags.clear();
00210       mDeletedFlags.clear();
00211       mSizeChanged = false;
00212     }
00213 
00214     EntityPrivate *clone() const
00215     {
00216       return new ItemPrivate( *this );
00217     }
00218 
00219     bool hasMetaTypeId( int mtid ) const {
00220         return std::find_if( mPayloads.begin(), mPayloads.end(),
00221                              _detail::BySharedPointerAndMetaTypeID( -1, mtid ) )
00222             != mPayloads.end();
00223     }
00224 
00225     PayloadBase * payloadBaseImpl( int spid, int mtid ) const {
00226         const PayloadContainer::const_iterator it
00227             = std::find_if( mPayloads.begin(), mPayloads.end(),
00228                             _detail::BySharedPointerAndMetaTypeID( spid, mtid ) );
00229         return it == mPayloads.end() ? 0 : it->payload.get() ;
00230     }
00231 
00232     bool movePayloadFrom( ItemPrivate * other, int mtid ) const /*sic!*/ {
00233       assert( other );
00234       const size_t oldSize = mPayloads.size();
00235       PayloadContainer & oPayloads = other->mPayloads;
00236       const _detail::BySharedPointerAndMetaTypeID matcher( -1, mtid );
00237       const size_t numMatching
00238         = std::count_if( oPayloads.begin(), oPayloads.end(), matcher );
00239       mPayloads.resize( oldSize + numMatching );
00240       using namespace std; // for swap()
00241       for ( PayloadContainer::iterator
00242               dst = mPayloads.begin() + oldSize,
00243               src = oPayloads.begin(), end = oPayloads.end() ; src != end ; ++src )
00244         if ( matcher( *src ) ) {
00245           swap( *dst, *src );
00246           ++dst;
00247         }
00248       return numMatching > 0 ;
00249     }
00250 
00251 #if 0
00252     std::auto_ptr<PayloadBase> takePayloadBaseImpl( int spid, int mtid ) {
00253         PayloadContainer::iterator it
00254             = std::find_if( mPayloads.begin(), mPayloads.end(),
00255                             _detail::BySharedPointerAndMetaTypeID( spid, mtid ) );
00256         if ( it == mPayloads.end() )
00257             return std::auto_ptr<PayloadBase>();
00258         std::rotate( it, it + 1, mPayloads.end() );
00259         std::auto_ptr<PayloadBase> result( it->payload.release() );
00260         mPayloads.pop_back();
00261         return result;
00262     }
00263 #endif
00264 
00265     void setPayloadBaseImpl( int spid, int mtid, std::auto_ptr<PayloadBase> p, bool add ) const /*sic!*/ {
00266 
00267         if ( !add )
00268             mLegacyPayload.reset();
00269 
00270         if ( !p.get() ) {
00271             if ( !add )
00272                 mPayloads.clear();
00273             return;
00274         }
00275 
00276         // if !add, delete all payload variants
00277         // (they're conversions of each other)
00278         mPayloads.resize( add ? mPayloads.size() + 1 : 1 );
00279         _detail::TypedPayload & tp = mPayloads.back();
00280         tp.payload.reset( p.release() );
00281         tp.sharedPointerId = spid;
00282         tp.metaTypeId = mtid;
00283     }
00284 
00285     void setLegacyPayloadBaseImpl( std::auto_ptr<PayloadBase> p );
00286     void tryEnsureLegacyPayload() const;
00287 
00288     mutable _detail::clone_ptr<PayloadBase> mLegacyPayload;
00289     mutable PayloadContainer mPayloads;
00290     mutable bool mConversionInProgress;
00291     Item::Flags mFlags;
00292     int mRevision;
00293     Entity::Id mCollectionId;
00294     qint64 mSize;
00295     QDateTime mModificationTime;
00296     QString mMimeType;
00297     Item::Flags mAddedFlags;
00298     Item::Flags mDeletedFlags;
00299     bool mFlagsOverwritten : 1;
00300     bool mSizeChanged : 1;
00301     bool mClearPayload : 1;
00302 };
00303 
00304 }
00305 
00306 #endif
00307 
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:22 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs-4.8.5 API Reference

Skip menu "kdepimlibs-4.8.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal