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
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.