00001 /******************************************************************************* 00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * 00007 * - Redistributions of source code must retain the above copyright notice, 00008 * this list of conditions and the following disclaimer. 00009 * 00010 * - Redistributions in binary form must reproduce the above copyright notice, 00011 * this list of conditions and the following disclaimer in the documentation 00012 * and/or other materials provided with the distribution. 00013 * 00014 * - Neither the name of Vintela, Inc. nor the names of its 00015 * contributors may be used to endorse or promote products derived from this 00016 * software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS 00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00028 * POSSIBILITY OF SUCH DAMAGE. 00029 *******************************************************************************/ 00030 00035 #ifndef OW_ENUMERATION_HPP_INCLUDE_GUARD_ 00036 #define OW_ENUMERATION_HPP_INCLUDE_GUARD_ 00037 #include "OW_config.h" 00038 #include "OW_TempFileEnumerationImplBase.hpp" 00039 #include "OW_IntrusiveReference.hpp" 00040 00041 #include <iterator> // for the iterator tags 00042 00043 namespace OW_NAMESPACE 00044 { 00045 00046 template <class T> 00047 class TempFileEnumerationImpl : public TempFileEnumerationImplBase 00048 { 00049 public: 00050 TempFileEnumerationImpl() 00051 { 00052 } 00053 TempFileEnumerationImpl(String const& filename) 00054 : TempFileEnumerationImplBase(filename) 00055 { 00056 } 00057 virtual ~TempFileEnumerationImpl() 00058 { 00059 } 00060 void nextElement(T& out) 00061 { 00062 throwIfEmpty(); 00063 out.readObject(m_Data); 00064 --m_size; 00065 } 00066 T nextElement() 00067 { 00068 throwIfEmpty(); 00069 T retval; 00070 retval.readObject(m_Data); 00071 --m_size; 00072 return retval; 00073 } 00074 void addElement( const T& arg ) 00075 { 00076 arg.writeObject(m_Data); 00077 ++m_size; 00078 } 00079 private: 00080 // Prevent copying or assignment 00081 TempFileEnumerationImpl( const TempFileEnumerationImpl<T>& ); 00082 TempFileEnumerationImpl<T>& operator=( const TempFileEnumerationImpl<T>& ); 00083 }; 00084 00085 template <class T> 00086 class Enumeration 00087 { 00088 public: 00089 Enumeration() 00090 : m_impl( new TempFileEnumerationImpl<T> ) 00091 { 00092 } 00093 // Build an enumeration out of the file referenced by filename 00094 Enumeration(String const& filename) 00095 : m_impl( new TempFileEnumerationImpl<T>(filename) ) 00096 { 00097 } 00098 bool hasMoreElements() const 00099 { 00100 return m_impl->hasMoreElements(); 00101 } 00102 void nextElement(T& arg) 00103 { 00104 m_impl->nextElement(arg); 00105 } 00106 T nextElement() 00107 { 00108 return m_impl->nextElement(); 00109 } 00110 size_t numberOfElements() const 00111 { 00112 return m_impl->numberOfElements(); 00113 } 00114 void addElement(const T& arg) 00115 { 00116 m_impl->addElement(arg); 00117 } 00118 void clear() 00119 { 00120 m_impl->clear(); 00121 } 00122 // Returns the filename of the file that contains the enumeration data. 00123 // After this call, the enumeration will not contain any items. 00124 String releaseFile() 00125 { 00126 return m_impl->releaseFile(); 00127 } 00128 bool usingTempFile() const 00129 { 00130 return m_impl->usingTempFile(); 00131 } 00132 private: 00133 IntrusiveReference< TempFileEnumerationImpl<T> > m_impl; 00134 }; 00135 00136 template <class T> 00137 class Enumeration_input_iterator 00138 { 00139 public: 00140 typedef Enumeration<T> enumeration_type; 00141 typedef std::input_iterator_tag iterator_category; 00142 typedef T value_type; 00143 typedef const T* pointer; 00144 typedef const T& reference; 00145 typedef ptrdiff_t difference_type; 00146 Enumeration_input_iterator() : m_enumeration(0), m_ok(false) 00147 { 00148 } 00149 Enumeration_input_iterator(enumeration_type& e) : m_enumeration(&e) 00150 { 00151 m_read(); 00152 } 00153 00154 // compiler generated copy ctor is what we want. 00155 // compiler generated copy-assignment operator= is what we want. 00156 00157 reference operator*() const 00158 { 00159 return m_value; 00160 } 00161 pointer operator->() const 00162 { 00163 return &(operator*()); 00164 } 00165 Enumeration_input_iterator& operator++() 00166 { 00167 m_read(); 00168 return *this; 00169 } 00170 Enumeration_input_iterator operator++(int) 00171 { 00172 Enumeration_input_iterator tmp = *this; 00173 m_read(); 00174 return tmp; 00175 } 00176 bool m_equal(const Enumeration_input_iterator& x) const 00177 { 00178 return(m_ok == x.m_ok) && (!m_ok || m_enumeration == x.m_enumeration); 00179 } 00180 private: 00181 enumeration_type* m_enumeration; 00182 T m_value; 00183 bool m_ok; 00184 void m_read() 00185 { 00186 m_ok = (m_enumeration && m_enumeration->hasMoreElements()) ? true : false; 00187 if (m_ok) 00188 { 00189 m_enumeration->nextElement(m_value); 00190 } 00191 } 00192 }; 00193 00194 template <class T> 00195 inline bool 00196 operator==(const Enumeration_input_iterator<T>& x, 00197 const Enumeration_input_iterator<T>& y) 00198 { 00199 return x.m_equal(y); 00200 } 00201 00202 template <class T> 00203 inline bool 00204 operator!=(const Enumeration_input_iterator<T>& x, 00205 const Enumeration_input_iterator<T>& y) 00206 { 00207 return !x.m_equal(y); 00208 } 00209 00210 template <class T> 00211 class Enumeration_insert_iterator 00212 { 00213 public: 00214 typedef Enumeration<T> enumeration_type; 00215 typedef std::output_iterator_tag iterator_category; 00216 typedef void value_type; 00217 typedef void difference_type; 00218 typedef void pointer; 00219 typedef void reference; 00220 Enumeration_insert_iterator(enumeration_type& e) : m_enumeration(&e) 00221 { 00222 } 00223 Enumeration_insert_iterator<T>& operator=(const T& value) 00224 { 00225 m_enumeration->addElement(value); 00226 return *this; 00227 } 00228 Enumeration_insert_iterator<T>& operator*() 00229 { 00230 return *this; 00231 } 00232 Enumeration_insert_iterator<T>& operator++() 00233 { 00234 return *this; 00235 } 00236 Enumeration_insert_iterator<T>& operator++(int) 00237 { 00238 return *this; 00239 } 00240 private: 00241 enumeration_type* m_enumeration; 00242 }; 00243 00244 template <class Container> 00245 inline Enumeration_insert_iterator<Container> Enumeration_inserter(Enumeration<Container>& x) 00246 { 00247 return Enumeration_insert_iterator<Container>(x); 00248 } 00249 00250 } // end namespace OW_NAMESPACE 00251 00252 #endif