2 * Functions to work with strbufs.
7 #include "utils/utils.h"
11 struct strbuf visible
;
12 bool nm
; /* true if we insist on non-moving buffer resizes */
15 #define STRBUF_SET_UPTR(buf) \
16 ((buf)->visible.u = (unsigned char *)(buf)->visible.s)
17 #define STRBUF_SET_PTR(buf, ptr) \
18 ((buf)->visible.s = (ptr), STRBUF_SET_UPTR(buf))
20 void *strbuf_append(strbuf
*buf_o
, size_t len
)
22 struct strbuf_impl
*buf
= container_of(buf_o
, struct strbuf_impl
, visible
);
25 buf
->visible
.s
, buf
->size
, buf
->visible
.len
+ 1, len
, buf
->nm
);
27 toret
= buf
->visible
.s
+ buf
->visible
.len
;
28 buf
->visible
.len
+= len
;
29 buf
->visible
.s
[buf
->visible
.len
] = '\0';
33 void strbuf_shrink_to(strbuf
*buf
, size_t new_len
)
35 assert(new_len
<= buf
->len
);
37 buf
->s
[buf
->len
] = '\0';
40 void strbuf_shrink_by(strbuf
*buf
, size_t amount_to_remove
)
42 assert(amount_to_remove
<= buf
->len
);
43 buf
->len
-= amount_to_remove
;
44 buf
->s
[buf
->len
] = '\0';
47 bool strbuf_chomp(strbuf
*buf
, char char_to_remove
)
49 if (buf
->len
> 0 && buf
->s
[buf
->len
-1] == char_to_remove
) {
50 strbuf_shrink_by(buf
, 1);
56 static void strbuf_BinarySink_write(
57 BinarySink
*bs
, const void *data
, size_t len
)
59 strbuf
*buf_o
= BinarySink_DOWNCAST(bs
, strbuf
);
60 memcpy(strbuf_append(buf_o
, len
), data
, len
);
63 static void strbuf_BinarySink_writefmtv(
64 BinarySink
*bs
, const char *fmt
, va_list ap
)
66 strbuf
*buf_o
= BinarySink_DOWNCAST(bs
, strbuf
);
67 struct strbuf_impl
*buf
= container_of(buf_o
, struct strbuf_impl
, visible
);
68 STRBUF_SET_PTR(buf
, dupvprintf_inner(buf
->visible
.s
, buf
->visible
.len
,
69 &buf
->size
, fmt
, ap
));
70 buf
->visible
.len
+= strlen(buf
->visible
.s
+ buf
->visible
.len
);
73 static strbuf
*strbuf_new_general(bool nm
)
75 struct strbuf_impl
*buf
= snew(struct strbuf_impl
);
76 BinarySink_INIT(&buf
->visible
, strbuf_BinarySink_write
);
77 buf
->visible
.binarysink_
->writefmtv
= strbuf_BinarySink_writefmtv
;
81 STRBUF_SET_PTR(buf
, snewn(buf
->size
, char));
82 *buf
->visible
.s
= '\0';
85 strbuf
*strbuf_new(void) { return strbuf_new_general(false); }
86 strbuf
*strbuf_new_nm(void) { return strbuf_new_general(true); }
87 void strbuf_free(strbuf
*buf_o
)
89 struct strbuf_impl
*buf
= container_of(buf_o
, struct strbuf_impl
, visible
);
91 smemclr(buf
->visible
.s
, buf
->size
);
92 sfree(buf
->visible
.s
);
96 char *strbuf_to_str(strbuf
*buf_o
)
98 struct strbuf_impl
*buf
= container_of(buf_o
, struct strbuf_impl
, visible
);
99 char *ret
= buf
->visible
.s
;
103 strbuf
*strbuf_new_for_agent_query(void)
105 strbuf
*buf
= strbuf_new();
106 strbuf_append(buf
, 4);
109 void strbuf_finalise_agent_query(strbuf
*buf_o
)
111 struct strbuf_impl
*buf
= container_of(buf_o
, struct strbuf_impl
, visible
);
112 assert(buf
->visible
.len
>= 5);
113 PUT_32BIT_MSB_FIRST(buf
->visible
.u
, buf
->visible
.len
- 4);
116 strbuf
*strbuf_dup(ptrlen string
)
118 strbuf
*buf
= strbuf_new();
119 put_datapl(buf
, string
);
123 strbuf
*strbuf_dup_nm(ptrlen string
)
125 strbuf
*buf
= strbuf_new_nm();
126 put_datapl(buf
, string
);