Add dstringwriter.

This commit is contained in:
Christoffer Lerno
2023-03-22 12:23:47 +01:00
parent 9850adfa56
commit 316af36723
4 changed files with 65 additions and 5 deletions

View File

@@ -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
{

View File

@@ -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),
};

View File

@@ -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;
}
}

View File

@@ -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");
}