File Coverage

hoedown/src/buffer.c
Criterion Covered Total %
statement 59 79 74.6
branch 37 78 47.4
condition n/a
subroutine n/a
pod n/a
total 96 157 61.1


line stmt bran cond sub pod time code
1             #include "buffer.h"
2              
3             #include <stdio.h>
4             #include <stdlib.h>
5             #include <string.h>
6             #include <assert.h>
7              
8             #define BUFFER_MAX_ALLOC_SIZE (1024 * 1024 * 16) /* 16mb */
9              
10             /* hoedown_buffer_new: allocation of a new buffer */
11             hoedown_buffer *
12 29           hoedown_buffer_new(size_t unit)
13             {
14             hoedown_buffer *ret;
15 29           ret = malloc(sizeof (hoedown_buffer));
16              
17 29 50         if (ret) {
18 29           ret->data = 0;
19 29           ret->size = ret->asize = 0;
20 29           ret->unit = unit;
21             }
22 29           return ret;
23             }
24              
25             /* hoedown_buffer_free: decrease the reference count and free the buffer if needed */
26             void
27 18           hoedown_buffer_free(hoedown_buffer *buf)
28             {
29 18 50         if (!buf)
30 18           return;
31            
32 18           free(buf->data);
33 18           free(buf);
34             }
35            
36             /* hoedown_buffer_reset: frees internal data of the buffer */
37             void
38 0           hoedown_buffer_reset(hoedown_buffer *buf)
39             {
40 0 0         if (!buf)
41 0           return;
42            
43 0           free(buf->data);
44 0           buf->data = NULL;
45 0           buf->size = buf->asize = 0;
46             }
47            
48             /* hoedown_buffer_grow: increasing the allocated size to the given value */
49             int
50 73           hoedown_buffer_grow(hoedown_buffer *buf, size_t neosz)
51             {
52             size_t neoasz;
53             void *neodata;
54            
55 73 50         assert(buf && buf->unit);
    50          
56            
57 73 50         if (neosz > BUFFER_MAX_ALLOC_SIZE)
58             return HOEDOWN_BUF_ENOMEM;
59            
60 73 100         if (buf->asize >= neosz)
61             return HOEDOWN_BUF_OK;
62            
63 35           neoasz = buf->asize + buf->unit;
64 50 100         while (neoasz < neosz)
65 15           neoasz += buf->unit;
66            
67 35           neodata = realloc(buf->data, neoasz);
68 35 50         if (!neodata)
69             return HOEDOWN_BUF_ENOMEM;
70            
71 35           buf->data = neodata;
72 35           buf->asize = neoasz;
73 35           return HOEDOWN_BUF_OK;
74             }
75            
76             /* hoedown_buffer_put: appends raw data to a buffer */
77             void
78 153           hoedown_buffer_put(hoedown_buffer *buf, const void *data, size_t len)
79             {
80 153 50         assert(buf && buf->unit);
    50          
81            
82 153 100         if (buf->size + len > buf->asize && hoedown_buffer_grow(buf, buf->size + len) < 0)
    50          
83 153           return;
84            
85 153           memcpy(buf->data + buf->size, data, len);
86 153           buf->size += len;
87             }
88            
89             /* hoedown_buffer_puts: appends a NUL-terminated string to a buffer */
90             void
91 0           hoedown_buffer_puts(hoedown_buffer *buf, const char *str)
92             {
93 0           hoedown_buffer_put(buf, str, strlen(str));
94 0           }
95            
96            
97             /* hoedown_buffer_putc: appends a single uint8_t to a buffer */
98             void
99 42           hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c)
100             {
101 42 50         assert(buf && buf->unit);
    50          
102            
103 42 50         if (buf->size + 1 > buf->asize && hoedown_buffer_grow(buf, buf->size + 1) < 0)
    0          
104 42           return;
105            
106 42           buf->data[buf->size] = c;
107 42           buf->size += 1;
108             }
109            
110             int
111 1           hoedown_buffer_prefix(const hoedown_buffer *buf, const char *prefix)
112             {
113             size_t i;
114 1 50         assert(buf && buf->unit);
    50          
115            
116 1 50         for (i = 0; i < buf->size; ++i) {
117 1 50         if (prefix[i] == 0)
118             return 0;
119            
120 1 50         if (buf->data[i] != prefix[i])
121 1           return buf->data[i] - prefix[i];
122             }
123            
124             return 0;
125             }
126            
127             /* hoedown_buffer_slurp: removes a given number of bytes from the head of the array */
128             void
129 0           hoedown_buffer_slurp(hoedown_buffer *buf, size_t len)
130             {
131 0 0         assert(buf && buf->unit);
    0          
132            
133 0 0         if (len >= buf->size) {
134 0           buf->size = 0;
135 0           return;
136             }
137            
138 0           buf->size -= len;
139 0           memmove(buf->data, buf->data + len, buf->size);
140             }
141            
142             /* hoedown_buffer_cstr: NULL-termination of the string array */
143             const char *
144 6           hoedown_buffer_cstr(hoedown_buffer *buf)
145             {
146 6 50         assert(buf && buf->unit);
    50          
147            
148 6 50         if (buf->size < buf->asize && buf->data[buf->size] == 0)
    50          
149             return (char *)buf->data;
150            
151 0 0         if (buf->size + 1 <= buf->asize || hoedown_buffer_grow(buf, buf->size + 1) == 0) {
    0          
152 0           buf->data[buf->size] = 0;
153 0           return (char *)buf->data;
154             }
155            
156             return NULL;
157             }
158            
159             /* hoedown_buffer_printf: formatted printing to a buffer */
160             void
161 25           hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...)
162             {
163             va_list ap;
164             int n;
165            
166 25 50         assert(buf && buf->unit);
    50          
167            
168 25 100         if (buf->size >= buf->asize && hoedown_buffer_grow(buf, buf->size + 1) < 0)
    50          
169 0           return;
170            
171 25           va_start(ap, fmt);
172 25           n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
173 25           va_end(ap);
174            
175 25 50         if (n < 0) {
176             #ifndef _MSC_VER
177             return;
178             #else
179             va_start(ap, fmt);
180             n = _vscprintf(fmt, ap);
181             va_end(ap);
182             #endif
183             }
184            
185 25 100         if ((size_t)n >= buf->asize - buf->size) {
186 1 50         if (hoedown_buffer_grow(buf, buf->size + n + 1) < 0)
187             return;
188            
189 1           va_start(ap, fmt);
190 1           n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
191 1           va_end(ap);
192             }
193            
194 25 50         if (n < 0)
195             return;
196            
197 25           buf->size += n;
198             }
199