00001 #ifndef EDG_WORKLOAD_COMMON_UTILITIES_FILELISTITERATOR_H
00002 #define EDG_WORKLOAD_COMMON_UTILITIES_FILELISTITERATOR_H
00003
00004 #ifndef EDG_WORKLOAD_COMMON_UTILITIES_FILECONTAINER_H
00005 #include "filecontainer.h"
00006 #endif
00007
00008 #include <boost/shared_ptr.hpp>
00009
00010 #include <classad_distribution.h>
00011
00012 COMMON_NAMESPACE_BEGIN {
00013
00014 namespace utilities {
00015
00016 class _file_sequence_t;
00017
00018 class _base_iterator_t {
00019 friend class _file_sequence_t;
00020
00021 public:
00022 _base_iterator_t( void );
00023 _base_iterator_t( const _base_iterator_t &bt );
00024
00025 ~_base_iterator_t( void );
00026
00027 inline bool is_equal( const _base_iterator_t &bi ) const
00028 { return( (this->bi_container == bi.bi_container) && (this->bi_iterator.position() == bi.bi_iterator.position()) ); }
00029 inline bool is_different( const _base_iterator_t &bi ) const
00030 { return( (this->bi_container != bi.bi_container) || (this->bi_iterator.position() != bi.bi_iterator.position()) ); }
00031
00032 _base_iterator_t ©( const _base_iterator_t &bi );
00033 _base_iterator_t &read_string( bool check = true );
00034 _base_iterator_t &increment( void );
00035 _base_iterator_t &decrement( void );
00036
00037 inline void check_status( void ) const
00038 {
00039 if( !this->bi_good )
00040 throwErrorAndDumpFile( *this->bi_container, FileContainerError::unavailable_position, "_base_iterator_t::check_status()",
00041 this->bi_container->filename(), __LINE__ );
00042 }
00043 inline bool good( void ) const { return this->bi_good; }
00044 inline const std::string &get_data( void ) const { return( this->bi_data ); }
00045
00046 protected:
00047 _base_iterator_t( FileIterator &fi, _file_sequence_t *sequence );
00048 _base_iterator_t( _file_sequence_t *sequence );
00049
00050 inline void good( bool gd ) { this->bi_good = gd; return; }
00051
00052 mutable bool bi_new;
00053 bool bi_good;
00054 FileContainer *bi_container;
00055 FileIterator bi_iterator;
00056 std::string bi_data;
00057 };
00058
00059 template <class Type>
00060 class StdConverter {
00061 public:
00062 inline StdConverter( void ) {}
00063
00064 inline std::string operator()( const Type &data ) { return( boost::lexical_cast<std::string>(data) ); }
00065 inline Type operator()( const std::string &data ) { return( boost::lexical_cast<Type>(data) ); }
00066 };
00067
00068 template <> class StdConverter<std::string> {};
00069
00070 template <> class StdConverter<classad::ClassAd> {
00071 public:
00072 StdConverter( void );
00073
00074 std::string operator()( const classad::ClassAd &data );
00075 const classad::ClassAd &operator()( const std::string &data );
00076
00077 private:
00078 classad::ClassAd sc_classad;
00079 };
00080
00081 template <class Type, class Converter>
00082 class FileList;
00083
00084 template <class Type, class Converter = StdConverter<Type> >
00085 class FLIterator : private _base_iterator_t {
00086 friend class FileList<Type, Converter>;
00087
00088 public:
00089 typedef Type value_type;
00090 typedef Type * pointer;
00091 typedef Type & reference;
00092 typedef ptrdiff_t difference_type;
00093 typedef std::bidirectional_iterator_tag iterator_category;
00094
00095 FLIterator( void );
00096 FLIterator( const FLIterator & );
00097
00098 ~FLIterator( void );
00099
00100 inline FLIterator &operator=( const FLIterator &that )
00101 {
00102 if( this != &that ) {
00103 this->copy( that );
00104 this->fli_object = that.fli_object;
00105 }
00106
00107 return *this;
00108 }
00109 inline const Type &operator*( void ) const
00110 {
00111 this->check_status();
00112 if( this->bi_new ) {
00113 this->fli_object.reset( new Type(fli_s_converter(this->bi_data)) );
00114 this->bi_new = false;
00115 }
00116 return *this->fli_object;
00117 }
00118 inline const Type *operator->( void ) const
00119 {
00120 this->check_status();
00121 if( this->bi_new ) {
00122 this->fli_object.reset( new Type(fli_s_converter(this->bi_data)) );
00123 this->bi_new = false;
00124 }
00125 return this->fli_object.get();
00126 }
00127
00128
00129 inline FLIterator &operator++( void ) { this->increment(); this->read_string( false ); return *this; }
00130 inline FLIterator &operator--( void ) { this->decrement(); this->read_string( false ); return *this; }
00131
00132 inline FLIterator operator++( int ) { FLIterator tmp( *this ); this->increment(); this->read_string( false ); return tmp; }
00133 inline FLIterator operator--( int ) { FLIterator tmp( *this ); this->decrement(); this->read_string( false ); return tmp; }
00134
00135 inline bool operator==( const FLIterator &fli ) { return this->is_equal( fli ); }
00136 inline bool operator!=( const FLIterator &fli ) { return this->is_different( fli ); }
00137
00138 inline void reset( void ) { this->good( false ); return; }
00139
00140 static Converter fli_s_converter;
00141
00142 protected:
00143 FLIterator( const _base_iterator_t &bli );
00144 FLIterator( const FileIterator &it, _file_sequence_t &seq );
00145
00146 inline _base_iterator_t &getBase( void ) { return( (_base_iterator_t &)(*this) ); }
00147 inline const _base_iterator_t &getBase( void ) const { return( (const _base_iterator_t &)(*this) ); }
00148
00149 mutable boost::shared_ptr<Type> fli_object;
00150 };
00151
00152 template <class Type, class Converter>
00153 Converter FLIterator<Type, Converter>::fli_s_converter;
00154
00155 template <class Type, class Converter>
00156 FLIterator<Type, Converter>::FLIterator<Type, Converter>( void ) : _base_iterator_t(), fli_object() {}
00157
00158 template <class Type, class Converter>
00159 FLIterator<Type, Converter>::FLIterator<Type, Converter>( const FLIterator<Type, Converter> &fli ) :
00160 _base_iterator_t( fli ), fli_object()
00161 {}
00162
00163 template <class Type, class Converter>
00164 FLIterator<Type, Converter>::FLIterator<Type, Converter>( const _base_iterator_t &bi ) : _base_iterator_t( bi ), fli_object()
00165 { this->read_string( false ); }
00166
00167 template <class Type, class Converter>
00168 FLIterator<Type, Converter>::FLIterator<Type, Converter>( const FileIterator &it, _file_sequence_t &seq ) : _base_iterator_t( it, seq ),
00169 fli_object()
00170 { this->read_string( false ); }
00171
00172 template <class Type, class Converter>
00173 FLIterator<Type, Converter>::~FLIterator<Type, Converter>( void ) {}
00174
00175 template<> const std::string &FLIterator<std::string>::operator*( void ) const
00176 {
00177 this->check_status();
00178 return this->bi_data;
00179 }
00180 template<> const std::string *FLIterator<std::string>::operator->( void ) const
00181 {
00182 this->check_status();
00183 return &this->bi_data;
00184 }
00185
00186 };
00187
00188 } COMMON_NAMESPACE_END;
00189
00190 #endif
00191
00192
00193
00194