diff options
Diffstat (limited to 'src/mongo/util/bufreader.h')
-rw-r--r-- | src/mongo/util/bufreader.h | 198 |
1 files changed, 107 insertions, 91 deletions
diff --git a/src/mongo/util/bufreader.h b/src/mongo/util/bufreader.h index 481d0dbe31b..e641a01af63 100644 --- a/src/mongo/util/bufreader.h +++ b/src/mongo/util/bufreader.h @@ -35,99 +35,115 @@ namespace mongo { - /** helper to read and parse a block of memory - methods throw the eof exception if the operation would pass the end of the - buffer with which we are working. - */ - class BufReader { - MONGO_DISALLOW_COPYING(BufReader); - public: - class eof : public std::exception { - public: - eof() { } - virtual const char * what() const throw() { return "BufReader eof"; } - }; - - BufReader(const void *p, unsigned len) : _start(p), _pos(p), _end(((char *)_pos)+len) { } - - bool atEof() const { return _pos == _end; } - - /** read in the object specified, and advance buffer pointer */ - template <typename T> - void read(T &t) { - T* cur = (T*) _pos; - T *next = cur + 1; - if( _end < next ) throw eof(); - t = *cur; - _pos = next; - } - - /** read in and return an object of the specified type, and advance buffer pointer */ - template <typename T> - T read() { - T out; - read(out); - return out; - } - - /** read in the object specified, but do not advance buffer pointer */ - template <typename T> - void peek(T &t) const { - T* cur = (T*) _pos; - T *next = cur + 1; - if( _end < next ) throw eof(); - t = *cur; - } - - /** read in and return an object of the specified type, but do not advance buffer pointer */ - template <typename T> - T peek() const { - T out; - peek(out); - return out; - } - - /** return current offset into buffer */ - unsigned offset() const { return (char*)_pos - (char*)_start; } - - /** return remaining bytes */ - unsigned remaining() const { return (char*)_end -(char*)_pos; } - - /** back up by nbytes */ - void rewind(unsigned nbytes) { - _pos = ((char *) _pos) - nbytes; - verify( _pos >= _start ); - } - - /** return current position pointer, and advance by len */ - const void* skip(unsigned len) { - const char *nxt = ((char *) _pos) + len; - if( _end < nxt ) throw eof(); - const void *p = _pos; - _pos = nxt; - return p; - } - - /// reads a NUL terminated string - StringData readCStr() { - const char* start = static_cast<const char*>(pos()); - size_t len = strnlen(start, remaining()-1); - if (start[len] != '\0') throw eof(); // no NUL byte in remaining bytes - skip(len + 1/*NUL byte*/); - return StringData(start, len); - } +/** helper to read and parse a block of memory + methods throw the eof exception if the operation would pass the end of the + buffer with which we are working. +*/ +class BufReader { + MONGO_DISALLOW_COPYING(BufReader); - void readStr(std::string& s) { - s = readCStr().toString(); +public: + class eof : public std::exception { + public: + eof() {} + virtual const char* what() const throw() { + return "BufReader eof"; } - - const void* pos() { return _pos; } - const void* start() { return _start; } - - private: - const void *_start; - const void *_pos; - const void *_end; }; + BufReader(const void* p, unsigned len) : _start(p), _pos(p), _end(((char*)_pos) + len) {} + + bool atEof() const { + return _pos == _end; + } + + /** read in the object specified, and advance buffer pointer */ + template <typename T> + void read(T& t) { + T* cur = (T*)_pos; + T* next = cur + 1; + if (_end < next) + throw eof(); + t = *cur; + _pos = next; + } + + /** read in and return an object of the specified type, and advance buffer pointer */ + template <typename T> + T read() { + T out; + read(out); + return out; + } + + /** read in the object specified, but do not advance buffer pointer */ + template <typename T> + void peek(T& t) const { + T* cur = (T*)_pos; + T* next = cur + 1; + if (_end < next) + throw eof(); + t = *cur; + } + + /** read in and return an object of the specified type, but do not advance buffer pointer */ + template <typename T> + T peek() const { + T out; + peek(out); + return out; + } + + /** return current offset into buffer */ + unsigned offset() const { + return (char*)_pos - (char*)_start; + } + + /** return remaining bytes */ + unsigned remaining() const { + return (char*)_end - (char*)_pos; + } + + /** back up by nbytes */ + void rewind(unsigned nbytes) { + _pos = ((char*)_pos) - nbytes; + verify(_pos >= _start); + } + + /** return current position pointer, and advance by len */ + const void* skip(unsigned len) { + const char* nxt = ((char*)_pos) + len; + if (_end < nxt) + throw eof(); + const void* p = _pos; + _pos = nxt; + return p; + } + + /// reads a NUL terminated string + StringData readCStr() { + const char* start = static_cast<const char*>(pos()); + size_t len = strnlen(start, remaining() - 1); + if (start[len] != '\0') + throw eof(); // no NUL byte in remaining bytes + skip(len + 1 /*NUL byte*/); + return StringData(start, len); + } + + void readStr(std::string& s) { + s = readCStr().toString(); + } + + const void* pos() { + return _pos; + } + const void* start() { + return _start; + } + +private: + const void* _start; + const void* _pos; + const void* _end; +}; } |