nmsg  0.9.0
strbuf.c
1 /*
2  * Copyright (c) 2009, 2012 by Farsight Security, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* Import. */
18 
19 #include "private.h"
20 
21 /* Macros. */
22 
23 #define DEFAULT_STRBUF_ALLOC_SZ 1024
24 
25 /* Export. */
26 
27 struct nmsg_strbuf *
29  struct nmsg_strbuf *sb;
30 
31  sb = calloc(1, sizeof(*sb));
32 
33  return (sb);
34 }
35 
36 void
38  free((*sb)->data);
39  free(*sb);
40  *sb = NULL;
41 }
42 
44 nmsg_strbuf_append(struct nmsg_strbuf *sb, const char *fmt, ...) {
45  ssize_t avail, needed;
46  int status;
47  va_list args, args_copy;
48 
49  /* allocate a data buffer if necessary */
50  if (sb->data == NULL) {
51  sb->pos = sb->data = malloc(DEFAULT_STRBUF_ALLOC_SZ);
52  if (sb->data == NULL)
53  return (nmsg_res_memfail);
54  sb->bufsz = DEFAULT_STRBUF_ALLOC_SZ;
55  }
56 
57  /* determine how many bytes are needed */
58  va_start(args, fmt);
59  va_copy(args_copy, args);
60  needed = vsnprintf(NULL, 0, fmt, args_copy) + 1;
61  va_end(args_copy);
62  if (needed < 0) {
63  free(sb->data);
64  sb->pos = sb->data = NULL;
65  sb->bufsz = 0;
66  return (nmsg_res_failure);
67  }
68 
69  /* determine how many bytes of buffer space are available */
70  avail = sb->bufsz - (sb->pos - sb->data);
71  assert(avail >= 0);
72 
73  /* increase buffer size if necessary */
74  if (needed > avail) {
75  size_t offset;
76  ssize_t new_bufsz = 2 * sb->bufsz;
77  void *ptr = sb->data;
78 
79  offset = sb->pos - sb->data;
80 
81  while (new_bufsz - (ssize_t) sb->bufsz < needed)
82  new_bufsz *= 2;
83  assert(sb->bufsz > 0);
84  ptr = realloc(sb->data, new_bufsz);
85  if (ptr == NULL) {
86  free(sb->data);
87  sb->pos = sb->data = NULL;
88  sb->bufsz = 0;
89  return (nmsg_res_memfail);
90  }
91  sb->data = ptr;
92  sb->pos = sb->data + offset;
93  sb->bufsz = new_bufsz;
94  }
95 
96  /* print to the end of the strbuf */
97  status = vsnprintf(sb->pos, needed + 1, fmt, args);
98  if (status >= 0)
99  sb->pos += status;
100  else {
101  free(sb->data);
102  sb->pos = sb->data = NULL;
103  sb->bufsz = 0;
104  return (nmsg_res_failure);
105  }
106 
107  return (nmsg_res_success);
108 }
109 
110 size_t
112  assert(sb->pos >= sb->data);
113  assert(sb->pos - sb->data <= (ssize_t) sb->bufsz);
114  return (sb->pos - sb->data);
115 }
116 
117 nmsg_res
119  void *ptr = sb->data;
120 
121  ptr = realloc(sb->data, DEFAULT_STRBUF_ALLOC_SZ);
122  if (ptr == NULL) {
123  free(sb->data);
124  sb->pos = sb->data = NULL;
125  sb->bufsz = 0;
126  return (nmsg_res_memfail);
127  }
128  sb->pos = sb->data = ptr;
129  sb->bufsz = DEFAULT_STRBUF_ALLOC_SZ;
130 
131  return (nmsg_res_success);
132 }
size_t nmsg_strbuf_len(struct nmsg_strbuf *sb)
Find the length of the used portion of the string buffer.
Definition: strbuf.c:111
nmsg_res
nmsg result code
Definition: res.h:25
success
Definition: res.h:26
out of memory
Definition: res.h:29
char * pos
end of string
Definition: strbuf.h:33
size_t bufsz
size of data allocation
Definition: strbuf.h:35
struct nmsg_strbuf * nmsg_strbuf_init(void)
Initialize a string buffer.
Definition: strbuf.c:28
char * data
buffer for string data
Definition: strbuf.h:34
void nmsg_strbuf_destroy(struct nmsg_strbuf **sb)
Destroy all resources associated with a string buffer.
Definition: strbuf.c:37
generic failure
Definition: res.h:27
nmsg_res nmsg_strbuf_append(struct nmsg_strbuf *sb, const char *fmt,...)
Append to a string buffer.
Definition: strbuf.c:44
String buffer.
Definition: strbuf.h:32
nmsg_res nmsg_strbuf_reset(struct nmsg_strbuf *sb)
Reset a string buffer.
Definition: strbuf.c:118