wibble  1.1
netbuffer.h
Go to the documentation of this file.
1 #ifndef WIBBLE_SYS_NETBUFFER_H
2 #define WIBBLE_SYS_NETBUFFER_H
3 
4 /*
5  * Variable-size, reference-counted memory buffer used to access network
6  * packets
7  *
8  * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include <wibble/sys/buffer.h>
26 #include <wibble/exception.h>
27 
28 namespace wibble {
29 namespace sys {
30 
35 class NetBuffer : public Buffer
36 {
37 public:
42  size_t cursor;
43 
44 public:
45  NetBuffer() throw () : Buffer(), cursor(0) {}
46  NetBuffer(size_t size) : Buffer(size), cursor(0) {}
47  NetBuffer(void* buf, size_t size, bool own = true)
48  : Buffer(buf, size, own), cursor(0) {}
49  NetBuffer(const void* buf, size_t size)
50  : Buffer(buf, size), cursor(0) {}
51 
52  NetBuffer(const Buffer& buf) throw () : Buffer(buf), cursor(0) {}
53  NetBuffer(const NetBuffer& buf) throw ()
54  : Buffer(buf), cursor(buf.cursor) {}
55 
56  NetBuffer& operator=(const Buffer& buf)
57  {
58  Buffer::operator=(buf);
59  cursor = 0;
60  return *this;
61  }
62 
64  {
65  Buffer::operator=(buf);
66  cursor = buf.cursor;
67  return *this;
68  }
69 
71  const void* data(size_t ofs = 0) const throw () { return static_cast<const char*>(Buffer::data()) + cursor + ofs; }
72 
74  void* data(size_t ofs = 0) throw () { return static_cast<char*>(Buffer::data()) + cursor + ofs; }
75 
77  size_t size() const throw () { return Buffer::size() - cursor; }
78 
83  template<class T>
84  bool fits(size_t ofs = 0) const throw ()
85  {
86  return cursor + ofs + sizeof(T) < size();
87  }
88 
92  template<class T>
93  const T* cast(size_t ofs = 0) const throw (wibble::exception::Consistency)
94  {
95  if (cursor + ofs + sizeof(T) >= size())
96  throw wibble::exception::Consistency("reading from buffer", "tried to read past the end of the buffer");
97  return static_cast<const T*>(data(ofs));
98  }
99 
104  {
105  return after(ofs);
106  }
107 
111  const NetBuffer after(size_t ofs) const throw (wibble::exception::Consistency)
112  {
113  NetBuffer res(*this);
114  res.skip(ofs);
115  return res;
116  }
117 
122  template<class T>
123  const NetBuffer after() const throw (wibble::exception::Consistency)
124  {
125  NetBuffer res(*this);
126  res.skip(sizeof(T));
127  return res;
128  }
129 
134  {
135  skip(ofs);
136  return *this;
137  }
138 
143  template<class T>
144  void skip() throw (wibble::exception::Consistency)
145  {
146  skip(sizeof(T));
147  }
148 
152  void skip(size_t t) throw (wibble::exception::Consistency)
153  {
154  if (cursor + t >= size())
155  throw wibble::exception::Consistency("reading from buffer", "tried to skip past the end of the buffer");
156  cursor += t;
157  }
158 };
159 
160 }
161 }
162 
163 // vim:set ts=4 sw=4:
164 #endif