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 
150  void cut(const size_t at, const size_t byte_count) {
151  if (byte_count>0) {
152  const size_t keepFrom = at+byte_count;
153 
154  if (keepFrom <= get_position()) {
155  const size_t restlen = get_position()-keepFrom;
156  memmove(data+at, data+keepFrom, restlen+1);
157 
158  set_pos(get_position()-byte_count);
159  }
160  else if (at < get_position()) {
161  set_pos(at);
162  }
163  }
164  }
165 
167  std::swap(data, other.data);
168  std::swap(buffer_size, other.buffer_size);
169  std::swap(pos, other.pos);
170  }
171 
172  // --------------------
173 
174  void put(char c) {
176  ensure_mem(1);
177  data[pos] = c;
178  inc_pos(1);
179  }
180  void nput(char c, size_t count) {
182  ensure_mem(count);
183  if (count) {
184  memset(data+pos, c, count);
185  inc_pos(count);
186  }
187  }
188 
189  void ncat(const char *from, size_t count) {
193  if (count) {
194  ensure_mem(count);
195  memcpy(data+pos, from, count);
196  inc_pos(count);
197  }
198  }
199  void cat(const char *from) {
201  ncat(from, strlen(from));
202  }
203 
204  int ncatPadded(const char *from, size_t count, size_t paddedWidth) {
206  ensure_mem(std::max(count, paddedWidth));
207  ncat(from, count);
208  int toPad = long(paddedWidth)-long(count);
209  if (toPad>0) nput(' ', toPad);
210  return toPad;
211  }
212  int catPadded(const char *from, size_t paddedWidth) {
217  return ncatPadded(from, strlen(from), paddedWidth);
218  }
219 
220  void npaste_at(size_t at, const char *from, size_t count) {
224  size_t till = at+count-1;
225  if (get_position() <= till) {
226  arb_assert(0); // attempt to paste over end-of-buffer. this is most-likely by mistake
227  // fallback code:
228  nput(' ', till+1-get_position()); // increase string to allow paste
229  }
230  memcpy(data+at, from, count);
231  }
232  void paste_at(size_t at, const char *from) {
234  npaste_at(at, from, strlen(from));
235  }
236 
237  void vnprintf(size_t maxlen, const char *templat, va_list& parg) __ATTR__VFORMAT_MEMBER(2);
238  void nprintf(size_t maxlen, const char *templat, ...) __ATTR__FORMAT_MEMBER(2);
239 
240  void putlong(long l) { nprintf(100, "%li", l); }
241  void putfloat(float f) { nprintf(100, "%f", f); }
242 
243  // wrapped cats:
244  void cat_wrapped(const char *in, const char *from) {
246  arb_assert(in[0] && in[1] && !in[2]); // 'in' has to be exactly 2 chars
247  put(in[0]);
248  cat(from);
249  put(in[1]);
250  }
251  void cat_sQuoted(const char *from) { cat_wrapped("''", from); }
252  void cat_dQuoted(const char *from) { cat_wrapped("\"\"", from); }
253 };
254 
255 #else
256 #error arb_strbuf.h included twice
257 #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 cut(const size_t at, const size_t byte_count)
Definition: arb_strbuf.h:150
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:232
void erase()
Definition: arb_strbuf.h:141
void npaste_at(size_t at, const char *from, size_t count)
Definition: arb_strbuf.h:220
char * release()
Definition: arb_strbuf.h:129
void nput(char c, size_t count)
Definition: arb_strbuf.h:180
void cat(const char *from)
Definition: arb_strbuf.h:199
int ncatPadded(const char *from, size_t count, size_t paddedWidth)
Definition: arb_strbuf.h:204
bool filled() const
Definition: arb_strbuf.h:117
void putlong(long l)
Definition: arb_strbuf.h:240
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:241
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:244
void swap_content(GBS_strstruct &other)
Definition: arb_strbuf.h:166
GBS_strstruct(size_t buffersize)
Definition: arb_strbuf.h:99
void ncat(const char *from, size_t count)
Definition: arb_strbuf.h:189
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:212
void cat_dQuoted(const char *from)
Definition: arb_strbuf.h:252
#define NULp
Definition: cxxforward.h:116
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:251
size_t get_position() const
Definition: arb_strbuf.h:112
void put(char c)
Definition: arb_strbuf.h:174
#define max(a, b)
Definition: f2c.h:154
GB_write_int const char s
Definition: AW_awar.cxx:154