-
Notifications
You must be signed in to change notification settings - Fork 9
/
strbuf.c
68 lines (59 loc) · 1.89 KB
/
strbuf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <string.h> // memcpy
#include <stdio.h>
#include <stdarg.h>
#include "strbuf.h"
void strbuf_init(StrBuf *strbuf, Context *context) {
strbuf->context = context;
strbuf->contents = 0;
}
void strbuf_clear(StrBuf *strbuf) {
array_clear(strbuf->contents);
}
Bool strbuf_put_byte(StrBuf *strbuf, Uint8 byte) {
Context *context = strbuf->context;
return array_push(strbuf->contents, byte);
}
Bool strbuf_put_rune(StrBuf *strbuf, Rune ch) {
return strbuf_put_byte(strbuf, ch);
// Decode UTF-8 Rune into individual code-points.
const Uint8 b0 = ch & 0xff;
const Uint8 b1 = (ch >> 8) & 0xff;
const Uint8 b2 = (ch >> 16) & 0xff;
const Uint8 b3 = (ch >> 24) & 0xff;
Bool ok = true;
if ((b0 & 0xC0) != 0x80) ok = ok && strbuf_put_byte(strbuf, b0);
if ((b1 & 0xC0) != 0x80) ok = ok && strbuf_put_byte(strbuf, b1);
if ((b2 & 0xC0) != 0x80) ok = ok && strbuf_put_byte(strbuf, b2);
if ((b3 & 0xC0) != 0x80) ok = ok && strbuf_put_byte(strbuf, b3);
return ok;
}
Bool strbuf_put_string(StrBuf *strbuf, String string) {
Context *context = strbuf->context;
const Uint64 size = array_size(strbuf->contents);
if (array_expand(strbuf->contents, string.length)) {
memcpy(&strbuf->contents[size], string.contents, string.length);
return true;
}
return false;
}
Bool strbuf_put_formatted(StrBuf *strbuf, const char *fmt, ...) {
Context *context = strbuf->context;
va_list va;
va_start(va, fmt);
const long bytes = vsnprintf(0, 0, fmt, va);
va_end(va);
const Uint64 size = array_size(strbuf->contents);
if (array_expand(strbuf->contents, bytes + 1)) {
va_list ap;
va_start(ap, fmt);
vsnprintf(RCAST(char *, &strbuf->contents[size]), bytes + 1, fmt, ap);
array_meta(strbuf->contents)->size--; // Remove NUL from vsnprintf.
va_end(ap);
return true;
}
return false;
}
String strbuf_result(StrBuf *strbuf) {
Array(Uint8) contents = strbuf->contents;
return LIT(String, contents, array_size(contents));
}