diff options
Diffstat (limited to 'strbuf.h')
-rw-r--r-- | strbuf.h | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/strbuf.h b/strbuf.h new file mode 100644 index 0000000..fbc8651 --- /dev/null +++ b/strbuf.h | |||
@@ -0,0 +1,154 @@ | |||
1 | /* strbuf - String buffer routines | ||
2 | * | ||
3 | * Copyright (c) 2010-2011 Mark Pulford <mark@kyne.com.au> | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining | ||
6 | * a copy of this software and associated documentation files (the | ||
7 | * "Software"), to deal in the Software without restriction, including | ||
8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
9 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
10 | * permit persons to whom the Software is furnished to do so, subject to | ||
11 | * the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be | ||
14 | * included in all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
19 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
20 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
21 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
23 | */ | ||
24 | |||
25 | #include <stdlib.h> | ||
26 | #include <stdarg.h> | ||
27 | |||
28 | /* Size: Total bytes allocated to *buf | ||
29 | * Length: String length, excluding optional NULL terminator. | ||
30 | * Increment: Allocation increments when resizing the string buffer. | ||
31 | * Dynamic: True if created via strbuf_new() | ||
32 | */ | ||
33 | |||
34 | typedef struct { | ||
35 | char *buf; | ||
36 | int size; | ||
37 | int length; | ||
38 | int increment; | ||
39 | int dynamic; | ||
40 | int reallocs; | ||
41 | int debug; | ||
42 | } strbuf_t; | ||
43 | |||
44 | #ifndef STRBUF_DEFAULT_SIZE | ||
45 | #define STRBUF_DEFAULT_SIZE 1023 | ||
46 | #endif | ||
47 | #ifndef STRBUF_DEFAULT_INCREMENT | ||
48 | #define STRBUF_DEFAULT_INCREMENT -2 | ||
49 | #endif | ||
50 | |||
51 | /* Initialise */ | ||
52 | extern strbuf_t *strbuf_new(int len); | ||
53 | extern void strbuf_init(strbuf_t *s, int len); | ||
54 | extern void strbuf_set_increment(strbuf_t *s, int increment); | ||
55 | |||
56 | /* Release */ | ||
57 | extern void strbuf_free(strbuf_t *s); | ||
58 | extern char *strbuf_free_to_string(strbuf_t *s, int *len); | ||
59 | |||
60 | /* Management */ | ||
61 | extern void strbuf_resize(strbuf_t *s, int len); | ||
62 | static int strbuf_empty_length(strbuf_t *s); | ||
63 | static int strbuf_length(strbuf_t *s); | ||
64 | static char *strbuf_string(strbuf_t *s, int *len); | ||
65 | static void strbuf_ensure_empty_length(strbuf_t *s, int len); | ||
66 | static char *strbuf_empty_ptr(strbuf_t *s); | ||
67 | static void strbuf_extend_length(strbuf_t *s, int len); | ||
68 | |||
69 | /* Update */ | ||
70 | extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...); | ||
71 | extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...); | ||
72 | static void strbuf_append_mem(strbuf_t *s, const char *c, int len); | ||
73 | extern void strbuf_append_string(strbuf_t *s, const char *str); | ||
74 | static void strbuf_append_char(strbuf_t *s, const char c); | ||
75 | static void strbuf_ensure_null(strbuf_t *s); | ||
76 | |||
77 | /* Reset string for before use */ | ||
78 | static inline void strbuf_reset(strbuf_t *s) | ||
79 | { | ||
80 | s->length = 0; | ||
81 | } | ||
82 | |||
83 | static inline int strbuf_allocated(strbuf_t *s) | ||
84 | { | ||
85 | return s->buf != NULL; | ||
86 | } | ||
87 | |||
88 | /* Return bytes remaining in the string buffer | ||
89 | * Ensure there is space for a NULL terminator. */ | ||
90 | static inline int strbuf_empty_length(strbuf_t *s) | ||
91 | { | ||
92 | return s->size - s->length - 1; | ||
93 | } | ||
94 | |||
95 | static inline void strbuf_ensure_empty_length(strbuf_t *s, int len) | ||
96 | { | ||
97 | if (len > strbuf_empty_length(s)) | ||
98 | strbuf_resize(s, s->length + len); | ||
99 | } | ||
100 | |||
101 | static inline char *strbuf_empty_ptr(strbuf_t *s) | ||
102 | { | ||
103 | return s->buf + s->length; | ||
104 | } | ||
105 | |||
106 | static inline void strbuf_extend_length(strbuf_t *s, int len) | ||
107 | { | ||
108 | s->length += len; | ||
109 | } | ||
110 | |||
111 | static inline int strbuf_length(strbuf_t *s) | ||
112 | { | ||
113 | return s->length; | ||
114 | } | ||
115 | |||
116 | static inline void strbuf_append_char(strbuf_t *s, const char c) | ||
117 | { | ||
118 | strbuf_ensure_empty_length(s, 1); | ||
119 | s->buf[s->length++] = c; | ||
120 | } | ||
121 | |||
122 | static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c) | ||
123 | { | ||
124 | s->buf[s->length++] = c; | ||
125 | } | ||
126 | |||
127 | static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len) | ||
128 | { | ||
129 | strbuf_ensure_empty_length(s, len); | ||
130 | memcpy(s->buf + s->length, c, len); | ||
131 | s->length += len; | ||
132 | } | ||
133 | |||
134 | static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len) | ||
135 | { | ||
136 | memcpy(s->buf + s->length, c, len); | ||
137 | s->length += len; | ||
138 | } | ||
139 | |||
140 | static inline void strbuf_ensure_null(strbuf_t *s) | ||
141 | { | ||
142 | s->buf[s->length] = 0; | ||
143 | } | ||
144 | |||
145 | static inline char *strbuf_string(strbuf_t *s, int *len) | ||
146 | { | ||
147 | if (len) | ||
148 | *len = s->length; | ||
149 | |||
150 | return s->buf; | ||
151 | } | ||
152 | |||
153 | /* vi:ai et sw=4 ts=4: | ||
154 | */ | ||