From 5fd397563e6ccf1d2cd237f4338c2f006922822e Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 20 Jan 2025 01:30:12 -0600 Subject: [PATCH] libcinputstream: implement available --- c/native.c | 6 ++++++ c/native/libcinputstream.c | 19 +++++++++++++++++++ c/native/libcinputstream.h | 1 + classes/jvm/internal/LibcInputStream.java | 11 +++++++++-- classes/test/TestInputStream.java | 12 ++++++++++-- 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/c/native.c b/c/native.c index b62ef24..ca3a784 100644 --- a/c/native.c +++ b/c/native.c @@ -168,6 +168,12 @@ const static struct native_method native_method[] = { .method_descriptor = "([B)I", .func = native_jvm_internal_libcinputstream_open_1, }, + { + .class_name = "jvm/internal/LibcInputStream", + .method_name = "_available", + .method_descriptor = "(I)I", + .func = native_jvm_internal_libcinputstream_available_1, + }, { .class_name = "jvm/internal/LibcInputStream", .method_name = "_close", diff --git a/c/native/libcinputstream.c b/c/native/libcinputstream.c index 002e62e..ca221df 100644 --- a/c/native/libcinputstream.c +++ b/c/native/libcinputstream.c @@ -16,6 +16,25 @@ void native_jvm_internal_libcinputstream_open_1(struct vm * vm, uint32_t * args) operand_stack_push_u32(vm->current_frame, (uint32_t)file); } +void native_jvm_internal_libcinputstream_available_1(struct vm * vm, uint32_t * args) +{ + FILE * file = (FILE *)args[0]; + assert(file != nullptr); + + int current = fseek(file, 0L, SEEK_CUR); + int ret_end = fseek(file, 0L, SEEK_END); + assert(ret_end != -1); + int ftell_end = ftell(file); + assert(ftell_end != -1); + int ret_set = fseek(file, current, SEEK_SET); + assert(ret_set != -1); + + assert(ftell_end >= current); + int available = ftell_end - current; + + operand_stack_push_u32(vm->current_frame, available); +} + void native_jvm_internal_libcinputstream_close_1(struct vm * vm, uint32_t * args) { FILE * file = (FILE *)args[0]; diff --git a/c/native/libcinputstream.h b/c/native/libcinputstream.h index 070327a..8b06ad3 100644 --- a/c/native/libcinputstream.h +++ b/c/native/libcinputstream.h @@ -5,5 +5,6 @@ #include "vm.h" void native_jvm_internal_libcinputstream_open_1(struct vm * vm, uint32_t * args); +void native_jvm_internal_libcinputstream_available_1(struct vm * vm, uint32_t * args); void native_jvm_internal_libcinputstream_close_1(struct vm * vm, uint32_t * args); void native_jvm_internal_libcinputstream_read_1(struct vm * vm, uint32_t * args); diff --git a/classes/jvm/internal/LibcInputStream.java b/classes/jvm/internal/LibcInputStream.java index ffd026b..f64d601 100644 --- a/classes/jvm/internal/LibcInputStream.java +++ b/classes/jvm/internal/LibcInputStream.java @@ -1,6 +1,7 @@ package jvm.internal; import java.io.InputStream; +import java.io.IOException; public class LibcInputStream extends InputStream { private int file; // is actually FILE * @@ -11,15 +12,21 @@ public class LibcInputStream extends InputStream { file = _open(path.path); } + private static native int _available(int file); + + public int available() throws IOException { + return _available(file); + } + private static native void _close(int file); - public void close() { + public void close() throws IOException { _close(file); } private static native int _read(int file); - public int read() { + public int read() throws IOException { return _read(file); } } diff --git a/classes/test/TestInputStream.java b/classes/test/TestInputStream.java index 188e5ae..d5040cf 100644 --- a/classes/test/TestInputStream.java +++ b/classes/test/TestInputStream.java @@ -10,7 +10,15 @@ class TestInputStream { public static void main() throws IOException { Path path = FileSystems.getDefault().getPath("/home/bilbo/source.txt"); InputStream is = Files.newInputStream(path); - char c = (char)is.read(); - System.out.println(c); + int available = is.available(); + System.out.print("available: "); + System.out.println(available); + + byte[] buf = new byte[available]; + int read = is.read(buf, 0, available); + System.out.print("read: "); + System.out.println(read); + + System.out.println(buf); } }