Evo C++ Library v0.5.1
rawbuffer.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_impl_rawbuffer_h
9 #define INCL_evo_impl_rawbuffer_h
10 
11 #include "sys.h"
12 #include "../type.h"
13 
14 // Disable certain MSVC warnings for this file
15 #if defined(_MSC_VER)
16  #pragma warning(push)
17  #pragma warning(disable:4458)
18 #endif
19 
20 namespace evo {
23 
25 
34 struct RawBuffer {
35  char* data;
36  ulong size;
37  ulong used;
38  bool owned;
39 
41  RawBuffer() : data(NULL), size(0), used(0), owned(false)
42  { }
43 
45  RawBuffer(ulong size) : data(NULL), size(0), used(0), owned(false)
46  { resize(size); }
47 
50  if (owned)
51  ::free(data);
52  }
53 
57  ulong avail() const {
58  assert( used <= size );
59  return size - used;
60  }
61 
66  ulong avail(ulong checksize) const {
67  assert(used <= size);
68  const ulong size_avail = size - used;
69  return (checksize > size_avail ? size_avail : checksize);
70  }
71 
78  if (owned)
79  ::free(data);
80  data = NULL;
81  size = 0;
82  used = 0;
83  owned = false;
84  return *this;
85  }
86 
96  RawBuffer& ref(char* data, ulong size, ulong used=0) {
97  assert( data != NULL );
98  if (owned)
99  ::free(this->data);
100  this->data = data;
101  this->size = size;
102  this->used = used;
103  owned = false;
104  return *this;
105  }
106 
116  RawBuffer& resize(ulong newsize) {
117  if (newsize == 0) {
118  // Clear
119  if (size > 0) {
120  if (owned)
121  ::free(data);
122  data = NULL;
123  size = 0;
124  used = 0;
125  owned = false;
126  }
127  } else if (size != newsize) {
128  // New positive size
129  assert( newsize > 0 );
130  if (used > 0) {
131  // Preserve existing items
132  if (used > newsize)
133  used = newsize;
134  char* const old_data = data;
135  data = (char*)::malloc((size_t)newsize);
136  memcpy(data, old_data, (size_t)used);
137  if (owned)
138  ::free(old_data);
139  } else {
140  // New array
141  if (owned)
142  ::free(data);
143  data = (char*)::malloc((size_t)newsize);
144  }
145  size = newsize;
146  owned = true;
147  }
148  return *this;
149  }
150 
158  if (min > size)
159  resize(min);
160  return *this;
161  }
162 
169  used = 0;
170  return *this;
171  }
172 
180  ulong insert(ulong index, ulong size=1) {
181  ulong tempsize = used + size;
182  if (tempsize > this->size)
183  resize(tempsize);
184  if (index < used) {
185  // Insert
186  memmove(data+index+size, data+index, used-index);
187  } else {
188  // Append
189  index = used;
190  }
191  used += size;
192  return index;
193  }
194 
202  RawBuffer& remove(ulong index, ulong size=1) {
203  if (index < used && size > 0) {
204  // Size after removed items
205  size_t tempsize = used - index;
206  if (size >= tempsize)
207  tempsize = 0;
208  else
209  tempsize -= size;
210 
211  // Remove
212  if (tempsize > 0) {
213  // Shift items after removed
214  memmove(data+index, data+index+size, tempsize);
215  used -= size;
216  } else {
217  // Remove all items after index
218  used = index;
219  }
220  }
221  return *this;
222  }
223 
229  void flush(ulong& offset) {
230  assert( used <= size );
231  if (offset >= used) {
232  offset = 0;
233  used = 0;
234  } else if (offset > 0) {
235  used -= offset;
236  memmove(data, data+offset, used);
237  offset = 0;
238  }
239  }
240 
249  ulong read(ulong& offset, char* buf, ulong readsize) {
250  if (offset < used) {
251  ulong maxsize = used - offset;
252  if (readsize > maxsize)
253  readsize = maxsize;
254  memcpy(buf, data+offset, readsize);
255  offset += readsize;
256  } else
257  readsize = 0;
258  return readsize;
259  }
260 
269  ulong write(const char* buf, ulong writesize) {
270  if (used < size) {
271  ulong maxsize = size - used;
272  if (writesize > maxsize)
273  writesize = maxsize;
274  memcpy(data+used, buf, writesize);
275  used += writesize;
276  } else
277  writesize = 0;
278  return writesize;
279  }
280 
289  ulong write(char ch, ulong count=1) {
290  if (used < size) {
291  const ulong maxsize = size - used;
292  if (count > maxsize)
293  count = maxsize;
294  memset(data+used, ch, count);
295  used += count;
296  } else
297  count = 0;
298  return count;
299  }
300 
301 private:
302  // Disable copying
303  RawBuffer(const RawBuffer&);
304  RawBuffer& operator=(const RawBuffer&);
305 };
306 
308 
309 }
310 #if defined(_MSC_VER)
311  #pragma warning(pop)
312 #endif
313 #endif
RawBuffer & ref(char *data, ulong size, ulong used=0)
Reference another buffer.
Definition: rawbuffer.h:96
RawBuffer & minsize(ulong min)
Resize buffer if smaller than minimum size.
Definition: rawbuffer.h:157
ulong insert(ulong index, ulong size=1)
Make room to insert items.
Definition: rawbuffer.h:180
RawBuffer & clear()
Clear buffer.
Definition: rawbuffer.h:168
RawBuffer(ulong size)
Constructor.
Definition: rawbuffer.h:45
Evo implementation detail for system portability – this is included by most Evo headers, include this via: include <evo/type.h>.
ulong size
Buffer size (capacity) in bytes – do not modify, use: resize(), minsize(), reset(), ref()
Definition: rawbuffer.h:36
ulong write(char ch, ulong count=1)
Write character at end of buffer.
Definition: rawbuffer.h:289
void flush(ulong &offset)
Flush data already read from buffer using offset.
Definition: rawbuffer.h:229
RawBuffer & reset()
Reset to empty state without a buffer.
Definition: rawbuffer.h:77
~RawBuffer()
Destructor.
Definition: rawbuffer.h:49
RawBuffer & resize(ulong newsize)
Resize buffer.
Definition: rawbuffer.h:116
ulong read(ulong &offset, char *buf, ulong readsize)
Read from buffer using offset.
Definition: rawbuffer.h:249
Evo C++ Library namespace.
Definition: alg.h:11
char * data
Buffer data pointer, NULL if empty (size=0)
Definition: rawbuffer.h:35
ulong avail() const
Get size available.
Definition: rawbuffer.h:57
bool owned
Whether this owns the buffer and must free it.
Definition: rawbuffer.h:38
ulong avail(ulong checksize) const
Get size up to size available.
Definition: rawbuffer.h:66
RawBuffer()
Constructor.
Definition: rawbuffer.h:41
T & min(T &a, T &b)
Returns lowest of given values.
Definition: alg.h:26
Simple raw memory buffer.
Definition: rawbuffer.h:34
ulong write(const char *buf, ulong writesize)
Write at end of buffer.
Definition: rawbuffer.h:269
ulong used
Buffer size in use in bytes.
Definition: rawbuffer.h:37