commit 316a40ee12d8b90ae1f676bbf195de32cb6f2fc1
parent 7dfb0145d6bc57177b0267a2e07d4a84e38eb659
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 25 Mar 2021 11:28:54 -0400
encoding::hex: support encoding to stream
Diffstat:
6 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/cmd/hare/schedule.ha b/cmd/hare/schedule.ha
@@ -156,7 +156,7 @@ fn sched_hare_object(
let current = false;
let output = if (len(namespace) != 0) {
- let version = hex::encode(ver.hash);
+ let version = hex::encodestr(ver.hash);
let ns = unparse::identstr(namespace);
let env = module::identuscore(namespace);
defer free(env);
diff --git a/encoding/hex/hex.ha b/encoding/hex/hex.ha
@@ -7,23 +7,30 @@ use strio;
// Error returned when attempting to decode an invalid hex string.
export type invalid = void!;
-// Encodes a byte slice to hex and writes it to a string. The caller must free
-// this string.
-export fn encode(b: []u8) str = {
- let buf = strio::dynamic();
+// Encodes a byte slice as a hexadecimal string and writes it to a stream.
+export fn encode(sink: *io::stream, b: []u8) (size | io::error) = {
+ let z = 0z;
for (let i = 0z; i < len(b); i += 1) {
let s = strconv::u8tosb(b[i], strconv::base::HEX_LOWER);
if (len(s) == 1) {
- io::write(buf, ['0': u32: u8]);
+ z += io::write(sink, ['0': u32: u8])?;
};
- io::write(buf, strings::toutf8(s)) as size;
+ z += io::write(sink, strings::toutf8(s))?;
};
- return strio::finish(buf);
+ return z;
+};
+
+// Encodes a byte slice as a hexadecimal string and returns it. The caller must
+// free the return value.
+export fn encodestr(b: []u8) str = {
+ let sink = strio::dynamic();
+ encode(sink, b) as size;
+ return strio::finish(sink);
};
@test fn encode() void = {
let in: [_]u8 = [0xCA, 0xFE, 0xBA, 0xBE, 0xDE, 0xAD, 0xF0, 0x0D];
- let s = encode(in);
+ let s = encodestr(in);
defer free(s);
assert(s == "cafebabedeadf00d");
};
diff --git a/hare/module/manifest.ha b/hare/module/manifest.ha
@@ -231,7 +231,7 @@ export fn manifest_write(ctx: *context, manifest: *manifest) (void | error) = {
fmt::fprintfln(fd, "version {}", VERSION)?;
for (let i = 0z; i < len(manifest.inputs); i += 1) {
const input = manifest.inputs[i];
- let hash = hex::encode(input.hash);
+ let hash = hex::encodestr(input.hash);
defer free(hash);
const want = fs::stat_mask::INODE | fs::stat_mask::MTIME;
@@ -243,13 +243,13 @@ export fn manifest_write(ctx: *context, manifest: *manifest) (void | error) = {
for (let i = 0z; i < len(manifest.versions); i += 1) {
const ver = manifest.versions[i];
- let hash = hex::encode(ver.hash);
+ let hash = hex::encodestr(ver.hash);
defer free(hash);
fmt::fprintf(fd, "module {}", hash);
for (let j = 0z; j < len(ver.inputs); j += 1) {
- let hash = hex::encode(ver.inputs[i].hash);
+ let hash = hex::encodestr(ver.inputs[i].hash);
defer free(hash);
fmt::fprintf(fd, " {}", hash);
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -295,7 +295,7 @@ hare_module() {
gen_ssa hare::module \
hare::ast hare::lex hare::parse hare::unparse strio fs io strings hash \
crypto::sha256 dirs bytes encoding::utf8 ascii fmt time slice bufio \
- strconv os
+ strconv os encoding::hex
}
gensrcs_hare_parse() {
@@ -512,7 +512,7 @@ temp() {
printf '# temp\n'
gen_srcs temp \
'$(PLATFORM).ha'
- gen_ssa temp crypto::random encoding::hex fs io os path
+ gen_ssa temp crypto::random encoding::hex fs io os path strio
}
types() {
diff --git a/stdlib.mk b/stdlib.mk
@@ -383,7 +383,7 @@ stdlib_hare_module_srcs= \
$(STDLIB)/hare/module/scan.ha \
$(STDLIB)/hare/module/manifest.ha
-$(HARECACHE)/hare/module/hare_module.ssa: $(stdlib_hare_module_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_lex) $(stdlib_hare_parse) $(stdlib_hare_unparse) $(stdlib_strio) $(stdlib_fs) $(stdlib_io) $(stdlib_strings) $(stdlib_hash) $(stdlib_crypto_sha256) $(stdlib_dirs) $(stdlib_bytes) $(stdlib_encoding_utf8) $(stdlib_ascii) $(stdlib_fmt) $(stdlib_time) $(stdlib_slice) $(stdlib_bufio) $(stdlib_strconv) $(stdlib_os)
+$(HARECACHE)/hare/module/hare_module.ssa: $(stdlib_hare_module_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_lex) $(stdlib_hare_parse) $(stdlib_hare_unparse) $(stdlib_strio) $(stdlib_fs) $(stdlib_io) $(stdlib_strings) $(stdlib_hash) $(stdlib_crypto_sha256) $(stdlib_dirs) $(stdlib_bytes) $(stdlib_encoding_utf8) $(stdlib_ascii) $(stdlib_fmt) $(stdlib_time) $(stdlib_slice) $(stdlib_bufio) $(stdlib_strconv) $(stdlib_os) $(stdlib_encoding_hex)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/hare/module
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::module \
@@ -606,7 +606,7 @@ $(HARECACHE)/strio/strio.ssa: $(stdlib_strio_srcs) $(stdlib_rt) $(stdlib_io) $(s
stdlib_temp_srcs= \
$(STDLIB)/temp/$(PLATFORM).ha
-$(HARECACHE)/temp/temp.ssa: $(stdlib_temp_srcs) $(stdlib_rt) $(stdlib_crypto_random) $(stdlib_encoding_hex) $(stdlib_fs) $(stdlib_io) $(stdlib_os) $(stdlib_path)
+$(HARECACHE)/temp/temp.ssa: $(stdlib_temp_srcs) $(stdlib_rt) $(stdlib_crypto_random) $(stdlib_encoding_hex) $(stdlib_fs) $(stdlib_io) $(stdlib_os) $(stdlib_path) $(stdlib_strio)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/temp
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntemp \
@@ -1035,7 +1035,7 @@ testlib_hare_module_srcs= \
$(STDLIB)/hare/module/scan.ha \
$(STDLIB)/hare/module/manifest.ha
-$(TESTCACHE)/hare/module/hare_module.ssa: $(testlib_hare_module_srcs) $(testlib_rt) $(testlib_hare_ast) $(testlib_hare_lex) $(testlib_hare_parse) $(testlib_hare_unparse) $(testlib_strio) $(testlib_fs) $(testlib_io) $(testlib_strings) $(testlib_hash) $(testlib_crypto_sha256) $(testlib_dirs) $(testlib_bytes) $(testlib_encoding_utf8) $(testlib_ascii) $(testlib_fmt) $(testlib_time) $(testlib_slice) $(testlib_bufio) $(testlib_strconv) $(testlib_os)
+$(TESTCACHE)/hare/module/hare_module.ssa: $(testlib_hare_module_srcs) $(testlib_rt) $(testlib_hare_ast) $(testlib_hare_lex) $(testlib_hare_parse) $(testlib_hare_unparse) $(testlib_strio) $(testlib_fs) $(testlib_io) $(testlib_strings) $(testlib_hash) $(testlib_crypto_sha256) $(testlib_dirs) $(testlib_bytes) $(testlib_encoding_utf8) $(testlib_ascii) $(testlib_fmt) $(testlib_time) $(testlib_slice) $(testlib_bufio) $(testlib_strconv) $(testlib_os) $(testlib_encoding_hex)
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/hare/module
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::module \
@@ -1265,7 +1265,7 @@ $(TESTCACHE)/strio/strio.ssa: $(testlib_strio_srcs) $(testlib_rt) $(testlib_io)
testlib_temp_srcs= \
$(STDLIB)/temp/$(PLATFORM).ha
-$(TESTCACHE)/temp/temp.ssa: $(testlib_temp_srcs) $(testlib_rt) $(testlib_crypto_random) $(testlib_encoding_hex) $(testlib_fs) $(testlib_io) $(testlib_os) $(testlib_path)
+$(TESTCACHE)/temp/temp.ssa: $(testlib_temp_srcs) $(testlib_rt) $(testlib_crypto_random) $(testlib_encoding_hex) $(testlib_fs) $(testlib_io) $(testlib_os) $(testlib_path) $(testlib_strio)
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/temp
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntemp \
diff --git a/temp/+linux.ha b/temp/+linux.ha
@@ -4,6 +4,7 @@ use fs;
use io;
use os;
use path;
+use strio;
fn get_tmpdir() str = os::tryenv("TMPDIR", "/tmp");
@@ -55,10 +56,14 @@ export fn named(
//
// The caller must free the return value.
export fn dir() str = {
- let buf: [8]u8 = [0...];
+ let buf: [8]u8 = [0...], name: [16]u8 = [0...];
random::buffer(buf[..]);
- let name = hex::encode(buf);
- defer free(name);
+
+ let sink = strio::fixed(name);
+ defer io::close(sink);
+ hex::encode(sink, buf) as size;
+ let name = strio::string(sink);
+
let path = path::join(get_tmpdir(), name);
match (os::mkdir(path)) {
err: fs::error => abort("Could not create temp directory"),