From 2437573a8fec758fa8df413d931ba82eb2d02870 Mon Sep 17 00:00:00 2001 From: Pierre Curto Date: Mon, 10 Jul 2023 20:13:31 +0200 Subject: [PATCH] lib/std/io: add Stream.read_all (#843) * lib/std/io: add Stream.read_all Signed-off-by: Pierre Curto * lib/std/core: use shortened receiver notation Signed-off-by: Pierre Curto --------- Signed-off-by: Pierre Curto --- lib/std/core/mem_allocator.c3 | 40 +++++++++++------------ lib/std/core/string.c3 | 56 ++++++++++++++++----------------- lib/std/core/string_iterator.c3 | 14 ++++----- lib/std/core/string_to_real.c3 | 2 +- lib/std/core/types.c3 | 2 +- lib/std/io/io.c3 | 1 + lib/std/io/io_printf.c3 | 2 +- lib/std/io/io_stream.c3 | 7 +++++ 8 files changed, 66 insertions(+), 58 deletions(-) diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3 index 4c2487dc6..2cf5c08a6 100644 --- a/lib/std/core/mem_allocator.c3 +++ b/lib/std/core/mem_allocator.c3 @@ -62,64 +62,64 @@ fault AllocationFailure -macro void*! Allocator.alloc(Allocator* allocator, usz size) +macro void*! Allocator.alloc(&allocator, usz size) { - return allocator.function(allocator, size, 0, 0, null, ALLOC); + return allocator.function(&allocator, size, 0, 0, null, ALLOC); } /** * @require alignment && math::is_power_of_2(alignment) */ -macro void*! Allocator.alloc_aligned(Allocator* allocator, usz size, usz alignment, usz offset = 0) +macro void*! Allocator.alloc_aligned(&allocator, usz size, usz alignment, usz offset = 0) { - return allocator.function(allocator, size, alignment, offset, null, ALIGNED_ALLOC); + return allocator.function(&allocator, size, alignment, offset, null, ALIGNED_ALLOC); } -macro void*! Allocator.realloc(Allocator* allocator, void* old_pointer, usz size) +macro void*! Allocator.realloc(&allocator, void* old_pointer, usz size) { - return allocator.function(allocator, size, 0, 0, old_pointer, REALLOC); + return allocator.function(&allocator, size, 0, 0, old_pointer, REALLOC); } /** * @require alignment && math::is_power_of_2(alignment) */ -macro void*! Allocator.realloc_aligned(Allocator* allocator, void* old_pointer, usz size, usz alignment, usz offset = 0) +macro void*! Allocator.realloc_aligned(&allocator, void* old_pointer, usz size, usz alignment, usz offset = 0) { - return allocator.function(allocator, size, alignment, offset, old_pointer, ALIGNED_REALLOC); + return allocator.function(&allocator, size, alignment, offset, old_pointer, ALIGNED_REALLOC); } -macro usz Allocator.mark(Allocator* allocator) +macro usz Allocator.mark(&allocator) { - return (usz)(uptr)allocator.function(allocator, 0, 0, 0, null, MARK) ?? 0; + return (usz)(uptr)allocator.function(&allocator, 0, 0, 0, null, MARK) ?? 0; } -macro void*! Allocator.calloc(Allocator* allocator, usz size) +macro void*! Allocator.calloc(&allocator, usz size) { - return allocator.function(allocator, size, 0, 0, null, CALLOC); + return allocator.function(&allocator, size, 0, 0, null, CALLOC); } /** * @require alignment && math::is_power_of_2(alignment) */ -macro void*! Allocator.calloc_aligned(Allocator* allocator, usz size, usz alignment, usz offset = 0) +macro void*! Allocator.calloc_aligned(&allocator, usz size, usz alignment, usz offset = 0) { - return allocator.function(allocator, size, alignment, offset, null, ALIGNED_CALLOC); + return allocator.function(&allocator, size, alignment, offset, null, ALIGNED_CALLOC); } -macro void! Allocator.free(Allocator* allocator, void* old_pointer) +macro void! Allocator.free(&allocator, void* old_pointer) { - allocator.function(allocator, 0, 0, 0, old_pointer, FREE)!; + allocator.function(&allocator, 0, 0, 0, old_pointer, FREE)!; } -macro void! Allocator.free_aligned(Allocator* allocator, void* old_pointer) +macro void! Allocator.free_aligned(&allocator, void* old_pointer) { - allocator.function(allocator, 0, 0, 0, old_pointer, ALIGNED_FREE)!; + allocator.function(&allocator, 0, 0, 0, old_pointer, ALIGNED_FREE)!; } -macro void Allocator.reset(Allocator* allocator, usz mark = 0) +macro void Allocator.reset(&allocator, usz mark = 0) { - (void)allocator.function(allocator, mark, 0, 0, null, RESET); + (void)allocator.function(&allocator, mark, 0, 0, null, RESET); } fn usz alignment_for_allocation(usz alignment) @inline @private diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index 645b71c76..4e039ea47 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -85,7 +85,7 @@ fn String join(String[] s, String joiner, Allocator* using = mem::heap()) * @param [in] string * @param [in] to_trim **/ -fn String String.trim(String string, String to_trim = "\t\n\r ") +fn String String.trim(string, String to_trim = "\t\n\r ") { usz start = 0; usz len = string.len; @@ -100,7 +100,7 @@ fn String String.trim(String string, String to_trim = "\t\n\r ") * @param [in] string * @param [in] needle **/ -fn bool String.starts_with(String string, String needle) +fn bool String.starts_with(string, String needle) { if (needle.len > string.len) return false; if (!needle.len) return true; @@ -111,7 +111,7 @@ fn bool String.starts_with(String string, String needle) * @param [in] string * @param [in] needle **/ -fn bool String.ends_with(String string, String needle) +fn bool String.ends_with(string, String needle) { if (needle.len > string.len) return false; if (!needle.len) return true; @@ -124,7 +124,7 @@ fn bool String.ends_with(String string, String needle) * @param [in] string * @param [in] needle **/ -fn String String.strip(String string, String needle) +fn String String.strip(string, String needle) { if (!needle.len || !string.starts_with(needle)) return string; return string[needle.len..]; @@ -136,7 +136,7 @@ fn String String.strip(String string, String needle) * @param [in] string * @param [in] needle **/ -fn String String.strip_end(String string, String needle) +fn String String.strip_end(string, String needle) { if (!needle.len || !string.ends_with(needle)) return string; // Note that this is the safe way if we want to support zero length. @@ -154,7 +154,7 @@ fn String String.strip_end(String string, String needle) * @require needle.len > 0 "The needle must be at least 1 character long" * @ensure return.len > 0 **/ -fn String[] String.split(String s, String needle, usz max = 0, Allocator* using = mem::heap()) +fn String[] String.split(s, String needle, usz max = 0, Allocator* using = mem::heap()) { usz capacity = 16; usz i = 0; @@ -192,12 +192,12 @@ fn String[] String.split(String s, String needle, usz max = 0, Allocator* using * @param [in] needle * @param max "Max number of elements, 0 means no limit, defaults to 0" **/ -fn String[] String.tsplit(String s, String needle, usz max = 0) +fn String[] String.tsplit(s, String needle, usz max = 0) { return s.split(needle, max, mem::temp()) @inline; } -fn bool String.contains(String s, String needle) +fn bool String.contains(s, String needle) { return @ok(s.index_of(needle)); } @@ -213,7 +213,7 @@ fn bool String.contains(String s, String needle) * @return "the index of the needle" * @return! SearchResult.MISSING "if the needle cannot be found" **/ -fn usz! String.index_of(String s, String needle) +fn usz! String.index_of(s, String needle) { usz match = 0; usz needed = needle.len; @@ -249,7 +249,7 @@ fn usz! String.index_of(String s, String needle) * @return "the index of the needle" * @return! SearchResult.MISSING "if the needle cannot be found" **/ -fn usz! String.rindex_of(String s, String needle) +fn usz! String.rindex_of(s, String needle) { usz match = 0; usz needed = needle.len; @@ -274,12 +274,12 @@ fn usz! String.rindex_of(String s, String needle) return SearchResult.MISSING?; } -fn String ZString.as_str(ZString str) +fn String ZString.as_str(str) { return (String)((char*)str)[:str.len()]; } -fn usz ZString.char_len(ZString str) +fn usz ZString.char_len(str) { usz len = 0; char* ptr = (char*)str; @@ -290,7 +290,7 @@ fn usz ZString.char_len(ZString str) return len; } -fn usz ZString.len(ZString str) +fn usz ZString.len(str) { usz len = 0; char* ptr = (char*)str; @@ -299,7 +299,7 @@ fn usz ZString.len(ZString str) } -fn ZString String.zstr_copy(String s, Allocator* using = mem::heap()) +fn ZString String.zstr_copy(s, Allocator* using = mem::heap()) { usz len = s.len; char* str = malloc(len + 1, .using = using); @@ -308,7 +308,7 @@ fn ZString String.zstr_copy(String s, Allocator* using = mem::heap()) return (ZString)str; } -fn String String.concat(String s1, String s2, Allocator* using = mem::heap()) +fn String String.concat(s1, String s2, Allocator* using = mem::heap()) { usz full_len = s1.len + s2.len; char* str = malloc(full_len + 1, .using = using); @@ -319,12 +319,12 @@ fn String String.concat(String s1, String s2, Allocator* using = mem::heap()) return (String)str[:full_len]; } -fn String String.tconcat(String s1, String s2) => s1.concat(s2, mem::temp()); +fn String String.tconcat(s1, String s2) => s1.concat(s2, mem::temp()); -fn ZString String.zstr_tcopy(String s) => s.zstr_copy(mem::temp()) @inline; +fn ZString String.zstr_tcopy(s) => s.zstr_copy(mem::temp()) @inline; -fn String String.copy(String s, Allocator* using = mem::heap()) +fn String String.copy(s, Allocator* using = mem::heap()) { usz len = s.len; char* str = malloc(len + 1, .using = using); @@ -333,10 +333,10 @@ fn String String.copy(String s, Allocator* using = mem::heap()) return (String)str[:len]; } -fn String String.tcopy(String s) => s.copy(mem::temp()) @inline; +fn String String.tcopy(s) => s.copy(mem::temp()) @inline; -fn String ZString.copy(ZString z, Allocator* using = mem::heap()) => z.as_str().copy(using) @inline; -fn String ZString.tcopy(ZString z) => z.as_str().copy(mem::temp()) @inline; +fn String ZString.copy(z, Allocator* using = mem::heap()) => z.as_str().copy(using) @inline; +fn String ZString.tcopy(z) => z.as_str().copy(mem::temp()) @inline; /** * Convert an UTF-8 string to UTF-16 @@ -344,7 +344,7 @@ fn String ZString.tcopy(ZString z) => z.as_str().copy(mem::temp()) @inline; * @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence" * @return! AllocationFailure "If allocation of the string fails" **/ -fn Char16[]! String.to_utf16(String s, Allocator* using = mem::heap()) +fn Char16[]! String.to_utf16(s, Allocator* using = mem::heap()) { usz len16 = conv::utf16len_for_utf8(s); Char16* data = malloc_checked(Char16, len16 + 1, .using = using)!; @@ -353,9 +353,9 @@ fn Char16[]! String.to_utf16(String s, Allocator* using = mem::heap()) return data[:len16]; } -fn WString! String.to_wstring(String s, Allocator* using = mem::heap()) => (WString)s.to_utf16(using).ptr; +fn WString! String.to_wstring(s, Allocator* using = mem::heap()) => (WString)s.to_utf16(using).ptr; -fn Char32[]! String.to_utf32(String s, Allocator* using = mem::heap()) +fn Char32[]! String.to_utf32(s, Allocator* using = mem::heap()) { usz codepoints = conv::utf8_codepoints(s); Char32* data = malloc_checked(Char32, codepoints + 1, .using = using)!; @@ -364,24 +364,24 @@ fn Char32[]! String.to_utf32(String s, Allocator* using = mem::heap()) return data[:codepoints]; } -fn void String.convert_ascii_to_lower(String s) +fn void String.convert_ascii_to_lower(s) { foreach (&c : s) if (*c >= 'A' && *c <= 'Z') *c += 'a' - 'A'; } -fn String String.ascii_to_lower(String s, Allocator* using = mem::heap()) +fn String String.ascii_to_lower(s, Allocator* using = mem::heap()) { String copy = s.copy(using); copy.convert_ascii_to_lower(); return copy; } -fn void String.convert_ascii_to_upper(String s) +fn void String.convert_ascii_to_upper(s) { foreach (&c : s) if (*c >= 'a' && *c <= 'z') *c -= 'a' - 'A'; } -fn String String.ascii_to_upper(String s, Allocator* using = mem::heap()) +fn String String.ascii_to_upper(s, Allocator* using = mem::heap()) { String copy = s.copy(using); copy.convert_ascii_to_upper(); diff --git a/lib/std/core/string_iterator.c3 b/lib/std/core/string_iterator.c3 index 96ea6b4da..246626508 100644 --- a/lib/std/core/string_iterator.c3 +++ b/lib/std/core/string_iterator.c3 @@ -6,18 +6,18 @@ struct StringIterator usz current; } -fn void StringIterator.reset(StringIterator* this) +fn void StringIterator.reset(&self) { - this.current = 0; + self.current = 0; } -fn Char32! StringIterator.next(StringIterator* this) +fn Char32! StringIterator.next(&self) { - usz len = this.utf8.len; - usz current = this.current; + usz len = self.utf8.len; + usz current = self.current; if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; usz read = (len - current < 4 ? len - current : 4); - Char32 res = conv::utf8_to_char32(&this.utf8[current], &read)!; - this.current += read; + Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!; + self.current += read; return res; } \ No newline at end of file diff --git a/lib/std/core/string_to_real.c3 b/lib/std/core/string_to_real.c3 index cf405e62c..dabaef323 100644 --- a/lib/std/core/string_to_real.c3 +++ b/lib/std/core/string_to_real.c3 @@ -449,7 +449,7 @@ macro double! hexfloat(char[] chars, int $bits, int $emin, int sign) return math::scalbn(y, (int)e2); } -macro String.to_real(String chars, $Type) @private +macro String.to_real(chars, $Type) @private { int sign = 1; $switch ($Type) diff --git a/lib/std/core/types.c3 b/lib/std/core/types.c3 index dc2f29be7..220587965 100644 --- a/lib/std/core/types.c3 +++ b/lib/std/core/types.c3 @@ -85,7 +85,7 @@ macro bool is_numerical($Type) $endif } -fn bool TypeKind.is_int(TypeKind kind) @inline +fn bool TypeKind.is_int(kind) @inline { return kind == TypeKind.SIGNED_INT || kind == TypeKind.UNSIGNED_INT; } diff --git a/lib/std/io/io.c3 b/lib/std/io/io.c3 index 22f0295be..592039de6 100644 --- a/lib/std/io/io.c3 +++ b/lib/std/io/io.c3 @@ -30,6 +30,7 @@ fault IoError OUT_OF_SPACE, INVALID_PUSHBACK, EOF, + UNEXPECTED_EOF, CANNOT_READ_DIR, TOO_MANY_DESCRIPTORS, FILE_IS_DIR, diff --git a/lib/std/io/io_printf.c3 b/lib/std/io/io_printf.c3 index 7c5311a16..8867efb6b 100644 --- a/lib/std/io/io_printf.c3 +++ b/lib/std/io/io_printf.c3 @@ -121,7 +121,7 @@ macro bool! Formatter.print_with_function(&self, any arg) self.width = old_width; self.prec = old_prec; } - arg.to_format(&self)!; // TODO should be self + arg.to_format(&self)!; return true; } if (&arg.to_string) diff --git a/lib/std/io/io_stream.c3 b/lib/std/io/io_stream.c3 index 14ab3d879..0d8bd631d 100644 --- a/lib/std/io/io_stream.c3 +++ b/lib/std/io/io_stream.c3 @@ -104,6 +104,13 @@ fn char! Stream.read_byte(self) @inline return IoError.UNSUPPORTED_OPERATION?; } +fn usz! Stream.read_all(self, char[] buffer) @inline +{ + usz n = self.read(buffer)!; + if (n != buffer.len) return IoError.UNEXPECTED_EOF?; + return n; +} + fn String! Stream.readline(self, Allocator* using = mem::heap()) { ReadByteStreamFn func;