INTRODUCTION Overview Download and Install Quick Start Documentation Publications NONFRAMEWORK CODE Driver Interfaces Drivers Libraries Utilities FRAMEWORK CODE Interfaces Components Libraries Utilities Full Software Listings DEVELOPER Tutorials Examples Dev Guide Dashboard PEOPLE Contributors Users Project Download Mailing lists
|
filebreadcrumbs.h00001 #ifndef ORCALOG_FILEBREADCRUMBS_H 00002 #define ORCALOG_FILEBREADCRUMBS_H 00003 00004 #include <sstream> 00005 #include <fstream> 00006 #include <vector> 00007 #include <IceUtil/IceUtil.h> 00008 #include <orcalog/utils.h> 00009 00010 namespace orcalog { 00011 namespace detail { 00012 00014 enum SeekResult { 00015 SeekOK, 00016 SeekQueryInFuture, 00017 SeekQueryBeforeStart 00018 }; 00020 00021 // 00022 // @brief Class to leave a trail of bread-crumbs when moving sequentially through a 00023 // file, so we can rewind. 00024 // Assumes that we start from the start and place a crumb at every point to which 00025 // we might later want to rewind. 00026 // 00027 // @author Alex Brooks 00028 // 00029 template<typename IndexType> 00030 class FileBreadCrumbs 00031 { 00032 public: 00033 00034 // As you move through the file, call this to leave a trail 00035 // of bread-crumbs so that rewind is possible. 00036 // 'pos' can be read with 'tellg()' (STL book p.634) 00037 void placeCrumb( const std::ios::pos_type &pos, const IndexType &t ); 00038 00039 // Tries to find the first marker after (or at) the query. 00040 // Returns: 00041 // SeekOK: valid answer returned in 'pos'. 00042 // SeekQueryInFuture : there was no marker at or after the query (ie the query is in the future). 00043 SeekResult getCrumbAtOrAfter( const IndexType &t, std::ios::pos_type &pos ); 00044 00045 // Tries to find the marker exactly at the query. 00046 // Returns: 00047 // true: found 00048 // false: not found 00049 bool getCrumbAt( const IndexType &t, std::ios::pos_type &pos ); 00050 00051 // Tries to find the last marker before the query. 00052 // Returns: 00053 // SeekOK: valid answer returned in 'pos'. 00054 // SeekQueryBeforeStart : there was no marker before the query (ie the query is before the start). 00055 SeekResult getCrumbBefore( const IndexType &t, std::ios::pos_type &pos ); 00056 00057 const IndexType &latest() const { return maxIndex_; } 00058 00059 private: 00060 00061 bool haveCrumbAt( const IndexType &t ); 00062 00063 std::map<IndexType,std::ios::pos_type> crumbs_; 00064 typedef typename std::map<IndexType,std::ios::pos_type>::const_iterator ConstCrumbsIterator; 00065 00066 IndexType maxIndex_; 00067 }; 00068 00071 00072 template<typename IndexType> 00073 bool 00074 FileBreadCrumbs<IndexType>::haveCrumbAt( const IndexType &index ) 00075 { 00076 ConstCrumbsIterator it = 00077 crumbs_.find( index ); 00078 return !(it == crumbs_.end()); 00079 } 00080 00081 template<typename IndexType> 00082 void 00083 FileBreadCrumbs<IndexType>::placeCrumb( const std::ios::pos_type &pos, 00084 const IndexType &index ) 00085 { 00086 if ( crumbs_.size() == 0 ) 00087 { 00088 // First crumb -- add it and make this the maxIndex_ 00089 maxIndex_ = index; 00090 crumbs_[index] = pos; 00091 } 00092 else 00093 { 00094 // Already have at least one crumb. 00095 // Add this one if it's new. 00096 if ( index > maxIndex_ || 00097 !haveCrumbAt(index) ) 00098 { 00099 crumbs_[index] = pos; 00100 if ( index > maxIndex_ ) 00101 maxIndex_ = index; 00102 } 00103 } 00104 } 00105 00106 template<typename IndexType> 00107 SeekResult 00108 FileBreadCrumbs<IndexType>::getCrumbAtOrAfter( const IndexType &index, 00109 std::ios::pos_type &pos ) 00110 { 00111 ConstCrumbsIterator it = crumbs_.lower_bound( index ); 00112 if ( it == crumbs_.end() ) 00113 { 00114 return SeekQueryInFuture; 00115 } 00116 else 00117 { 00118 pos = it->second; 00119 return SeekOK; 00120 } 00121 } 00122 00123 template<typename IndexType> 00124 bool 00125 FileBreadCrumbs<IndexType>::getCrumbAt( const IndexType &index, 00126 std::ios::pos_type &pos ) 00127 { 00128 ConstCrumbsIterator it = crumbs_.find( index ); 00129 if ( it == crumbs_.end() ) 00130 { 00131 return false; 00132 } 00133 else 00134 { 00135 pos = it->second; 00136 return true; 00137 } 00138 } 00139 00140 template<typename IndexType> 00141 SeekResult 00142 FileBreadCrumbs<IndexType>::getCrumbBefore( const IndexType &index, 00143 std::ios::pos_type &pos ) 00144 { 00145 // Find the first crumb after the specified index 00146 ConstCrumbsIterator it = crumbs_.lower_bound( index ); 00147 00148 if ( it == crumbs_.begin() ) 00149 { 00150 return SeekQueryBeforeStart; 00151 } 00152 else 00153 { 00154 it--; 00155 pos = it->second; 00156 return SeekOK; 00157 } 00158 } 00159 00161 00162 inline std::string toString( SeekResult &r ) 00163 { 00164 std::stringstream ss; 00165 switch (r) 00166 { 00167 case SeekOK: 00168 ss << "SeekOK"; 00169 break; 00170 case SeekQueryInFuture: 00171 ss << "SeekQueryInFuture"; 00172 break; 00173 case SeekQueryBeforeStart: 00174 ss << "SeekQueryBeforeStart"; 00175 break; 00176 default: 00177 ss << "Unknown SeekResult"; 00178 break; 00179 } 00180 return ss.str(); 00181 } 00182 00183 } // end namespace orcalog 00184 } // end namespace detail 00185 00186 #endif |
Webmaster: Tobias Kaupp (tobasco at users.sourceforge.net)