00001 // @file bufreader.h parse a memory region into usable pieces 00002 00019 #pragma once 00020 00021 namespace mongo { 00022 00027 class BufReader : boost::noncopyable { 00028 public: 00029 class eof : public std::exception { 00030 public: 00031 virtual const char * what() { return "BufReader eof"; } 00032 }; 00033 00034 BufReader(const void *p, unsigned len) : _start(p), _pos(p), _end(((char *)_pos)+len) { } 00035 00036 bool atEof() const { return _pos == _end; } 00037 00039 template <typename T> 00040 void read(T &t) { 00041 T* cur = (T*) _pos; 00042 T *next = cur + 1; 00043 if( _end < next ) throw eof(); 00044 t = *cur; 00045 _pos = next; 00046 } 00047 00049 template <typename T> 00050 void peek(T &t) { 00051 T* cur = (T*) _pos; 00052 T *next = cur + 1; 00053 if( _end < next ) throw eof(); 00054 t = *cur; 00055 } 00056 00058 unsigned offset() const { return (char*)_pos - (char*)_start; } 00059 00061 unsigned remaining() const { return (char*)_end -(char*)_pos; } 00062 00064 void rewind(unsigned nbytes) { 00065 _pos = ((char *) _pos) - nbytes; 00066 assert( _pos >= _start ); 00067 } 00068 00070 const void* skip(unsigned len) { 00071 const char *nxt = ((char *) _pos) + len; 00072 if( _end < nxt ) throw eof(); 00073 const void *p = _pos; 00074 _pos = nxt; 00075 return p; 00076 } 00077 00078 void readStr(string& s) { 00079 StringBuilder b; 00080 while( 1 ) { 00081 char ch; 00082 read(ch); 00083 if( ch == 0 ) 00084 break; 00085 b << ch; 00086 } 00087 s = b.str(); 00088 } 00089 00090 const void* pos() { return _pos; } 00091 00092 private: 00093 const void *_start; 00094 const void *_pos; 00095 const void *_end; 00096 }; 00097 00098 }