libcinputstream: implement available

This commit is contained in:
Zack Buhman 2025-01-20 01:30:12 -06:00
parent 86e18a0944
commit 5fd397563e
5 changed files with 45 additions and 4 deletions

View File

@ -168,6 +168,12 @@ const static struct native_method native_method[] = {
.method_descriptor = "([B)I", .method_descriptor = "([B)I",
.func = native_jvm_internal_libcinputstream_open_1, .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", .class_name = "jvm/internal/LibcInputStream",
.method_name = "_close", .method_name = "_close",

View File

@ -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); 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) void native_jvm_internal_libcinputstream_close_1(struct vm * vm, uint32_t * args)
{ {
FILE * file = (FILE *)args[0]; FILE * file = (FILE *)args[0];

View File

@ -5,5 +5,6 @@
#include "vm.h" #include "vm.h"
void native_jvm_internal_libcinputstream_open_1(struct vm * vm, uint32_t * args); 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_close_1(struct vm * vm, uint32_t * args);
void native_jvm_internal_libcinputstream_read_1(struct vm * vm, uint32_t * args); void native_jvm_internal_libcinputstream_read_1(struct vm * vm, uint32_t * args);

View File

@ -1,6 +1,7 @@
package jvm.internal; package jvm.internal;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException;
public class LibcInputStream extends InputStream { public class LibcInputStream extends InputStream {
private int file; // is actually FILE * private int file; // is actually FILE *
@ -11,15 +12,21 @@ public class LibcInputStream extends InputStream {
file = _open(path.path); 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); private static native void _close(int file);
public void close() { public void close() throws IOException {
_close(file); _close(file);
} }
private static native int _read(int file); private static native int _read(int file);
public int read() { public int read() throws IOException {
return _read(file); return _read(file);
} }
} }

View File

@ -10,7 +10,15 @@ class TestInputStream {
public static void main() throws IOException { public static void main() throws IOException {
Path path = FileSystems.getDefault().getPath("/home/bilbo/source.txt"); Path path = FileSystems.getDefault().getPath("/home/bilbo/source.txt");
InputStream is = Files.newInputStream(path); InputStream is = Files.newInputStream(path);
char c = (char)is.read(); int available = is.available();
System.out.println(c); 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);
} }
} }