bugfixes in core reader / openal libraries
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 22 Mar 2022 04:28:42 +0000 (23:28 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 22 Mar 2022 04:28:42 +0000 (23:28 -0500)
core/conv.onyx
core/io/io.onyx
core/io/reader.onyx
core/net/net.onyx
docs/todo
include/onyx_library.h
modules/onyx_runtime/onyx_runtime.c
modules/openal/module.onyx
modules/openal/onyx_openal.c
modules/openal/onyx_openal.so

index 278d0a5038acfe91f1cb09943f2758dbddd3fed9..f904224390eed04de1e03cbf643d14ac6c870787 100644 (file)
@@ -78,14 +78,14 @@ str_to_i64 :: (s: str, base: u32 = 10) -> i64 {
             if base <= 10 do fallthrough;
 
             value *= ~~base;
-            value += ~~(c - #char "A");
+            value += ~~((c - #char "A") + 10);
         }
         
         case #char "a" .. #char "z" {
             if base <= 10 do fallthrough;
 
             value *= ~~base;
-            value += ~~(c - #char "a");
+            value += ~~((c - #char "a") + 10);
         }
 
         case #default do break break;
index 71739d8983d4d3a1ef4e63cd1a2d53150691e970..f6a56452005eecca9313fa8ee64c3e10cf65f283 100644 (file)
@@ -29,4 +29,7 @@ Error :: enum {
 
     // Not possible to unread.
     InvalidUnread  :: 0x09;
+
+    // When reading from a stream, no data was read.
+    ReadPending    :: 0x0a;
 }
\ No newline at end of file
index c60ba6edc9b390054598bf9b0156d0fc72e35a02..d2cecc3a901989b9d7c5a8ce3faa3b6970df762f 100644 (file)
@@ -120,6 +120,7 @@ unread_byte :: (use reader: ^Reader) -> Error {
     return .None;
 }
 
+
 read_bytes :: (use reader: ^Reader, bytes: [] u8) -> (i32, Error) {
     n := bytes.count;
     if n == 0 {
@@ -132,23 +133,31 @@ read_bytes :: (use reader: ^Reader, bytes: [] u8) -> (i32, Error) {
         if reader_empty(reader) do return 0, reader_consume_error(reader);
 
         if n >= buffer.count {
-            error, n = stream_read(stream, bytes);
+            while true {
+                error, n = stream_read(stream, bytes);
+                if error != .ReadPending do break;
+            }
 
             if n > 0 do last_byte = cast(i32) bytes[n - 1];
-
             return n, reader_consume_error(reader);
         }
+    }
 
-        start, end = 0, 0;
-        error, n = stream_read(stream, buffer);
-        if n == 0 do return 0, reader_consume_error(reader);
-        end += n;
+    write_index := 0;
+    while n > 0 {
+        if reader_read_next_chunk(reader) == .ReadPending {
+            return write_index, .ReadPending;
+        }
+
+        to_write := math.min(n, end);
+        memory.copy(bytes.data + write_index, buffer.data, to_write);
+        n -= to_write;
+        write_index += to_write;
+        start += to_write;
     }
 
-    memory.copy(bytes.data, buffer.data + start, n);
-    start += n;
-    last_byte = cast(i32) buffer[start - 1];
-    return n, .None;
+    last_byte = cast(i32) bytes[bytes.count - 1];
+    return bytes.count, .None;
 }
 
 read_string :: (use reader: ^Reader, bytes := 1, allocator := context.allocator) -> str {
@@ -245,8 +254,10 @@ read_u64 :: (use reader: ^Reader) -> u64 {
     return n;
 }
 
-read_line :: (use reader: ^Reader, consume_newline := true, allocator := context.allocator, inplace := false) -> str {
-    reader_read_next_chunk(reader);
+read_line :: (use reader: ^Reader, consume_newline := true, allocator := context.allocator, inplace := false, shift_buffer := true) -> str {
+    if shift_buffer {
+        while reader_read_next_chunk(reader) == .ReadPending ---
+    }
 
     count := start;
     defer start = count;
@@ -266,9 +277,11 @@ read_line :: (use reader: ^Reader, consume_newline := true, allocator := context
     return out;
 }
 
-read_word :: (use reader: ^Reader, numeric_allowed := false, allocator := context.allocator, inplace := false) -> str {
+read_word :: (use reader: ^Reader, numeric_allowed := false, allocator := context.allocator, inplace := false, shift_buffer := true) -> str {
     skip_whitespace(reader);
-    reader_read_next_chunk(reader);
+    if shift_buffer {
+        while reader_read_next_chunk(reader) == .ReadPending ---
+    }
 
     count := start;
     defer start = count;
@@ -292,8 +305,10 @@ read_word :: (use reader: ^Reader, numeric_allowed := false, allocator := contex
     return out;
 }
 
-read_until :: (use reader: ^Reader, until: u8, skip: u32 = 0, allocator := context.allocator, consume_end := false, inplace := false) -> str {
-    reader_read_next_chunk(reader);
+read_until :: (use reader: ^Reader, until: u8, skip: u32 = 0, allocator := context.allocator, consume_end := false, inplace := false, shift_buffer := true) -> str {
+    if shift_buffer {
+        while reader_read_next_chunk(reader) == .ReadPending ---
+    }
 
     count := start;
     defer start = count;
@@ -410,6 +425,11 @@ skip_bytes :: (use reader: ^Reader, bytes: u32) -> (skipped: i32, err: Error) {
     // Try to re-read multiple times
     for 16 {
         err, n := stream_read(stream, buffer[end .. buffer.count]);
+        if err == .ReadPending {
+            error = err;
+            return err if end == 0 else .None;
+        }
+
         end += n;
         if err != .None {
             if err == .EOF do done = true;
index 45799c00136011dc1346a775a5e107ffb6871e84..82bf9b045c1ac083eb1b670311ac0f1c7e5f7253 100644 (file)
@@ -144,8 +144,12 @@ socket_sendall :: (s: ^Socket, data: [] u8) {
 
 socket_recv :: (s: ^Socket, maxlen := 1024, allocator := context.allocator) -> [] u8 {
     buffer := alloc.from_stack(maxlen);
-    received := __net_recv(s.handle, .{ buffer, maxlen });
-    if received < 0 { s.vtable = null; return .[]; }
+    would_block: bool;
+    received := __net_recv(s.handle, .{ buffer, maxlen }, ^would_block);
+    if received < 0 { 
+        if !would_block do s.vtable = null;
+        return .[];
+    }
 
     result := memory.make_slice(u8, received, allocator=allocator);
     memory.copy(result.data, buffer, received);
@@ -154,8 +158,11 @@ socket_recv :: (s: ^Socket, maxlen := 1024, allocator := context.allocator) -> [
 }
 
 socket_recv_into :: (s: ^Socket, buffer: [] u8) -> i32 {
-    received := __net_recv(s.handle, buffer);
-    if received < 0 { s.vtable = null; }
+    would_block: bool;
+    received := __net_recv(s.handle, buffer, ^would_block);
+    if received < 0 && !would_block do s.vtable = null;
+    if would_block do return 0;
+
     return received;
 }
 
@@ -163,8 +170,12 @@ socket_recv_into :: (s: ^Socket, buffer: [] u8) -> i32 {
     read = (use s: ^Socket, buffer: [] u8) -> (io.Error, u32) {
         if handle == 0 do return .BadFile, 0;
         
-        bytes_read := __net_recv(handle, buffer);
-        if bytes_read < 0 { s.vtable = null; }
+        would_block := false;
+        bytes_read := __net_recv(handle, buffer, ^would_block);
+        if bytes_read < 0 && !would_block do s.vtable = null;
+
+        if would_block do return .ReadPending, bytes_read;
+
         return .None, bytes_read;
     },
 
@@ -191,7 +202,7 @@ socket_recv_into :: (s: ^Socket, buffer: [] u8) -> i32 {
     #package __net_accept        :: (handle: Socket.Handle, out_address: ^Socket_Address.Handle) -> Socket.Handle ---
     #package __net_connect       :: (handle: Socket.Handle, host: str, port: u16) -> SocketError ---
     #package __net_send          :: (handle: Socket.Handle, data: [] u8)  -> i32 ---
-    #package __net_recv          :: (handle: Socket.Handle, data: [] u8)  -> i32 ---
+    #package __net_recv          :: (handle: Socket.Handle, data: [] u8, async_would_block: ^bool)  -> i32 ---
     #package __net_poll_recv     :: (handle: [] Socket.Handle, timeout: i32, out_recv_indicies: ^i32) -> i32 ---
 
     #package __net_address_get_address :: (address: Socket_Address.Handle, out_buffer: [] u8) -> i32 ---
index 02dbdee4e3b580aa18fcd9ceac743d279f602189..3ba0ab4c737ac753e2ba2ea394ba5c7b10e7fca1 100644 (file)
--- a/docs/todo
+++ b/docs/todo
@@ -217,10 +217,10 @@ Wishlist:
 
 
 Revamping File System:
-    [ ] runtime.fs should contain runtime specific file system API calls
-    [ ] 'os.File' should effectily be 'os.FileStream' and FileStream should go away
+    [x] runtime.fs should contain runtime specific file system API calls
+    [x] 'os.File' should effectily be 'os.FileStream' and FileStream should go away
         os.File :: struct {
             use stream: io.Stream;
             use data:   runtime.fs.FileData;
         }
-    [ ] Most file functionality will be provided using the stream API.
+    [x] Most file functionality will be provided using the stream API.
index 4361c7530718f942c406abd4f70ef2cacda55d03..d4aae4b4fd7415117d11ca10fb0a2c3d55e21db8 100644 (file)
@@ -24,7 +24,7 @@ typedef struct OnyxRuntime {
     // HACK HACK HACK
     // There should need to be this much stuff in here, but because Wasmer doesn't ship a "wasmerdll.lib"
     // file for windows, it is impossible for it to link successfully against the function provided in onyx.exe.
-    // Therefore, we must serve as the linker and do this manually. Hopefully they that library file
+    // Therefore, we must serve as the linker and do this manually. Hopefully that library file will be
     // shipped soon so this can go away...
     char* (*wasm_memory_data)(wasm_memory_t *wasm_memory);
     wasm_extern_t* (*wasm_extern_lookup_by_name)(wasm_module_t* module, wasm_instance_t* instance, const char* name);
index f3527c35e9513ea534e4d38c048eb7194baa917f..41577ee96a3d9cdd9ed16369c52c7bffc4e21538 100644 (file)
@@ -950,11 +950,19 @@ ONYX_DEF(__net_send, (WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) {
     return NULL;
 }
 
-ONYX_DEF(__net_recv, (WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) {
+ONYX_DEF(__net_recv, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) {
+    *(i32 *) ONYX_PTR(params->data[3].of.i32) = 0;
+
     #ifdef _BH_LINUX
     // TODO: The flags at the end should be controllable.
     int received = recv(params->data[0].of.i32, ONYX_PTR(params->data[1].of.i32), params->data[2].of.i32, 0);
     results->data[0] = WASM_I32_VAL(received);
+
+    if (received < 0) {
+        if (errno == EAGAIN || errno == EWOULDBLOCK) {
+            *(i32 *) ONYX_PTR(params->data[3].of.i32) = 1;
+        }
+    }
     #endif
 
     return NULL;
index 353e3629adb0ae166aa31dd71581fde2cdbc57cf..ad5bfa50e9211064cf19fd855442f8775b197ab9 100644 (file)
@@ -1,5 +1,7 @@
 package openal
 
+use package core { cptr }
+
 #library "onyx_openal"
 
 ALCdevice :: #distinct u64
@@ -104,8 +106,8 @@ ALCextfunc :: #distinct u64
     alcCaptureSamples :: (device: ALCdevice, buf: rawptr, samples: i32) -> void ---
 
     // This returns a C-allocated string, which is not supported at the moment.
-    // alGetString :: (device: ALCdevice, param:i32) -> cstr ---
-    // alcGetString :: (device: ALCdevice, param:i32) -> cstr ---
+    alGetString  :: (device: ALCdevice, param: i32) -> cptr(u8) ---
+    alcGetString :: (device: ALCdevice, param: i32) -> cptr(u8) ---
 }
 
 AL_FALSE :: 0
index 52d2673e4d260f1f45bd5ce1a859a6beda814242..79d4924943212a1ffad1dcb305ffbe283ea8c022 100644 (file)
@@ -112,6 +112,10 @@ ONYX_DEF(alDopplerFactor, (FLOAT), ()) { alDistanceModel(P(0, f32)); return NULL
 ONYX_DEF(alSpeedOfSound, (FLOAT), ()) { alDistanceModel(P(0, f32)); return NULL; }
 
 ONYX_DEF(alGetError, (), (INT)) { results->data[0] = WASM_I32_VAL(alGetError()); return NULL; }
+ONYX_DEF(alGetString, (INT), (LONG)) {
+    wasm_val_init_ptr(&results->data[0], (void *) alGetString(P(0, i32)));
+    return NULL;
+}
 
 ONYX_DEF(alcCreateContext, (LONG, PTR), (LONG)) { wasm_val_init_ptr(&results->data[0], alcCreateContext((ALCdevice *) P(0, i64), ONYX_PTR(P(1, i32)))); return NULL; }
 ONYX_DEF(alcMakeContextCurrent, (LONG), (BOOL)) { results->data[0] = WASM_I32_VAL(alcMakeContextCurrent((ALCcontext *) P(0, i64))); return NULL; }
@@ -137,7 +141,10 @@ ONYX_DEF(alcCaptureCloseDevice, (LONG), (BOOL)) { results->data[0] = WASM_I32_VA
 ONYX_DEF(alcCaptureStart, (LONG), ()) { alcCaptureStart((ALCdevice *) P(0, i64)); return NULL; }
 ONYX_DEF(alcCaptureStop, (LONG), ()) { alcCaptureStop((ALCdevice *) P(0, i64)); return NULL; }
 ONYX_DEF(alcCaptureSamples, (LONG, PTR, INT), ()) { alcCaptureSamples((ALCdevice *) P(0, i64), ONYX_PTR(P(1, i32)), P(2, i32)); return NULL; }
-
+ONYX_DEF(alcGetString, (LONG, INT), (LONG)) {
+    wasm_val_init_ptr(&results->data[0], (void *) alcGetString((ALCdevice *) P(0, i64), P(1, i32)));
+    return NULL;
+}
 
 ONYX_LIBRARY {
     ONYX_FUNC(alGenBuffers)
index 77bd206581031ccb2a6666bc0c8390c82b41958a..7b8357933ac60f375b03645015e14b1993fca5ee 100755 (executable)
Binary files a/modules/openal/onyx_openal.so and b/modules/openal/onyx_openal.so differ