cloud_pubsub plugin: New plugin publishing to or subscribing from Google Cloud Pub...
[collectd.git] / src / utils_strbuf.c
1 /**
2  * collectd - src/utils_strbuf.c
3  * Copyright (C) 2018  Florian Forster
4  *
5  * MIT License
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * Authors:
26  *   Florian Forster <octo at collectd.org>
27  **/
28
29 #include "utils_strbuf.h"
30 #include "collectd.h"
31
32 #include <stdarg.h>
33
34 strbuf_t *strbuf_create(size_t sz) /* {{{ */
35 {
36   strbuf_t *buf;
37
38   buf = malloc(sizeof(*buf));
39   if (buf == NULL)
40     return NULL;
41   memset(buf, 0, sizeof(*buf));
42
43   buf->buffer = malloc(sz);
44   if (buf->buffer == NULL) {
45     free(buf);
46     return NULL;
47   }
48   memset(buf->buffer, 0, sz);
49
50   buf->free = sz;
51   buf->used = 0;
52
53   return buf;
54 } /* }}} int strbuf_t *strbuf_create */
55
56 void strbuf_destroy(strbuf_t *buf) /* {{{ */
57 {
58   if (buf == NULL)
59     return;
60
61   free(buf->buffer);
62   free(buf);
63 } /* }}} void strbuf_destroy */
64
65 void strbuf_reset(strbuf_t *buf) /* {{{ */
66 {
67   buf->free += buf->used;
68   buf->used = 0;
69   buf->buffer[0] = 0;
70 } /* }}} void strbuf_reset */
71
72 int strbuf_add(strbuf_t *buf, char const *str) /* {{{ */
73 {
74   char *base = buf->buffer + buf->used;
75   size_t len = strlen(str);
76
77   if (len >= buf->free)
78     return ENOMEM;
79
80   /* len+1 so copied memory includes the trailing nil. */
81   memcpy(base, str, len + 1);
82   buf->free -= len;
83   buf->used += len;
84
85   assert(buf->buffer[buf->used] == 0);
86
87   return 0;
88 } /* }}} int strbuf_add */
89
90 __attribute__((format(printf, 2, 3))) int
91 strbuf_addf(strbuf_t *buf, char const *format, ...) /* {{{ */
92 {
93   va_list ap;
94   char *base = buf->buffer + buf->used;
95   int status;
96   size_t len;
97
98   va_start(ap, format);
99   status = vsnprintf(base, buf->free, format, ap);
100   va_end(ap);
101
102   if (status < 0)
103     return status;
104
105   len = (size_t)status;
106   if (len >= buf->free) /* truncated */
107   {
108     base[0] = 0; /* make sure buffer appears unmodified. */
109     return ENOMEM;
110   }
111
112   buf->free -= len;
113   buf->used += len;
114
115   assert(buf->buffer[buf->used] == 0);
116
117   return 0;
118 } /* }}} int strbuf_addf */
119
120 /* vim: set sw=2 sts=2 et fdm=marker : */