source: branches/stable/CORE/arb_strbuf.h

Last change on this file was 11060, checked in by westram, 6 years ago
File size: 4.8 KB
Line 
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 ATTRIBUTES_H
21#include <attributes.h>
22#endif
23
24
25// -----------------------
26//      String streams
27
28class GBS_strstruct : virtual Noncopyable {
29    char   *data;
30    size_t  buffer_size;
31    size_t  pos;
32
33    void set_pos(size_t toPos) {
34        pos = toPos;
35        if (data) data[pos] = 0;
36    }
37    void inc_pos(size_t inc) { set_pos(pos+inc); }
38
39public:
40
41    GBS_strstruct()
42        : data(NULL)
43        , buffer_size(0)
44        , pos(0)
45    {}
46    GBS_strstruct(size_t buffersize)
47        : data(NULL)
48        , buffer_size(0)
49        , pos(0)
50    {
51        alloc_mem(buffersize);
52    }
53    ~GBS_strstruct() { free(data); }
54
55    size_t get_buffer_size() const { return buffer_size; }
56    size_t get_position() const { return pos; }
57
58    bool filled() const { return get_position()>0; }
59    bool empty() const { return !filled(); }
60
61    const char *get_data() const { return data; }
62
63    char *release_mem(size_t& size) {
64        char *result = data;
65        size         = buffer_size;
66        buffer_size  = 0;
67        data         = 0;
68        return result;
69    }
70    char *release() { size_t s; return release_mem(s); }
71
72    void erase() { set_pos(0); }
73
74    void assign_mem(char *block, size_t blocksize) {
75        free(data);
76
77        arb_assert(block && blocksize>0);
78
79        data      = block;
80        buffer_size = blocksize;
81
82        erase();
83    }
84    void reassign_mem(GBS_strstruct& from) {
85        size_t  size;
86        char   *block = from.release_mem(size);
87
88        assign_mem(block, size);
89    }
90
91    void alloc_mem(size_t blocksize) {
92        arb_assert(blocksize>0);
93        arb_assert(!data);
94
95        assign_mem((char*)malloc(blocksize), blocksize);
96    }
97    void realloc_mem(size_t newsize) {
98        if (!data) alloc_mem(newsize);
99        else {
100            // cppcheck-suppress memleakOnRealloc
101            data        = (char*)realloc(data, newsize);
102            buffer_size = newsize;
103
104            arb_assert(pos<newsize);
105        }
106    }
107
108    void ensure_mem(size_t needed_size) {
109        // ensures insertion of 'needed_size' bytes is ok
110        size_t whole_needed_size = pos+needed_size+1;
111        if (buffer_size<whole_needed_size) {
112            size_t next_size = (whole_needed_size * 3) >> 1;
113            realloc_mem(next_size);
114        }
115    }
116
117    // --------------------
118
119    void cut_tail(size_t byte_count) {
120        set_pos(pos<byte_count ? 0 : pos-byte_count);
121    }
122
123    void put(char c) {
124        ensure_mem(1);
125        data[pos] = c;
126        inc_pos(1);
127    }
128    void nput(char c, size_t count) {
129        ensure_mem(count);
130        memset(data+pos, c, count);
131        inc_pos(count);
132    }
133
134    void ncat(const char *from, size_t count) {
135        if (count) {
136            ensure_mem(count);
137            memcpy(data+pos, from, count);
138            inc_pos(count);
139        }
140    }
141    void cat(const char *from) { ncat(from, strlen(from)); }
142
143    void vnprintf(size_t maxlen, const char *templat, va_list& parg) __ATTR__VFORMAT_MEMBER(2);
144    void nprintf(size_t maxlen, const char *templat, ...) __ATTR__FORMAT_MEMBER(2);
145
146    void putlong(long l) { nprintf(100, "%li", l); }
147    void putfloat(float f) { nprintf(100, "%f", f); }
148};
149
150// old interface
151
152GBS_strstruct *GBS_stropen(long init_size);
153char          *GBS_strclose(GBS_strstruct *strstr);
154void           GBS_strforget(GBS_strstruct *strstr);
155char          *GBS_mempntr(GBS_strstruct *strstr);
156long           GBS_memoffset(GBS_strstruct *strstr);
157void           GBS_str_cut_tail(GBS_strstruct *strstr, size_t byte_count);
158void           GBS_strncat(GBS_strstruct *strstr, const char *ptr, size_t len);
159void           GBS_strcat(GBS_strstruct *strstr, const char *ptr);
160void           GBS_strnprintf(GBS_strstruct *strstr, long maxlen, const char *templat, ...) __ATTR__FORMAT(3);
161void           GBS_chrcat(GBS_strstruct *strstr, char ch);
162void           GBS_chrncat(GBS_strstruct *strstr, char ch, size_t n);
163void           GBS_intcat(GBS_strstruct *strstr, long val);
164void           GBS_floatcat(GBS_strstruct *strstr, double val);
165
166#else
167#error arb_strbuf.h included twice
168#endif // ARB_STRBUF_H
Note: See TracBrowser for help on using the repository browser.