libtasks Documentation  1.6
buffer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014 ADTECH GmbH
3  * Licensed under MIT (https://github.com/adtechlabs/libtasks/blob/master/COPYING)
4  *
5  * Author: Andreas Pohl
6  */
7 
8 #ifndef _BUFFER_H_
9 #define _BUFFER_H_
10 
11 #include <vector>
12 #include <cstring>
13 #include <cassert>
14 #include <streambuf>
15 
16 #include <tasks/logging.h>
17 
18 namespace tasks {
19 namespace tools {
20 
21 class buffer : public std::streambuf {
22  public:
23  buffer() {
24  setg(ptr_begin(), ptr_begin(), ptr_end());
25  setp(ptr_begin(), ptr_end());
26  }
27 
28  buffer(std::size_t size) : buffer() { set_size(size); }
29 
30  inline char* ptr_write() { return pptr(); }
31 
32  inline char* ptr_read() { return gptr(); }
33 
34  inline const char* ptr_read() const { return gptr(); }
35 
36  inline char* ptr(std::size_t pos) {
37  assert(pos <= m_size);
38  return &m_buffer[pos];
39  }
40 
41  inline const char* ptr(std::size_t pos) const {
42  assert(pos <= m_size);
43  return &m_buffer[pos];
44  }
45 
46  inline char* ptr_begin() { return &m_buffer[0]; }
47 
48  inline const char* ptr_begin() const { return &m_buffer[0]; }
49 
50  inline char* ptr_end() { return &m_buffer[m_size]; }
51 
52  inline const char* ptr_end() const { return &m_buffer[m_size]; }
53 
54  inline std::size_t offset_write() const { return pptr() - ptr_begin(); }
55 
56  inline std::size_t offset_read() const { return gptr() - ptr_begin(); }
57 
58  inline void move_ptr_write(std::size_t s) { setp(ptr_write() + s, ptr_end()); }
59 
60  inline void move_ptr_read(std::size_t s) { setg(ptr_begin(), ptr_read() + s, ptr_end()); }
61 
62  inline void move_ptr_write_abs(std::size_t pos) { setp(ptr(pos), ptr_end()); }
63 
64  inline void move_ptr_read_abs(std::size_t pos) { setg(ptr_begin(), ptr(pos), ptr_end()); }
65 
66  inline std::streamsize to_write() const { return ptr_end() - pptr(); }
67 
68  inline std::streamsize to_read() const { return ptr_end() - gptr(); }
69 
70  inline std::size_t size() const { return m_size; }
71 
72  inline void set_size(std::size_t s) {
73  auto p_rd = ptr_read();
74  auto p_wr = ptr_write();
75  if (m_buffer.size() < s) {
76  auto oread = offset_read();
77  auto owrite = offset_write();
78  m_buffer.resize(s + 1024);
79  p_rd = ptr(oread);
80  p_wr = ptr(owrite);
81  }
82  m_size = s;
83  setg(ptr_begin(), p_rd, ptr_end());
84  setp(p_wr, ptr_end());
85  }
86 
87  inline void shrink() { m_buffer.resize(m_size); }
88 
89  inline std::size_t buffer_size() { return m_buffer.size(); }
90 
91  inline std::streamsize write(const char_type* data, std::streamsize size) { return xsputn(data, size); }
92 
93  inline std::streamsize read(char_type* data, std::streamsize size) { return xsgetn(data, size); }
94 
95  int_type sputc(char_type c) {
96  set_size(m_size + 1);
97  return std::streambuf::sputc(c);
98  }
99 
100  int_type overflow(int_type ch) { return sputc(traits_type::to_char_type(ch)); }
101 
102  inline void clear() {
103  m_size = 0;
104  setg(ptr_begin(), ptr_begin(), ptr_end());
105  setp(ptr_begin(), ptr_end());
106  }
107 
108  protected:
109  // std::streambuf override
110  std::streamsize xsputn(const char_type* s, std::streamsize count) {
111  set_size(m_size + count);
112  return std::streambuf::xsputn(s, count);
113  }
114 
115  // std::streambuf override
116  std::streamsize xsgetn(char_type* s, std::streamsize count) {
117  auto size = count;
118  auto bytes_left = to_read();
119  if (size > bytes_left) {
120  size = bytes_left;
121  }
122  return std::streambuf::xsgetn(s, size);
123  }
124 
125  private:
126  std::vector<char> m_buffer;
127  std::size_t m_size = 0;
128 };
129 
130 } // tools
131 } // tasks
132 
133 #endif // _BUFFER_H_
std::size_t size() const
Definition: buffer.h:70
void move_ptr_write_abs(std::size_t pos)
Definition: buffer.h:62
std::size_t offset_write() const
Definition: buffer.h:54
char * ptr_read()
Definition: buffer.h:32
const char * ptr_end() const
Definition: buffer.h:52
int_type overflow(int_type ch)
Definition: buffer.h:100
void move_ptr_read(std::size_t s)
Definition: buffer.h:60
std::streamsize xsputn(const char_type *s, std::streamsize count)
Definition: buffer.h:110
char * ptr_begin()
Definition: buffer.h:46
void move_ptr_write(std::size_t s)
Definition: buffer.h:58
std::size_t m_size
Definition: buffer.h:127
const char * ptr(std::size_t pos) const
Definition: buffer.h:41
char * ptr_write()
Definition: buffer.h:30
std::streamsize read(char_type *data, std::streamsize size)
Definition: buffer.h:93
std::size_t offset_read() const
Definition: buffer.h:56
std::size_t buffer_size()
Definition: buffer.h:89
int_type sputc(char_type c)
Definition: buffer.h:95
char * ptr(std::size_t pos)
Definition: buffer.h:36
char * ptr_end()
Definition: buffer.h:50
std::streamsize write(const char_type *data, std::streamsize size)
Definition: buffer.h:91
std::streamsize to_read() const
Definition: buffer.h:68
void set_size(std::size_t s)
Definition: buffer.h:72
const char * ptr_begin() const
Definition: buffer.h:48
std::streamsize to_write() const
Definition: buffer.h:66
void move_ptr_read_abs(std::size_t pos)
Definition: buffer.h:64
std::streamsize xsgetn(char_type *s, std::streamsize count)
Definition: buffer.h:116
std::vector< char > m_buffer
Definition: buffer.h:126
buffer(std::size_t size)
Definition: buffer.h:28
const char * ptr_read() const
Definition: buffer.h:34