ref: b65a821ba2d8c753e974b02e541229dfd6754a6a
parent: 7596ee5f651a67a62de4b009d8647f5b2cf729fb
author: Ori Bernstein <[email protected]>
date: Mon Apr 20 16:27:37 EDT 2015
Add support for fixed size str buffers.
--- a/libstd/strbuf.myr
+++ b/libstd/strbuf.myr
@@ -14,6 +14,7 @@
;;
const mksb : (-> strbuf#)
+ const mkbufsb : (buf : byte[:] -> strbuf#)
const sbfin : (sb : strbuf# -> byte[:])
const sbfree : (sb : strbuf# -> void)
const sbpeek : (sb : strbuf# -> byte[:])
@@ -21,24 +22,40 @@
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 : std.size -> void)
+ const sbtrim : (sb : strbuf#, len : size -> void)
;;
-const mksb = {
+const mksb = {
var sb
- sb = std.zalloc()
- sb.buf = std.slalloc(1)
+ sb = zalloc()
+ sb.buf = slalloc(1)
-> sb
}
-const sbfin = {sb : strbuf#
+const mkbufsb = {buf
+ var sb
+ sb = zalloc()
+ sb.buf = buf
+ sb.fixed = true
+ -> sb
+}
+
+const sbfin = {sb
var sl
sl = sb.buf[:sb.len]
- std.free(sb)
+ free(sb)
-> sl
}
+const sbfree = {sb
+ if !sb.fixed
+ slfree(sb.buf)
+ ;;
+ free(sb)
+}
+
+
const sbpeek = {sb : strbuf#
-> sb.buf[:sb.len]
}
@@ -51,12 +68,15 @@
-> true
}
const sbputs = {sb, v
- if !ensure(sb, v.len)
- -> false
- ;;
- std.slcp(sb.buf[sb.len:sb.len + v.len], v)
- sb.len += v.len
- -> true
+ 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)
@@ -67,9 +87,9 @@
}
const sbtrim = {sb, len
- std.assert(std.abs(len) <= sb.len, "trim out of range\n")
+ assert(abs(len) <= sb.len, "trim out of range\n")
if len < 0
- sb.len -= std.abs(len)
+ sb.len -= abs(len)
else
sb.len = len
;;
@@ -76,7 +96,7 @@
}
const ensure = {sb, len
- if sb.fixed && sb.len + len >= sb.buf.len
+ if sb.fixed && sb.len + len > sb.buf.len
-> false
;;
while sb.buf.len < sb.len + len
--- a/libstd/test/strbuf.myr
+++ b/libstd/test/strbuf.myr
@@ -2,6 +2,7 @@
const main = {
var sb
+ var buf : byte[16]
sb = std.mksb()
std.assert(std.sleq(std.sbpeek(sb), ""), "mismatched empty str\n")
@@ -20,5 +21,20 @@
std.assert(std.sleq(std.sbpeek(sb), "hello, 世界"), "mismatched unicode\n")
std.sbputb(sb, 10)
std.assert(std.sleq(std.sbpeek(sb), "hello, 世界\n"), "mismatched byte\n")
+
+ sb = std.mkbufsb(buf[:])
+ std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 5 characters */
+ std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 10 characters */
+ std.assert(std.sbputs(sb, "hello"), "failed to add hello\n") /* 15 characters */
+ std.assert(!std.sbputs(sb, "hello"), "erronous success\n") /* 16 characters */
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohelloh"), "failed to copy as much as possible\n")
+ std.sbtrim(sb, -1)
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "failed rtrim\n")
+ std.sbputc(sb, '世')
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohello"), "modified overflowed putc\n")
+ std.sbtrim(sb, -2)
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohel"), "failed rtrim\n")
+ std.sbputc(sb, '世')
+ std.assert(std.sleq(std.sbpeek(sb), "hellohellohel世"), "failed to append with putc\n")
}