STXXL  1.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
binary_buffer.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/common/binary_buffer.h
3  *
4  * Classes binary_buffer and binary_reader to construct data blocks with
5  * variable length content. Programs construct blocks using
6  * binary_buffer::put<type>() and read them using
7  * binary_reader::get<type>(). The operation sequences should match.
8  *
9  * Part of the STXXL. See http://stxxl.sourceforge.net
10  *
11  * Copyright (C) 2013-2014 Timo Bingmann <[email protected]>
12  *
13  * Distributed under the Boost Software License, Version 1.0.
14  * (See accompanying file LICENSE_1_0.txt or copy at
15  * http://www.boost.org/LICENSE_1_0.txt)
16  **************************************************************************/
17 
18 #ifndef STXXL_COMMON_BINARY_BUFFER_HEADER
19 #define STXXL_COMMON_BINARY_BUFFER_HEADER
20 
21 #include <cassert>
22 #include <cstdlib>
23 #include <cstring>
24 #include <stdexcept>
25 #include <string>
26 #include <vector>
27 
28 #include <stxxl/bits/namespace.h>
30 
32 
33 //! \addtogroup support
34 //! \{
35 
36 /*!
37  * binary_buffer represents a dynamically growable area of memory, which can be
38  * modified by appending integral data types via put() and other basic
39  * operations.
40  */
42 {
43 protected:
44  //! Allocated buffer pointer.
45  char* m_data;
46 
47  //! Size of valid data.
48  size_t m_size;
49 
50  //! Total capacity of buffer.
51  size_t m_capacity;
52 
53 public:
54  //! Create a new empty object
55  inline binary_buffer()
56  : m_data(NULL), m_size(0), m_capacity(0)
57  { }
58 
59  //! Copy-Constructor, duplicates memory content.
60  inline binary_buffer(const binary_buffer& other)
61  : m_data(NULL), m_size(0), m_capacity(0)
62  {
63  assign(other);
64  }
65 
66  //! Constructor, copy memory area.
67  inline binary_buffer(const void* data, size_t n)
68  : m_data(NULL), m_size(0), m_capacity(0)
69  {
70  assign(data, n);
71  }
72 
73  //! Constructor, create object with n bytes pre-allocated.
74  inline binary_buffer(size_t n)
75  : m_data(NULL), m_size(0), m_capacity(0)
76  {
77  alloc(n);
78  }
79 
80  //! Constructor from std::string, copies string content.
81  inline binary_buffer(const std::string& str)
82  : m_data(NULL), m_size(0), m_capacity(0)
83  {
84  assign(str.data(), str.size());
85  }
86 
87  //! Destroys the memory space.
88  inline ~binary_buffer()
89  {
90  dealloc();
91  }
92 
93  //! Return a pointer to the currently kept memory area.
94  inline const char * data() const
95  {
96  return m_data;
97  }
98 
99  //! Return a writeable pointer to the currently kept memory area.
100  inline char * data()
101  {
102  return m_data;
103  }
104 
105  //! Return the currently used length in bytes.
106  inline size_t size() const
107  {
108  return m_size;
109  }
110 
111  //! Return the currently allocated buffer capacity.
112  inline size_t capacity() const
113  {
114  return m_capacity;
115  }
116 
117  //! Explicit conversion to std::string (copies memory of course).
118  inline std::string str() const
119  {
120  return std::string(reinterpret_cast<const char*>(m_data), m_size);
121  }
122 
123  //! Set the valid bytes in the buffer, use if the buffer is filled
124  //! directly.
125  inline binary_buffer & set_size(size_t n)
126  {
127  assert(n <= m_capacity);
128  m_size = n;
129 
130  return *this;
131  }
132 
133  //! Make sure that at least n bytes are allocated.
134  inline binary_buffer & alloc(size_t n)
135  {
136  if (m_capacity < n)
137  {
138  m_capacity = n;
139  m_data = static_cast<char*>(realloc(m_data, m_capacity));
140  }
141 
142  return *this;
143  }
144 
145  //! Deallocates the kept memory space (we use dealloc() instead of free()
146  //! as a name, because sometimes "free" is replaced by the preprocessor)
148  {
149  if (m_data) free(m_data);
150  m_data = NULL;
151  m_size = m_capacity = 0;
152 
153  return *this;
154  }
155 
156  //! Detach the memory from the object, returns the memory pointer.
157  inline const char * detach()
158  {
159  const char* data = m_data;
160  m_data = NULL;
161  m_size = m_capacity = 0;
162  return data;
163  }
164 
165  //! Clears the memory contents, does not deallocate the memory.
166  inline binary_buffer & clear()
167  {
168  m_size = 0;
169  return *this;
170  }
171 
172  //! Copy a memory range into the buffer, overwrites all current
173  //! data. Roughly equivalent to clear() followed by append().
174  inline binary_buffer & assign(const void* data, size_t len)
175  {
176  if (len > m_capacity) alloc(len);
177 
178  memcpy(m_data, data, len);
179  m_size = len;
180 
181  return *this;
182  }
183 
184  //! Copy the contents of another buffer object into this buffer, overwrites
185  //! all current data. Roughly equivalent to clear() followed by append().
186  inline binary_buffer & assign(const binary_buffer& other)
187  {
188  if (&other != this)
189  assign(other.data(), other.size());
190 
191  return *this;
192  }
193 
194  //! Assignment operator: copy other's memory range into buffer.
195  inline binary_buffer& operator = (const binary_buffer& other)
196  {
197  if (&other != this)
198  assign(other.data(), other.size());
199 
200  return *this;
201  }
202 
203  //! Align the size of the buffer to a multiple of n. Fills up with 0s.
204  inline binary_buffer & align(size_t n)
205  {
206  assert(n > 0);
207  size_t rem = m_size % n;
208  if (rem != 0)
209  {
210  size_t add = n - rem;
211  if (m_size + add > m_capacity) dynalloc(m_size + add);
212  memset(m_data + m_size, 0, add);
213  m_size += add;
214  }
215  assert((m_size % n) == 0);
216 
217  return *this;
218  }
219 
220  //! Dynamically allocate more memory. At least n bytes will be available,
221  //! probably more to compensate future growth.
222  inline binary_buffer & dynalloc(size_t n)
223  {
224  if (m_capacity < n)
225  {
226  // place to adapt the buffer growing algorithm as need.
227  size_t newsize = m_capacity;
228 
229  while (newsize < n) {
230  if (newsize < 256) newsize = 512;
231  else if (newsize < 1024 * 1024) newsize = 2 * newsize;
232  else newsize += 1024 * 1024;
233  }
234 
235  alloc(newsize);
236  }
237 
238  return *this;
239  }
240 
241  // *** Appending Write Functions ***
242 
243  //! Append a memory range to the buffer
244  inline binary_buffer & append(const void* data, size_t len)
245  {
246  if (m_size + len > m_capacity) dynalloc(m_size + len);
247 
248  memcpy(m_data + m_size, data, len);
249  m_size += len;
250 
251  return *this;
252  }
253 
254  //! Append the contents of a different buffer object to this one.
255  inline binary_buffer & append(const class binary_buffer& bb)
256  {
257  return append(bb.data(), bb.size());
258  }
259 
260  //! Append to contents of a std::string, excluding the null (which isn't
261  //! contained in the string size anyway).
262  inline binary_buffer & append(const std::string& s)
263  {
264  return append(s.data(), s.size());
265  }
266 
267  //! Put (append) a single item of the template type T to the buffer. Be
268  //! careful with implicit type conversions!
269  template <typename Type>
270  inline binary_buffer & put(const Type item)
271  {
272  if (m_size + sizeof(Type) > m_capacity) dynalloc(m_size + sizeof(Type));
273 
274  *reinterpret_cast<Type*>(m_data + m_size) = item;
275  m_size += sizeof(Type);
276 
277  return *this;
278  }
279 
280  //! Append a varint to the buffer.
282  {
283  if (v < 128) {
284  put<uint8>(uint8(v));
285  }
286  else if (v < 128 * 128) {
287  put<uint8>((uint8)(((v >> 0) & 0x7F) | 0x80));
288  put<uint8>((uint8)((v >> 7) & 0x7F));
289  }
290  else if (v < 128 * 128 * 128) {
291  put<uint8>((uint8)(((v >> 0) & 0x7F) | 0x80));
292  put<uint8>((uint8)(((v >> 7) & 0x7F) | 0x80));
293  put<uint8>((uint8)((v >> 14) & 0x7F));
294  }
295  else if (v < 128 * 128 * 128 * 128) {
296  put<uint8>((uint8)(((v >> 0) & 0x7F) | 0x80));
297  put<uint8>((uint8)(((v >> 7) & 0x7F) | 0x80));
298  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
299  put<uint8>((uint8)((v >> 21) & 0x7F));
300  }
301  else {
302  put<uint8>((uint8)(((v >> 0) & 0x7F) | 0x80));
303  put<uint8>((uint8)(((v >> 7) & 0x7F) | 0x80));
304  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
305  put<uint8>((uint8)(((v >> 21) & 0x7F) | 0x80));
306  put<uint8>((uint8)((v >> 28) & 0x7F));
307  }
308 
309  return *this;
310  }
311 
312  //! Append a varint to the buffer.
313  inline binary_buffer & put_varint(int v)
314  {
315  return put_varint((uint32)v);
316  }
317 
318  //! Append a varint to the buffer.
320  {
321  if (v < 128) {
322  put<uint8>(uint8(v));
323  }
324  else if (v < 128 * 128) {
325  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
326  put<uint8>((uint8)((v >> 07) & 0x7F));
327  }
328  else if (v < 128 * 128 * 128) {
329  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
330  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
331  put<uint8>((uint8)((v >> 14) & 0x7F));
332  }
333  else if (v < 128 * 128 * 128 * 128) {
334  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
335  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
336  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
337  put<uint8>((uint8)((v >> 21) & 0x7F));
338  }
339  else if (v < ((uint64)128) * 128 * 128 * 128 * 128) {
340  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
341  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
342  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
343  put<uint8>((uint8)(((v >> 21) & 0x7F) | 0x80));
344  put<uint8>((uint8)((v >> 28) & 0x7F));
345  }
346  else if (v < ((uint64)128) * 128 * 128 * 128 * 128 * 128) {
347  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
348  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
349  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
350  put<uint8>((uint8)(((v >> 21) & 0x7F) | 0x80));
351  put<uint8>((uint8)(((v >> 28) & 0x7F) | 0x80));
352  put<uint8>((uint8)((v >> 35) & 0x7F));
353  }
354  else if (v < ((uint64)128) * 128 * 128 * 128 * 128 * 128 * 128) {
355  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
356  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
357  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
358  put<uint8>((uint8)(((v >> 21) & 0x7F) | 0x80));
359  put<uint8>((uint8)(((v >> 28) & 0x7F) | 0x80));
360  put<uint8>((uint8)(((v >> 35) & 0x7F) | 0x80));
361  put<uint8>((uint8)((v >> 42) & 0x7F));
362  }
363  else if (v < ((uint64)128) * 128 * 128 * 128 * 128 * 128 * 128 * 128) {
364  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
365  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
366  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
367  put<uint8>((uint8)(((v >> 21) & 0x7F) | 0x80));
368  put<uint8>((uint8)(((v >> 28) & 0x7F) | 0x80));
369  put<uint8>((uint8)(((v >> 35) & 0x7F) | 0x80));
370  put<uint8>((uint8)(((v >> 42) & 0x7F) | 0x80));
371  put<uint8>((uint8)((v >> 49) & 0x7F));
372  }
373  else if (v < ((uint64)128) * 128 * 128 * 128 * 128 * 128 * 128 * 128 * 128) {
374  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
375  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
376  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
377  put<uint8>((uint8)(((v >> 21) & 0x7F) | 0x80));
378  put<uint8>((uint8)(((v >> 28) & 0x7F) | 0x80));
379  put<uint8>((uint8)(((v >> 35) & 0x7F) | 0x80));
380  put<uint8>((uint8)(((v >> 42) & 0x7F) | 0x80));
381  put<uint8>((uint8)(((v >> 49) & 0x7F) | 0x80));
382  put<uint8>((uint8)((v >> 56) & 0x7F));
383  }
384  else {
385  put<uint8>((uint8)(((v >> 00) & 0x7F) | 0x80));
386  put<uint8>((uint8)(((v >> 07) & 0x7F) | 0x80));
387  put<uint8>((uint8)(((v >> 14) & 0x7F) | 0x80));
388  put<uint8>((uint8)(((v >> 21) & 0x7F) | 0x80));
389  put<uint8>((uint8)(((v >> 28) & 0x7F) | 0x80));
390  put<uint8>((uint8)(((v >> 35) & 0x7F) | 0x80));
391  put<uint8>((uint8)(((v >> 42) & 0x7F) | 0x80));
392  put<uint8>((uint8)(((v >> 49) & 0x7F) | 0x80));
393  put<uint8>((uint8)(((v >> 56) & 0x7F) | 0x80));
394  put<uint8>((uint8)((v >> 63) & 0x7F));
395  }
396 
397  return *this;
398  }
399 
400  //! Put a string by saving it's length followed by the data itself.
401  inline binary_buffer & put_string(const char* data, size_t len)
402  {
403  return put_varint((uint32)len).append(data, len);
404  }
405 
406  //! Put a string by saving it's length followed by the data itself.
407  inline binary_buffer & put_string(const std::string& str)
408  {
409  return put_string(str.data(), str.size());
410  }
411 
412  //! Put a binary_buffer by saving it's length followed by the data itself.
414  {
415  return put_string(bb.data(), bb.size());
416  }
417 };
418 
419 /*!
420  * binary_buffer_ref represents a memory area as pointer and valid length. It
421  * is not deallocated or otherwise managed. This class can be used to pass
422  * around references to binary_buffer objects.
423  */
425 {
426 protected:
427  //! Allocated buffer pointer.
428  const char* m_data;
429 
430  //! Size of valid data.
431  size_t m_size;
432 
433 public:
434  //! Constructor, assign memory area from binary_buffer.
436  : m_data(bb.data()), m_size(bb.size())
437  { }
438 
439  //! Constructor, assign memory area from pointer and length.
440  binary_buffer_ref(const void* data, size_t n)
441  : m_data(reinterpret_cast<const char*>(data)), m_size(n)
442  { }
443 
444  //! Constructor, assign memory area from string, does NOT copy.
445  inline binary_buffer_ref(const std::string& str)
446  : m_data(str.data()), m_size(str.size())
447  { }
448 
449  //! Return a pointer to the currently kept memory area.
450  const void * data() const
451  { return m_data; }
452 
453  //! Return the currently valid length in bytes.
454  size_t size() const
455  { return m_size; }
456 
457  //! Explicit conversion to std::string (copies memory of course).
458  inline std::string str() const
459  { return std::string(reinterpret_cast<const char*>(m_data), m_size); }
460 
461  //! Compare contents of two binary_buffer_refs.
462  bool operator == (const binary_buffer_ref& br) const
463  {
464  if (m_size != br.m_size) return false;
465  return memcmp(m_data, br.m_data, m_size) == 0;
466  }
467 
468  //! Compare contents of two binary_buffer_refs.
469  bool operator != (const binary_buffer_ref& br) const
470  {
471  if (m_size != br.m_size) return true;
472  return memcmp(m_data, br.m_data, m_size) != 0;
473  }
474 };
475 
476 /*!
477  * binary_reader represents a binary_buffer_ref with an additional cursor with which
478  * the memory can be read incrementally.
479  */
481 {
482 protected:
483  //! Current read cursor
484  size_t m_curr;
485 
486 public:
487  //! Constructor, assign memory area from binary_buffer.
489  : binary_buffer_ref(br), m_curr(0)
490  { }
491 
492  //! Constructor, assign memory area from pointer and length.
493  inline binary_reader(const void* data, size_t n)
494  : binary_buffer_ref(data, n), m_curr(0)
495  { }
496 
497  //! Constructor, assign memory area from string, does NOT copy.
498  inline binary_reader(const std::string& str)
499  : binary_buffer_ref(str), m_curr(0)
500  { }
501 
502  //! Return the current read cursor.
503  inline size_t curr() const
504  {
505  return m_curr;
506  }
507 
508  //! Reset the read cursor.
510  {
511  m_curr = 0;
512  return *this;
513  }
514 
515  //! Check that n bytes are available at the cursor.
516  inline bool cursor_available(size_t n) const
517  {
518  return (m_curr + n <= m_size);
519  }
520 
521  //! Throws a std::underflow_error unless n bytes are available at the
522  //! cursor.
523  inline void check_available(size_t n) const
524  {
525  if (!cursor_available(n))
526  throw (std::underflow_error("binary_reader underrun"));
527  }
528 
529  //! Return true if the cursor is at the end of the buffer.
530  inline bool empty() const
531  {
532  return (m_curr == m_size);
533  }
534 
535  //! Advance the cursor given number of bytes without reading them.
536  inline binary_reader & skip(size_t n)
537  {
538  check_available(n);
539  m_curr += n;
540 
541  return *this;
542  }
543 
544  //! Fetch a number of unstructured bytes from the buffer, advancing the
545  //! cursor.
546  inline binary_reader & read(void* outdata, size_t datalen)
547  {
548  check_available(datalen);
549  memcpy(outdata, m_data + m_curr, datalen);
550  m_curr += datalen;
551 
552  return *this;
553  }
554 
555  //! Fetch a number of unstructured bytes from the buffer as std::string,
556  //! advancing the cursor.
557  inline std::string read(size_t datalen)
558  {
559  check_available(datalen);
560  std::string out(m_data + m_curr, datalen);
561  m_curr += datalen;
562  return out;
563  }
564 
565  //! Fetch a single item of the template type Type from the buffer,
566  //! advancing the cursor. Be careful with implicit type conversions!
567  template <typename Type>
568  inline Type get()
569  {
570  check_available(sizeof(Type));
571 
572  Type ret = *reinterpret_cast<const Type*>(m_data + m_curr);
573  m_curr += sizeof(Type);
574 
575  return ret;
576  }
577 
578  //! Fetch a varint with up to 32-bit from the buffer at the cursor.
580  {
581  uint32 u, v = get<uint8>();
582  if (!(v & 0x80)) return v;
583  v &= 0x7F;
584  u = get<uint8>(), v |= (u & 0x7F) << 7;
585  if (!(u & 0x80)) return v;
586  u = get<uint8>(), v |= (u & 0x7F) << 14;
587  if (!(u & 0x80)) return v;
588  u = get<uint8>(), v |= (u & 0x7F) << 21;
589  if (!(u & 0x80)) return v;
590  u = get<uint8>();
591  if (u & 0xF0)
592  throw (std::overflow_error("Overflow during varint decoding."));
593  v |= (u & 0x7F) << 28;
594  return v;
595  }
596 
597  //! Fetch a 64-bit varint from the buffer at the cursor.
599  {
600  uint64 u, v = get<uint8>();
601  if (!(v & 0x80)) return v;
602  v &= 0x7F;
603  u = get<uint8>(), v |= (u & 0x7F) << 7;
604  if (!(u & 0x80)) return v;
605  u = get<uint8>(), v |= (u & 0x7F) << 14;
606  if (!(u & 0x80)) return v;
607  u = get<uint8>(), v |= (u & 0x7F) << 21;
608  if (!(u & 0x80)) return v;
609  u = get<uint8>(), v |= (u & 0x7F) << 28;
610  if (!(u & 0x80)) return v;
611  u = get<uint8>(), v |= (u & 0x7F) << 35;
612  if (!(u & 0x80)) return v;
613  u = get<uint8>(), v |= (u & 0x7F) << 42;
614  if (!(u & 0x80)) return v;
615  u = get<uint8>(), v |= (u & 0x7F) << 49;
616  if (!(u & 0x80)) return v;
617  u = get<uint8>(), v |= (u & 0x7F) << 56;
618  if (!(u & 0x80)) return v;
619  u = get<uint8>();
620  if (u & 0xFE)
621  throw (std::overflow_error("Overflow during varint64 decoding."));
622  v |= (u & 0x7F) << 63;
623  return v;
624  }
625 
626  //! Fetch a string which was put via put_string().
627  inline std::string get_string()
628  {
629  uint32 len = get_varint();
630  return read(len);
631  }
632 
633  //! Fetch a binary_buffer_ref to a binary string or blob which was put via
634  //! put_string(). Does NOT copy the data.
636  {
637  uint32 len = get_varint();
638  // save object
639  binary_buffer_ref br(m_data + m_curr, len);
640  // skip over sub block data
641  skip(len);
642  return br;
643  }
644 };
645 
646 //! \}
647 
649 
650 #endif // !STXXL_COMMON_BINARY_BUFFER_HEADER
uint64 get_varint64()
Fetch a 64-bit varint from the buffer at the cursor.
binary_buffer & assign(const binary_buffer &other)
Copy the contents of another buffer object into this buffer, overwrites all current data...
binary_buffer_ref(const std::string &str)
Constructor, assign memory area from string, does NOT copy.
binary_buffer & put_varint(int v)
Append a varint to the buffer.
size_t capacity() const
Return the currently allocated buffer capacity.
binary_buffer_ref represents a memory area as pointer and valid length.
binary_buffer_ref(const binary_buffer &bb)
Constructor, assign memory area from binary_buffer.
binary_buffer & set_size(size_t n)
Set the valid bytes in the buffer, use if the buffer is filled directly.
size_t size() const
Return the currently used length in bytes.
size_t size() const
Return the currently valid length in bytes.
uint32 get_varint()
Fetch a varint with up to 32-bit from the buffer at the cursor.
unsigned long long int uint64
Definition: types.h:39
binary_buffer_ref get_binary_buffer_ref()
Fetch a binary_buffer_ref to a binary string or blob which was put via put_string(). Does NOT copy the data.
size_t m_size
Size of valid data.
char * m_data
Allocated buffer pointer.
Definition: binary_buffer.h:45
const char * data() const
Return a pointer to the currently kept memory area.
Definition: binary_buffer.h:94
binary_buffer & clear()
Clears the memory contents, does not deallocate the memory.
binary_buffer & put_varint(uint64 v)
Append a varint to the buffer.
binary_buffer(const binary_buffer &other)
Copy-Constructor, duplicates memory content.
Definition: binary_buffer.h:60
std::string read(size_t datalen)
Fetch a number of unstructured bytes from the buffer as std::string, advancing the cursor...
binary_reader & read(void *outdata, size_t datalen)
Fetch a number of unstructured bytes from the buffer, advancing the cursor.
binary_buffer & dealloc()
Deallocates the kept memory space (we use dealloc() instead of free() as a name, because sometimes &quot;f...
bool cursor_available(size_t n) const
Check that n bytes are available at the cursor.
size_t curr() const
Return the current read cursor.
binary_reader represents a binary_buffer_ref with an additional cursor with which the memory can be r...
binary_buffer(size_t n)
Constructor, create object with n bytes pre-allocated.
Definition: binary_buffer.h:74
~binary_buffer()
Destroys the memory space.
Definition: binary_buffer.h:88
binary_buffer & put_string(const char *data, size_t len)
Put a string by saving it&#39;s length followed by the data itself.
const void * data() const
Return a pointer to the currently kept memory area.
binary_buffer & put(const Type item)
Put (append) a single item of the template type T to the buffer. Be careful with implicit type conver...
binary_buffer & put_string(const std::string &str)
Put a string by saving it&#39;s length followed by the data itself.
void check_available(size_t n) const
Throws a std::underflow_error unless n bytes are available at the cursor.
binary_buffer()
Create a new empty object.
Definition: binary_buffer.h:55
unsigned int uint32
Definition: types.h:37
binary_buffer(const std::string &str)
Constructor from std::string, copies string content.
Definition: binary_buffer.h:81
binary_reader & skip(size_t n)
Advance the cursor given number of bytes without reading them.
binary_buffer & align(size_t n)
Align the size of the buffer to a multiple of n. Fills up with 0s.
binary_buffer & append(const std::string &s)
Append to contents of a std::string, excluding the null (which isn&#39;t contained in the string size any...
bool operator!=(const uint_pair &b) const
inequality checking operator
Definition: uint_types.h:198
size_t m_curr
Current read cursor.
const char * m_data
Allocated buffer pointer.
unsigned char uint8
Definition: types.h:33
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
std::string str() const
Explicit conversion to std::string (copies memory of course).
binary_buffer & dynalloc(size_t n)
Dynamically allocate more memory. At least n bytes will be available, probably more to compensate fut...
binary_reader(const void *data, size_t n)
Constructor, assign memory area from pointer and length.
binary_buffer & append(const class binary_buffer &bb)
Append the contents of a different buffer object to this one.
binary_buffer represents a dynamically growable area of memory, which can be modified by appending in...
Definition: binary_buffer.h:41
size_t m_capacity
Total capacity of buffer.
Definition: binary_buffer.h:51
bool empty() const
Return true if the cursor is at the end of the buffer.
binary_reader & rewind()
Reset the read cursor.
char * data()
Return a writeable pointer to the currently kept memory area.
binary_buffer & append(const void *data, size_t len)
Append a memory range to the buffer.
binary_reader(const std::string &str)
Constructor, assign memory area from string, does NOT copy.
size_t m_size
Size of valid data.
Definition: binary_buffer.h:48
std::string str() const
Explicit conversion to std::string (copies memory of course).
const char * detach()
Detach the memory from the object, returns the memory pointer.
binary_buffer(const void *data, size_t n)
Constructor, copy memory area.
Definition: binary_buffer.h:67
std::string get_string()
Fetch a string which was put via put_string().
binary_buffer_ref(const void *data, size_t n)
Constructor, assign memory area from pointer and length.
binary_buffer & assign(const void *data, size_t len)
Copy a memory range into the buffer, overwrites all current data. Roughly equivalent to clear() follo...
binary_buffer & put_varint(uint32 v)
Append a varint to the buffer.
binary_reader(const binary_buffer_ref &br)
Constructor, assign memory area from binary_buffer.
binary_buffer & put_string(const binary_buffer &bb)
Put a binary_buffer by saving it&#39;s length followed by the data itself.
binary_buffer & alloc(size_t n)
Make sure that at least n bytes are allocated.
bool operator==(const uint_pair &b) const
equality checking operator
Definition: uint_types.h:192
#define STXXL_END_NAMESPACE
Definition: namespace.h:17