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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
use "alloc"
use "die"
use "extremum"
use "slcp"
use "types"
use "utf"
use "memops"
pkg std =
type strbuf = struct
buf : byte[:]
len : size
fixed : bool
;;
const mksb : (-> strbuf#)
const mkbufsb : (buf : byte[:] -> strbuf#)
const sbfin : (sb : strbuf# -> byte[:])
const sbfree : (sb : strbuf# -> void)
const sbpeek : (sb : strbuf# -> byte[:])
const sbputc : (sb : strbuf#, v : char -> bool)
const sbputs : (sb : strbuf#, v : byte[:] -> bool)
const sbputb : (sb : strbuf#, v : byte -> bool)
const sbtrim : (sb : strbuf#, len : size -> void)
;;
const mksb = {
var sb
sb = zalloc()
sb.buf = slalloc(1)
-> sb
}
const mkbufsb = {buf
var sb
sb = zalloc()
sb.buf = buf
sb.fixed = true
-> sb
}
const sbfin = {sb
var sl
sl = sb.buf[:sb.len]
free(sb)
-> sl
}
const sbfree = {sb
if !sb.fixed
slfree(sb.buf)
;;
free(sb)
}
const sbpeek = {sb : strbuf#
-> sb.buf[:sb.len]
}
const sbputc = {sb, v
if !ensure(sb, charlen(v))
-> false
;;
sb.len += encode(sb.buf[sb.len:], v)
-> true
}
const sbputs = {sb, v
var ok
var len
ok = ensure(sb, v.len)
/* copy what we can */
len = min(sb.buf.len - sb.len, v.len)
slcp(sb.buf[sb.len:sb.len + len], v[:len])
sb.len += len
-> ok
}
const sbputb = {sb, v
if !ensure(sb, 1)
-> false
;;
sb.buf[sb.len++] = v
-> true
}
const sbtrim = {sb, len
len = min(sb.len, len)
if len < 0
sb.len -= abs(len)
else
sb.len = len
;;
}
const ensure = {sb, len
if sb.fixed && sb.len + len > sb.buf.len
-> false
;;
while sb.buf.len < sb.len + len
slgrow(&sb.buf, 2*sb.buf.len)
;;
-> true
}
|