wibble 0.1.28
|
00001 #ifndef WIBBLE_SYS_NETBUFFER_H 00002 #define WIBBLE_SYS_NETBUFFER_H 00003 00004 /* 00005 * Variable-size, reference-counted memory buffer used to access network 00006 * packets 00007 * 00008 * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org> 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 */ 00024 00025 #include <wibble/sys/buffer.h> 00026 #include <wibble/exception.h> 00027 00028 namespace wibble { 00029 namespace sys { 00030 00035 class NetBuffer : public Buffer 00036 { 00037 public: 00042 size_t cursor; 00043 00044 public: 00045 NetBuffer() throw () : Buffer(), cursor(0) {} 00046 NetBuffer(size_t size) : Buffer(size), cursor(0) {} 00047 NetBuffer(void* buf, size_t size, bool own = true) 00048 : Buffer(buf, size, own), cursor(0) {} 00049 NetBuffer(const void* buf, size_t size) 00050 : Buffer(buf, size), cursor(0) {} 00051 00052 NetBuffer(const Buffer& buf) throw () : Buffer(buf), cursor(0) {} 00053 NetBuffer(const NetBuffer& buf) throw () 00054 : Buffer(buf), cursor(buf.cursor) {} 00055 00056 NetBuffer& operator=(const Buffer& buf) 00057 { 00058 Buffer::operator=(buf); 00059 cursor = 0; 00060 return *this; 00061 } 00062 00063 NetBuffer& operator=(const NetBuffer& buf) 00064 { 00065 Buffer::operator=(buf); 00066 cursor = buf.cursor; 00067 return *this; 00068 } 00069 00071 const void* data(size_t ofs = 0) const throw () { return static_cast<const char*>(Buffer::data()) + cursor + ofs; } 00072 00074 void* data(size_t ofs = 0) throw () { return static_cast<char*>(Buffer::data()) + cursor + ofs; } 00075 00077 size_t size() const throw () { return Buffer::size() - cursor; } 00078 00083 template<class T> 00084 bool fits(size_t ofs = 0) const throw () 00085 { 00086 return cursor + ofs + sizeof(T) < size(); 00087 } 00088 00092 template<class T> 00093 const T* cast(size_t ofs = 0) const throw (wibble::exception::Consistency) 00094 { 00095 if (cursor + ofs + sizeof(T) >= size()) 00096 throw wibble::exception::Consistency("reading from buffer", "tried to read past the end of the buffer"); 00097 return (const T*)data(ofs); 00098 } 00099 00103 NetBuffer operator+(size_t ofs) throw (wibble::exception::Consistency) 00104 { 00105 return after(ofs); 00106 } 00107 00111 const NetBuffer after(size_t ofs) const throw (wibble::exception::Consistency) 00112 { 00113 NetBuffer res(*this); 00114 res.skip(ofs); 00115 return res; 00116 } 00117 00122 template<class T> 00123 const NetBuffer after() const throw (wibble::exception::Consistency) 00124 { 00125 NetBuffer res(*this); 00126 res.skip(sizeof(T)); 00127 return res; 00128 } 00129 00133 NetBuffer& operator+=(size_t ofs) throw (wibble::exception::Consistency) 00134 { 00135 skip(ofs); 00136 return *this; 00137 } 00138 00143 template<class T> 00144 void skip() throw (wibble::exception::Consistency) 00145 { 00146 skip(sizeof(T)); 00147 } 00148 00152 void skip(size_t t) throw (wibble::exception::Consistency) 00153 { 00154 if (cursor + t >= size()) 00155 throw wibble::exception::Consistency("reading from buffer", "tried to skip past the end of the buffer"); 00156 cursor += t; 00157 } 00158 }; 00159 00160 } 00161 } 00162 00163 // vim:set ts=4 sw=4: 00164 #endif