mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Add dstringwriter.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
14
lib/std/io/stream/dstringwriter.c3
Normal file
14
lib/std/io/stream/dstringwriter.c3
Normal 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),
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
17
test/unit/stdlib/io/dstringstream.c3
Normal file
17
test/unit/stdlib/io/dstringstream.c3
Normal 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");
|
||||
}
|
||||
Reference in New Issue
Block a user