1 /*
2  * Copyright (c) 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 #ifndef MY_UBUF_H
18 #define MY_UBUF_H
19 
20 #include <stdarg.h>
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "vector.h"
28 
VECTOR_GENERATE(ubuf,uint8_t)29 VECTOR_GENERATE(ubuf, uint8_t)
30 
31 static inline ubuf *
32 ubuf_new(void)
33 {
34 	return (ubuf_init(64));
35 }
36 
37 static inline ubuf *
ubuf_dup_cstr(const char * s)38 ubuf_dup_cstr(const char *s)
39 {
40 	size_t len = strlen(s);
41 	ubuf *u = ubuf_init(len + 1);
42 	ubuf_append(u, (const uint8_t *) s, len);
43 	return (u);
44 }
45 
46 static inline void
ubuf_add_cstr(ubuf * u,const char * s)47 ubuf_add_cstr(ubuf *u, const char *s)
48 {
49 	if (ubuf_size(u) > 0 && ubuf_value(u, ubuf_size(u) - 1) == '\x00')
50 		ubuf_clip(u, ubuf_size(u) - 1);
51 	ubuf_append(u, (const uint8_t *) s, strlen(s));
52 }
53 
54 static inline void
ubuf_cterm(ubuf * u)55 ubuf_cterm(ubuf *u)
56 {
57 	if (ubuf_size(u) == 0 ||
58 	    (ubuf_size(u) > 0 && ubuf_value(u, ubuf_size(u) - 1) != '\x00'))
59 	{
60 		ubuf_append(u, (const uint8_t *) "\x00", 1);
61 	}
62 }
63 
64 static inline char *
ubuf_cstr(ubuf * u)65 ubuf_cstr(ubuf *u)
66 {
67 	ubuf_cterm(u);
68 	return ((char *) ubuf_data(u));
69 }
70 
71 static inline void
ubuf_add_fmt(ubuf * u,const char * fmt,...)72 ubuf_add_fmt(ubuf *u, const char *fmt, ...)
73 {
74 	va_list args, args_copy;
75 	int status, needed;
76 
77 	if (ubuf_size(u) > 0 && ubuf_value(u, ubuf_size(u) - 1) == '\x00')
78 		ubuf_clip(u, ubuf_size(u) - 1);
79 
80 	va_start(args, fmt);
81 
82 	va_copy(args_copy, args);
83 	needed = vsnprintf(NULL, 0, fmt, args_copy);
84 	assert(needed >= 0);
85 	va_end(args_copy);
86 
87 	ubuf_reserve(u, ubuf_size(u) + needed + 1);
88 	status = vsnprintf((char *) ubuf_ptr(u), needed + 1, fmt, args);
89 	assert(status >= 0);
90 	ubuf_advance(u, needed);
91 
92 	va_end(args);
93 }
94 
95 static inline void
ubuf_rstrip(ubuf * u,char s)96 ubuf_rstrip(ubuf *u, char s)
97 {
98 	if (ubuf_size(u) > 0 &&
99 	    ubuf_value(u, ubuf_size(u) - 1) == ((uint8_t) s))
100 	{
101 		ubuf_clip(u, ubuf_size(u) - 1);
102 	}
103 }
104 
105 #endif /* MY_UBUF_H */
106