fix Object.free (#982)

* lib/std/collections: add HashMap.@each_entry()
* lib/std/json: fix Object.free() when object is a map
* lib/std/collections: fix allocator use in Object.{set,set_at,append}
* lib/std: add char.from_hex
* lib/std/collections: print arrays and objects compactly
* lib/std/io: fix Formatter.vprintf result
* lib/std/io/stream: rename module for ByteBuffer
* lib/std/io/stream: make Scanner a Stream reader
* lib/std/io: make std{in,err,out} return File* if no libc
This commit is contained in:
Pierre Curto
2023-09-12 13:49:52 +02:00
committed by GitHub
parent 37bb16cca1
commit d61482dffc
11 changed files with 141 additions and 52 deletions

View File

@@ -30,9 +30,19 @@ fn ByteBuffer*! ByteBuffer.tinit(&self, usz max_read, usz initial_capacity = 16)
return self.init(max_read, initial_capacity, mem::temp())!;
}
/**
* @require buf.len > 0
* @require self.bytes.len == 0 "Buffer already initialized."
**/
fn ByteBuffer*! ByteBuffer.init_with_buffer(&self, char[] buf)
{
*self = { .stream.fns = &BYTEBUFFER_INTERFACE, .max_read = buf.len, .bytes = buf };
return self;
}
fn void! ByteBuffer.free(&self)
{
self.allocator.free(self.bytes)!;
if (self.allocator) self.allocator.free(self.bytes)!;
*self = {};
}
@@ -104,6 +114,23 @@ fn void! ByteBuffer.pushback_byte(&self)
self.has_last = false;
}
fn void! ByteBuffer.seek(&self, isz offset, Seek seek)
{
switch (seek)
{
case SET:
if (offset < 0 || offset > self.write_idx) return IoError.INVALID_POSITION?;
self.read_idx = offset;
case CURSOR:
if ((offset < 0 && self.read_idx < -offset) ||
(offset > 0 && self.read_idx + offset > self.write_idx)) return IoError.INVALID_POSITION?;
self.read_idx += offset;
case END:
if (offset < 0 || offset > self.write_idx) return IoError.INVALID_POSITION?;
self.read_idx = self.write_idx - offset;
}
}
fn usz! ByteBuffer.available(&self) @inline
{
return self.write_idx - self.read_idx;

View File

@@ -1,4 +1,4 @@
module std::io::stream;
module std::io;
struct LimitReader
{

View File

@@ -2,7 +2,8 @@ module std::io;
struct Scanner
{
Stream* stream;
inline Stream stream;
Stream* wrapped_stream;
char[] buf;
usz pattern_idx;
usz read_idx;
@@ -20,9 +21,14 @@ struct Scanner
**/
fn void Scanner.init(&self, Stream* stream, char[] buffer)
{
*self = { .stream = stream, .buf = buffer };
*self = { .stream.fns = &SCANNER_INTERFACE, .wrapped_stream = stream, .buf = buffer };
}
const StreamInterface SCANNER_INTERFACE = {
.read_fn = (ReadStreamFn)&Scanner.read,
.read_byte_fn = (ReadByteStreamFn)&Scanner.read_byte,
};
/**
* Return and clear any remaining unscanned data.
**/
@@ -85,7 +91,7 @@ macro usz! Scanner.find(&self, buf, pattern) @private
macro usz! Scanner.refill(&self, buf) @private
{
usz! n = self.stream.read(buf);
usz! n = self.wrapped_stream.read(buf);
if (catch err = n)
{
case IoError.EOF:
@@ -94,4 +100,27 @@ macro usz! Scanner.refill(&self, buf) @private
return err?;
}
return n;
}
fn usz! Scanner.read(&self, char[] bytes)
{
usz n;
if (self.pattern_idx < self.read_idx)
{
n = min(bytes.len, self.read_idx - self.pattern_idx);
bytes[:n] = self.buf[self.pattern_idx:n];
self.pattern_idx += n;
bytes = bytes[n..];
}
n += self.wrapped_stream.read(bytes)!;
return n;
}
fn char! Scanner.read_byte(&self)
{
if (self.pattern_idx < self.read_idx)
{
return self.buf[self.pattern_idx++];
}
return self.wrapped_stream.read_byte();
}