From 316af36723a70fab8dbb8ab55408be1fef59a331 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Wed, 22 Mar 2023 12:23:47 +0100 Subject: [PATCH] Add dstringwriter. --- lib/std/core/dstring.c3 | 31 +++++++++++++++++++++++++++- lib/std/io/stream/dstringwriter.c3 | 14 +++++++++++++ src/compiler/sema_expr.c | 8 +++---- test/unit/stdlib/io/dstringstream.c3 | 17 +++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 lib/std/io/stream/dstringwriter.c3 create mode 100644 test/unit/stdlib/io/dstringstream.c3 diff --git a/lib/std/core/dstring.c3 b/lib/std/core/dstring.c3 index 805d9c0ea..a49d759b3 100644 --- a/lib/std/core/dstring.c3 +++ b/lib/std/core/dstring.c3 @@ -360,7 +360,7 @@ fn StringData* DString.data(DString str) @inline @private return (StringData*)str; } -fn void DString.reserve(DString* str, usz addition) @private +fn void DString.reserve(DString* str, usz addition) { StringData* data = str.data(); if (!data) @@ -375,6 +375,35 @@ fn void DString.reserve(DString* str, usz addition) @private *str = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator); } +fn usz! DString.read_from_stream(DString* string, Stream* reader) +{ + if (reader.supports_available()) + { + usz total_read = 0; + while (usz available = reader.available()?) + { + string.reserve(available); + StringData* data = string.data(); + usz len = reader.read(data.chars[data.len..(data.capacity - 1)])?; + total_read += len; + data.len += len; + } + return total_read; + } + usz total_read = 0; + while (true) + { + // Reserve at least 16 bytes + string.reserve(16); + StringData* data = string.data(); + // Read into the rest of the buffer + usz read = reader.read(data.chars[data.len..(data.capacity - 1)])?; + data.len += read; + // Ok, we reached the end. + if (read < 16) return total_read; + // Otherwise go another round + } +} struct StringData @private { diff --git a/lib/std/io/stream/dstringwriter.c3 b/lib/std/io/stream/dstringwriter.c3 new file mode 100644 index 000000000..85006aec0 --- /dev/null +++ b/lib/std/io/stream/dstringwriter.c3 @@ -0,0 +1,14 @@ +module std::io; + +fn Stream DString.as_stream(DString* dstring) +{ + return { .fns = &dstring_interface, .data = dstring }; +} + +StreamInterface dstring_interface = { + .destroy_fn = fn (s) => ((DString*)s.data).free(), + .len_fn = fn (s) => ((DString*)s.data).len(), + .write_fn = fn (s, char[] bytes) { ((DString*)s.data).append_chars((String)bytes); return bytes.len; }, + .write_byte_fn = fn (s, char c) => ((DString*)s.data).append_char(c), + .read_stream_fn = fn (s, reader) => ((DString*)s.data).read_from_stream(reader), +}; \ No newline at end of file diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 73e3b975a..8c52e6907 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2607,21 +2607,21 @@ static inline bool sema_expr_analyse_slice(SemaContext *context, Expr *expr) bool end_from_end = expr->subscript_expr.range.end_from_end; // Check range - if (type->type_kind == TYPE_POINTER) + if (type->type_kind == TYPE_POINTER || type->type_kind == TYPE_FLEXIBLE_ARRAY) { if (start_from_end) { - SEMA_ERROR(start, "Indexing from the end is not allowed for pointers."); + SEMA_ERROR(start, "Indexing from the end is not allowed for pointers or flexible array members."); return false; } if (!end) { - SEMA_ERROR(expr, "Omitting end index is not allowed for pointers."); + SEMA_ERROR(expr, "Omitting end index is not allowed for pointers or flexible array members."); return false; } if (end && end_from_end) { - SEMA_ERROR(end, "Indexing from the end is not allowed for pointers."); + SEMA_ERROR(end, "Indexing from the end is not allowed for pointers or flexible array members."); return false; } } diff --git a/test/unit/stdlib/io/dstringstream.c3 b/test/unit/stdlib/io/dstringstream.c3 new file mode 100644 index 000000000..d6640c6f8 --- /dev/null +++ b/test/unit/stdlib/io/dstringstream.c3 @@ -0,0 +1,17 @@ +module std::io @test; + +fn void! test_writing() +{ + DString foo; + foo.init(); + Stream s = foo.as_stream(); + s.write("hello")!!; + s.write_byte('-')!!; + s.write("what?")!!; + ByteReader r; + String test_str = "2134"; + r.init(test_str); + s.read_from(&&r.as_stream())?; + String o = foo.str(); + assert(o == "hello-what?2134"); +}