ARB
arb_strbuf.h
Go to the documentation of this file.
1 // ============================================================= //
2 // //
3 // File : arb_strbuf.h //
4 // Purpose : "unlimited" output buffer //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // ============================================================= //
10 
11 #ifndef ARB_STRBUF_H
12 #define ARB_STRBUF_H
13 
14 #ifndef ARBTOOLS_H
15 #include <arbtools.h>
16 #endif
17 #ifndef ARB_ASSERT_H
18 #include <arb_assert.h>
19 #endif
20 #ifndef ARB_MEM_H
21 #include "arb_mem.h"
22 #endif
23 #ifndef ATTRIBUTES_H
24 #include <attributes.h>
25 #endif
26 #ifndef ARB_STRING_H
27 #include "arb_string.h"
28 #endif
29 #ifndef _GLIBCXX_ALGORITHM
30 #include <algorithm>
31 #endif
32 
33 
34 // -----------------------
35 // String streams
36 
37 class GBS_strstruct : virtual Noncopyable {
38  char *data;
39  size_t buffer_size;
40  size_t pos;
41 
42  void set_pos(size_t toPos) {
43  pos = toPos;
44  if (data) data[pos] = 0;
45  }
46  void inc_pos(size_t inc) { set_pos(pos+inc); }
47 
48  char *release_mem(size_t& size) {
50  char *result = data;
51  size = buffer_size;
52  buffer_size = 0;
53  data = NULp;
54  return result;
55  }
56  void assign_mem(char *block, size_t blocksize) {
57  free(data);
58 
59  arb_assert(block && blocksize>0);
60 
61  data = block;
62  buffer_size = blocksize;
63 
64  erase();
65  }
66 
67  void alloc_mem(size_t blocksize) {
68  arb_assert(blocksize>0);
69  arb_assert(!data);
70 
71  assign_mem(ARB_alloc<char>(blocksize), blocksize);
72  }
73  void realloc_mem(size_t newsize) {
74  if (!data) alloc_mem(newsize);
75  else {
76  // cppcheck-suppress memleakOnRealloc
77  ARB_realloc(data, newsize);
78  buffer_size = newsize;
79 
80  arb_assert(pos<newsize);
81  }
82  }
83  void ensure_mem(size_t needed_size) {
84  // ensures insertion of 'needed_size' bytes is ok
85  size_t whole_needed_size = pos+needed_size+1;
86  if (buffer_size<whole_needed_size) {
87  size_t next_size = (whole_needed_size * 3) >> 1;
88  realloc_mem(next_size);
89  }
90  }
91 
92 public:
93 
95  data(NULp),
96  buffer_size(0),
97  pos(0)
98  {}
99  GBS_strstruct(size_t buffersize) :
100  data(NULp),
101  buffer_size(0),
102  pos(0)
103  {
104  alloc_mem(buffersize);
105  }
106  ~GBS_strstruct() { free(data); }
107 
108  size_t get_buffer_size() const {
110  return buffer_size;
111  }
112  size_t get_position() const {
114  return pos;
115  }
116 
117  bool filled() const { return get_position()>0; }
118  bool empty() const { return !filled(); }
119 
120  const char *get_data() const {
123  return null2empty(data);
124  }
125  char *get_copy() const {
127  return ARB_strndup(get_data(), get_position());
128  }
129  char *release() {
131  size_t s; return release_mem(s);
132  }
135  if (buffer_size > (pos*2) && buffer_size>1000) {
136  realloc_mem(pos+1);
137  }
138  return release();
139  }
140 
141  void erase() {
143  set_pos(0);
144  }
145  void cut_tail(size_t byte_count) {
147  set_pos(pos<byte_count ? 0 : pos-byte_count);
148  }
149 
151  std::swap(data, other.data);
152  std::swap(buffer_size, other.buffer_size);
153  std::swap(pos, other.pos);
154  }
155 
156  // --------------------
157 
158  void put(char c) {
160  ensure_mem(1);
161  data[pos] = c;
162  inc_pos(1);
163  }
164  void nput(char c, size_t count) {
166  ensure_mem(count);
167  if (count) {
168  memset(data+pos, c, count);
169  inc_pos(count);
170  }
171  }
172 
173  void ncat(const char *from, size_t count) {
177  if (count) {
178  ensure_mem(count);
179  memcpy(data+pos, from, count);
180  inc_pos(count);
181  }
182  }
183  void cat(const char *from) {
185  ncat(from, strlen(from));
186  }
187 
188  int ncatPadded(const char *from, size_t count, size_t paddedWidth) {
190  ensure_mem(std::max(count, paddedWidth));
191  ncat(from, count);
192  int toPad = long(paddedWidth)-long(count);
193  if (toPad>0) nput(' ', toPad);
194  return toPad;
195  }
196  int catPadded(const char *from, size_t paddedWidth) {
201  return ncatPadded(from, strlen(from), paddedWidth);
202  }
203 
204  void npaste_at(size_t at, const char *from, size_t count) {
208  size_t till = at+count-1;
209  if (get_position() <= till) {
210  arb_assert(0); // attempt to paste over end-of-buffer. this is most-likely by mistake
211  // fallback code:
212  nput(' ', till+1-get_position()); // increase string to allow paste
213  }
214  memcpy(data+at, from, count);
215  }
216  void paste_at(size_t at, const char *from) {
218  npaste_at(at, from, strlen(from));
219  }
220 
221  void vnprintf(size_t maxlen, const char *templat, va_list& parg) __ATTR__VFORMAT_MEMBER(2);
222  void nprintf(size_t maxlen, const char *templat, ...) __ATTR__FORMAT_MEMBER(2);
223 
224  void putlong(long l) { nprintf(100, "%li", l); }
225  void putfloat(float f) { nprintf(100, "%f", f); }
226 
227  // wrapped cats:
228  void cat_wrapped(const char *in, const char *from) {
230  arb_assert(in[0] && in[1] && !in[2]); // 'in' has to be exactly 2 chars
231  put(in[0]);
232  cat(from);
233  put(in[1]);
234  }
235  void cat_sQuoted(const char *from) { cat_wrapped("''", from); }
236  void cat_dQuoted(const char *from) { cat_wrapped("\"\"", from); }
237 };
238 
239 #else
240 #error arb_strbuf.h included twice
241 #endif // ARB_STRBUF_H
#define arb_assert(cond)
Definition: arb_assert.h:245
string result
void cut_tail(size_t byte_count)
Definition: arb_strbuf.h:145
void vnprintf(size_t maxlen, const char *templat, va_list &parg) __ATTR__VFORMAT_MEMBER(2)
Definition: arb_strbuf.cxx:13
long
Definition: AW_awar.cxx:152
void paste_at(size_t at, const char *from)
Definition: arb_strbuf.h:216
void erase()
Definition: arb_strbuf.h:141
void npaste_at(size_t at, const char *from, size_t count)
Definition: arb_strbuf.h:204
char * release()
Definition: arb_strbuf.h:129
void nput(char c, size_t count)
Definition: arb_strbuf.h:164
void cat(const char *from)
Definition: arb_strbuf.h:183
int ncatPadded(const char *from, size_t count, size_t paddedWidth)
Definition: arb_strbuf.h:188
bool filled() const
Definition: arb_strbuf.h:117
void putlong(long l)
Definition: arb_strbuf.h:224
size_t get_buffer_size() const
Definition: arb_strbuf.h:108
#define __ATTR__FORMAT_MEMBER(pos)
Definition: attributes.h:62
char * get_copy() const
Definition: arb_strbuf.h:125
void putfloat(float f)
Definition: arb_strbuf.h:225
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
Definition: ad_io_inline.h:19
void cat_wrapped(const char *in, const char *from)
Definition: arb_strbuf.h:228
void swap_content(GBS_strstruct &other)
Definition: arb_strbuf.h:150
GBS_strstruct(size_t buffersize)
Definition: arb_strbuf.h:99
void ncat(const char *from, size_t count)
Definition: arb_strbuf.h:173
char * ARB_strndup(const char *start, int len)
Definition: arb_string.h:83
void nprintf(size_t maxlen, const char *templat,...) __ATTR__FORMAT_MEMBER(2)
Definition: arb_strbuf.cxx:29
bool empty() const
Definition: arb_strbuf.h:118
void ARB_realloc(TYPE *&tgt, size_t nelem)
Definition: arb_mem.h:43
int catPadded(const char *from, size_t paddedWidth)
Definition: arb_strbuf.h:196
void cat_dQuoted(const char *from)
Definition: arb_strbuf.h:236
#define NULp
Definition: cxxforward.h:114
static ED4_block block
Definition: ED4_block.cxx:74
const char * get_data() const
Definition: arb_strbuf.h:120
#define __ATTR__VFORMAT_MEMBER(pos)
Definition: attributes.h:63
char * release_memfriendly()
Definition: arb_strbuf.h:133
void cat_sQuoted(const char *from)
Definition: arb_strbuf.h:235
size_t get_position() const
Definition: arb_strbuf.h:112
void put(char c)
Definition: arb_strbuf.h:158
#define max(a, b)
Definition: f2c.h:154
GB_write_int const char s
Definition: AW_awar.cxx:154