00001 /* 00002 * This file is part of Soprano Project. 00003 * 00004 * Copyright (C) 2006 Daniele Galdi <daniele.galdi@gmail.com> 00005 * Copyright (C) 2007 Sebastian Trueg <trueg@kde.org> 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Library General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Library General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Library General Public License 00018 * along with this library; see the file COPYING.LIB. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #ifndef SOPRANO_ITERATOR_H 00024 #define SOPRANO_ITERATOR_H 00025 00026 #include <QtCore/QSharedDataPointer> 00027 #include <QtCore/QList> 00028 00029 #include "iteratorbackend.h" 00030 #include "error.h" 00031 00032 namespace Soprano { 00033 00076 template<typename T> class Iterator : public Error::ErrorCache 00077 { 00078 public: 00082 Iterator(); 00083 00088 Iterator( IteratorBackend<T> *sti ); 00089 00090 Iterator( const Iterator &sti ); 00091 00092 virtual ~Iterator(); 00093 00094 Iterator& operator=( const Iterator& ); 00095 00099 void close(); 00100 00106 bool next(); 00107 00114 T current() const; 00115 00124 T operator*() const; 00125 00130 bool isValid() const; 00131 00141 QList<T> allElements(); 00142 00143 protected: 00149 void setBackend( IteratorBackend<T>* b ); 00150 00151 IteratorBackend<T>* backend() const; 00152 00153 private: 00154 class Private; 00155 QSharedDataPointer<Private> d; 00156 }; 00157 } 00158 00159 00161 template<typename T> class Soprano::Iterator<T>::Private : public QSharedData 00162 { 00163 public: 00164 Private() 00165 : backend( 0 ) { 00166 } 00167 00168 ~Private() { 00169 if( backend ) { 00170 backend->close(); 00171 delete backend; 00172 } 00173 } 00174 00175 IteratorBackend<T>* backend; 00176 }; 00177 00178 00179 template<typename T> Soprano::Iterator<T>::Iterator() 00180 : Error::ErrorCache(), 00181 d( new Private() ) 00182 00183 { 00184 } 00185 00186 template<typename T> Soprano::Iterator<T>::Iterator( IteratorBackend<T> *sti ) 00187 : Error::ErrorCache(), 00188 d( new Private() ) 00189 { 00190 d->backend = sti; 00191 } 00192 00193 template<typename T> Soprano::Iterator<T>::Iterator( const Iterator<T> &other ) 00194 : Error::ErrorCache(), 00195 d( other.d ) 00196 { 00197 } 00198 00199 template<typename T> Soprano::Iterator<T>::~Iterator() 00200 { 00201 } 00202 00203 template<typename T> Soprano::Iterator<T>& Soprano::Iterator<T>::operator=( const Iterator<T>& other ) 00204 { 00205 d = other.d; 00206 return *this; 00207 } 00208 00209 template<typename T> void Soprano::Iterator<T>::setBackend( IteratorBackend<T>* b ) 00210 { 00211 if ( d->backend != b ) { 00212 // now we want it to detach 00213 d->backend = b; 00214 } 00215 } 00216 00217 template<typename T> Soprano::IteratorBackend<T>* Soprano::Iterator<T>::backend() const 00218 { 00219 return d->backend; 00220 } 00221 00222 template<typename T> void Soprano::Iterator<T>::close() 00223 { 00224 // some evil hacking to avoid detachment of the shared data 00225 if( isValid() ) { 00226 const Private* cd = d.constData(); 00227 cd->backend->close(); 00228 setError( cd->backend->lastError() ); 00229 } 00230 else { 00231 setError( QString::fromLatin1( "Invalid iterator." ) ); 00232 } 00233 } 00234 00235 template<typename T> bool Soprano::Iterator<T>::next() 00236 { 00237 // some evil hacking to avoid detachment of the shared data 00238 const Private* cd = d.constData(); 00239 if( isValid() ) { 00240 bool hasNext = cd->backend->next(); 00241 setError( cd->backend->lastError() ); 00242 if( !hasNext ) { 00243 cd->backend->close(); 00244 } 00245 return hasNext; 00246 } 00247 else { 00248 setError( QString::fromLatin1( "Invalid iterator." ) ); 00249 return false; 00250 } 00251 } 00252 00253 template<typename T> T Soprano::Iterator<T>::current() const 00254 { 00255 if( isValid() ){ 00256 T c = d->backend->current(); 00257 setError( d->backend->lastError() ); 00258 return c; 00259 } 00260 else { 00261 setError( QString::fromLatin1( "Invalid iterator." ) ); 00262 return T(); 00263 } 00264 } 00265 00266 template<typename T> T Soprano::Iterator<T>::operator*() const 00267 { 00268 return current(); 00269 } 00270 00271 template<typename T> bool Soprano::Iterator<T>::isValid() const 00272 { 00273 return d->backend != 0; 00274 } 00275 00276 00277 template<typename T> QList<T> Soprano::Iterator<T>::allElements() 00278 { 00279 QList<T> sl; 00280 while ( next() ) { 00281 sl.append( current() ); 00282 } 00283 close(); 00284 return sl; 00285 } 00288 #endif 00289