1 /* charstring.c -- dynamically-sized char array that can report size
2 * in both characters and bytes
4 * This code is Copyright (c) 2014, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
12 #define CHARSTRING_DEFAULT_SIZE 64
15 char *buffer; /* the char array, not always null-terminated */
16 size_t max; /* current size of the char array, in bytes */
17 char *cur; /* size in bytes = cur - buffer, without trailing null */
22 charstring_reserve(charstring_t s, size_t need)
24 const size_t cur = s->cur - s->buffer;
26 while (need >= s->max - cur) {
27 /* Insufficient capacity, so double it. */
28 s->buffer = mh_xrealloc(s->buffer, s->max *= 2);
29 s->cur = s->buffer + cur;
34 * max is in characters
37 charstring_create(size_t max)
39 charstring_t s = mh_xcalloc(1, sizeof(*s));
41 s->max = max ? max : CHARSTRING_DEFAULT_SIZE;
42 s->cur = s->buffer = mh_xcalloc(s->max, 1);
48 charstring_copy(const charstring_t src)
50 const size_t num = src->cur - src->buffer;
51 charstring_t s = mh_xcalloc(1, sizeof(*s));
54 s->buffer = mh_xcalloc(s->max, 1);
55 memcpy(s->buffer, src->buffer, num);
56 s->cur = s->buffer + num;
62 * OK to call charstring_free with a NULL argument.
65 charstring_free(charstring_t s)
74 charstring_push_back(charstring_t s, const char c)
76 charstring_reserve(s, s->cur - s->buffer + 1);
81 * num is the number of bytes in c
84 charstring_push_back_chars(charstring_t s, const char c[], size_t num)
86 charstring_reserve(s, s->cur - s->buffer + num);
87 memcpy(s->cur, c, num);
92 charstring_append(charstring_t dest, const charstring_t src)
94 const size_t num = src->cur - src->buffer;
97 charstring_reserve(dest, dest->cur - dest->buffer + num);
98 memcpy(dest->cur, src->buffer, num);
104 charstring_append_cstring(charstring_t dest, const char src[])
106 const size_t num = strlen(src);
109 charstring_reserve(dest, dest->cur - dest->buffer + num);
110 memcpy(dest->cur, src, num); /* Exclude src's trailing NUL. */
116 charstring_clear(charstring_t s)
122 * Don't store return value of charstring_buffer() and use later after
123 * intervening push_back's; use charstring_buffer_copy() instead.
126 charstring_buffer(const charstring_t s)
128 charstring_reserve(s, s->cur - s->buffer + 1);
130 /* This is the only place that we null-terminate the buffer. */
132 /* Don't increment cur so that more can be appended later, and so
133 that charstring_bytes() behaves as strlen() by not counting the
140 charstring_buffer_copy(const charstring_t s)
142 char *copy = mh_xcalloc(s->cur - s->buffer + 1, 1);
144 /* Use charstring_buffer() to null terminate the buffer. */
145 memcpy(copy, charstring_buffer(s), s->cur - s->buffer + 1);
151 charstring_bytes(const charstring_t s)
153 return s->cur - s->buffer;