orca-robotics INTRODUCTION Overview Download and Install Quick Start Documentation Publications REPOSITORY Interfaces Components Libraries Utilities Software Map DEVELOPER Tutorials Examples Dev Guide Dashboard Wiki login/pass: orca/orca 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)