Inexor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
buffer_types.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 
6 #include <algorithm>
7 #include <enet/enet.h>
8 
9 #include <boost/algorithm/clamp.hpp> // TODO replace with std::clamp as soon as C++17 is our target.
10 
13 template <class T>
14 struct databuf
15 {
17  enum
18  {
19  OVERREAD = 1<<0,
20  OVERWROTE = 1<<1
21  };
22 
24  T *buf;
25  int len, maxlen;
27 
28  databuf() : buf(nullptr), len(0), maxlen(0), flags(0)
29  {
30  }
31 
32  template<class U>
33  databuf(T *buf, U maxlen) : buf(buf), len(0), maxlen((int)maxlen), flags(0) {}
34 
35  void reset()
36  {
37  len = 0;
38  flags = 0;
39  }
40 
41  void reset(T *buf_, int maxlen_)
42  {
43  reset();
44  buf = buf_;
45  maxlen = maxlen_;
46  }
47 
49  const T &get()
50  {
51  static T overreadval = 0;
52  if(len<maxlen) return buf[len++];
53  flags |= OVERREAD;
54  return overreadval;
55  }
56 
58  databuf subbuf(int sz)
59  {
60  sz = boost::algorithm::clamp(sz, 0, maxlen-len);
61  len += sz;
62  return databuf(&buf[len-sz], sz);
63  }
64 
65  T *pad(int numvals)
66  {
67  T *vals = &buf[len];
68  len += std::min(numvals, maxlen-len);
69  return vals;
70  }
71 
73  void put(const T &val)
74  {
75  if(len<maxlen) buf[len++] = val;
76  else flags |= OVERWROTE;
77  }
78 
80  void put(const T *vals, int numvals)
81  {
82  if(maxlen-len<numvals) flags |= OVERWROTE;
83  memcpy(&buf[len], (const void *)vals, std::min(maxlen-len, numvals)*sizeof(T));
84  len += std::min(maxlen-len, numvals);
85  }
86 
88  int get(T *vals, int numvals)
89  {
90  int read = std::min(maxlen-len, numvals);
91  if(read<numvals) flags |= OVERREAD;
92  memcpy(vals, (void *)&buf[len], read*sizeof(T));
93  len += read;
94  return read;
95  }
96 
98  void offset(int n)
99  {
100  n = std::min(n, maxlen);
101  buf += n;
102  maxlen -= n;
103  len = std::max(len-n, 0);
104  }
105 
106  T *getbuf() const { return buf; }
107 
108  bool empty() const { return len==0; }
110  int length() const { return len; }
112  int remaining() const { return maxlen-len; }
114  bool overread() const { return (flags&OVERREAD)!=0; }
116  bool overwrote() const { return (flags&OVERWROTE)!=0; }
117 
118  bool check(int n) { return remaining() >= n; }
119 
122  {
123  len = maxlen;
124  flags |= OVERREAD;
125  }
126 };
127 
130 
133 {
134  ENetPacket *packet;
135  int growth;
136 
138  packetbuf(ENetPacket *packet) : ucharbuf(packet->data, packet->dataLength), packet(packet), growth(0)
139  {
140  }
141 
143  packetbuf(int growth, int pflags = 0) : growth(growth)
144  {
145  packet = enet_packet_create(nullptr, growth, pflags);
146  buf = (uchar *)packet->data;
147  maxlen = packet->dataLength;
148  }
149 
152  {
153  cleanup();
154  }
155 
157  void reliable()
158  {
159  packet->flags |= ENET_PACKET_FLAG_RELIABLE;
160  }
161 
163  void resize(int n)
164  {
165  enet_packet_resize(packet, n);
166  buf = (uchar *)packet->data;
167  maxlen = packet->dataLength;
168  }
169 
172  void checkspace(int n)
173  {
174  if(len + n > maxlen && packet && growth > 0) resize(std::max(len + n, maxlen + growth));
175  }
176 
178  ucharbuf subbuf(int sz)
179  {
180  checkspace(sz);
181  return ucharbuf::subbuf(sz);
182  }
183 
185  void put(const uchar &val)
186  {
187  checkspace(1);
188  ucharbuf::put(val);
189  }
190  void put(const uchar *vals, int numvals)
191  {
192  checkspace(numvals);
193  ucharbuf::put(vals, numvals);
194  }
195 
198  ENetPacket *finalize()
199  {
200  resize(len);
201  return packet;
202  }
203 
205  void cleanup()
206  {
207  if(growth > 0 && packet && !packet->referenceCount)
208  {
209  enet_packet_destroy(packet);
210  packet = nullptr;
211  buf = nullptr;
212  len = maxlen = 0;
213  }
214  }
215 };
databuf()
Definition: buffer_types.hpp:28
void put(const T &val)
put one element at the end of the buffer.
Definition: buffer_types.hpp:73
const T & max(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:224
void put(const uchar *vals, int numvals)
Definition: buffer_types.hpp:190
template implementation of buffers (networking e.g.).
Definition: buffer_types.hpp:14
ENetPacket * packet
Definition: buffer_types.hpp:134
ucharbuf subbuf(int sz)
create a sub buffer of [sz] bytes size
Definition: buffer_types.hpp:178
packetbuf(ENetPacket *packet)
call constructor from inherited class in this constructor
Definition: buffer_types.hpp:138
void cleanup()
destroy ENET packet and reset memory
Definition: buffer_types.hpp:205
void put(const T *vals, int numvals)
put a given number of elements at the end of the buffer.
Definition: buffer_types.hpp:80
bool check(int n)
Definition: buffer_types.hpp:118
T * getbuf() const
Definition: buffer_types.hpp:106
int length() const
receive amount of values in buffer.
Definition: buffer_types.hpp:110
void offset(int n)
skip the first n elemnts of the buffer.
Definition: buffer_types.hpp:98
T * buf
the pointer to the data.
Definition: buffer_types.hpp:24
databuf< uchar > ucharbuf
Definition: buffer_types.hpp:129
databuf< char > charbuf
Definition: buffer_types.hpp:128
int maxlen
Definition: buffer_types.hpp:25
uchar flags
Definition: buffer_types.hpp:26
void resize(int n)
resize ENET packet, copy data and buffer length
Definition: buffer_types.hpp:163
void forceoverread()
force buffer to skip all free memory space
Definition: buffer_types.hpp:121
bool empty() const
Definition: buffer_types.hpp:108
const T & min(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:210
~packetbuf()
call cleanup in destructor!
Definition: buffer_types.hpp:151
void reset(T *buf_, int maxlen_)
Definition: buffer_types.hpp:41
bool overread() const
did we try to read too much?
Definition: buffer_types.hpp:114
unsigned char uchar
Basic type definitions.
Definition: cube_types.hpp:7
void put(const uchar &val)
write to buffer functions
Definition: buffer_types.hpp:185
network packet buffer
Definition: buffer_types.hpp:132
T * pad(int numvals)
Definition: buffer_types.hpp:65
int len
Definition: buffer_types.hpp:25
int remaining() const
receive remaining space in buffer.
Definition: buffer_types.hpp:112
databuf(T *buf, U maxlen)
Definition: buffer_types.hpp:33
void reset()
Definition: buffer_types.hpp:35
ENetPacket * finalize()
remove any allocated space which is not used yet background: allocations are expensive, so we pr
Definition: buffer_types.hpp:198
Definition: buffer_types.hpp:19
packetbuf(int growth, int pflags=0)
reserve memory in this constructor
Definition: buffer_types.hpp:143
void reliable()
set ENET_PACKET_FLAG_RELIABLE - flag
Definition: buffer_types.hpp:157
bool overwrote() const
did we try to write too much into the buffer?
Definition: buffer_types.hpp:116
void checkspace(int n)
check if [n] bytes memory are available in this buffer if not reserve memory!
Definition: buffer_types.hpp:172
Definition: buffer_types.hpp:20
databuf subbuf(int sz)
create a sub buffer copy from this buffer (from the current position)
Definition: buffer_types.hpp:58
int growth
Definition: buffer_types.hpp:135