wibble  0.1.28
netbuffer.h
Go to the documentation of this file.
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