Skip to content

Commit b5809a2

Browse files
committed
Implement DataInputStream::readFully and adjust some method position
1 parent 1249fff commit b5809a2

File tree

3 files changed

+79
-29
lines changed

3 files changed

+79
-29
lines changed

java_runtime/src/classes/java/io/data_input_stream.rs

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ impl DataInputStream {
1919
interfaces: vec![],
2020
methods: vec![
2121
JavaMethodProto::new("<init>", "(Ljava/io/InputStream;)V", Self::init, Default::default()),
22-
JavaMethodProto::new("read", "()I", Self::read_byte_int, Default::default()),
23-
JavaMethodProto::new("read", "([BII)I", Self::read, Default::default()),
2422
JavaMethodProto::new("readBoolean", "()Z", Self::read_boolean, Default::default()),
2523
JavaMethodProto::new("readByte", "()B", Self::read_byte, Default::default()),
2624
JavaMethodProto::new("readChar", "()C", Self::read_char, Default::default()),
2725
JavaMethodProto::new("readDouble", "()D", Self::read_double, Default::default()),
2826
JavaMethodProto::new("readFloat", "()F", Self::read_float, Default::default()),
27+
JavaMethodProto::new("readFully", "([B)V", Self::read_fully, Default::default()),
28+
JavaMethodProto::new("readFully", "([BII)V", Self::read_fully_offset_length, Default::default()),
2929
JavaMethodProto::new("readInt", "()I", Self::read_int, Default::default()),
3030
JavaMethodProto::new("readLong", "()J", Self::read_long, Default::default()),
3131
JavaMethodProto::new("readShort", "()S", Self::read_short, Default::default()),
@@ -46,31 +46,6 @@ impl DataInputStream {
4646
Ok(())
4747
}
4848

49-
async fn read(
50-
jvm: &Jvm,
51-
_: &mut RuntimeContext,
52-
this: ClassInstanceRef<Self>,
53-
b: ClassInstanceRef<Array<i8>>,
54-
off: i32,
55-
len: i32,
56-
) -> Result<i32> {
57-
tracing::debug!("java.io.DataInputStream::read({:?}, {:?}, {}, {})", &this, &b, off, len);
58-
59-
let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?;
60-
let result: i32 = jvm.invoke_virtual(&r#in, "read", "([BII)I", (b, off, len)).await?;
61-
62-
Ok(result)
63-
}
64-
65-
async fn read_byte_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<i32> {
66-
tracing::debug!("java.io.DataInputStream::read({:?})", &this);
67-
68-
let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?;
69-
let result: i32 = jvm.invoke_virtual(&r#in, "read", "()I", ()).await?;
70-
71-
Ok(result)
72-
}
73-
7449
async fn read_byte(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<i8> {
7550
tracing::debug!("java.io.DataInputStream::readByte({:?})", &this);
7651

@@ -213,4 +188,36 @@ impl DataInputStream {
213188

214189
Ok(JavaLangString::from_rust_string(jvm, &string).await?.into())
215190
}
191+
192+
async fn read_fully(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, b: ClassInstanceRef<Array<i8>>) -> Result<()> {
193+
tracing::debug!("java.io.DataInputStream::readFully({:?}, {:?})", &this, &b);
194+
195+
let length = jvm.array_length(&b).await?;
196+
197+
let _: () = jvm.invoke_virtual(&this, "readFully", "([BII)V", (b.clone(), 0, length as i32)).await?;
198+
199+
Ok(())
200+
}
201+
202+
async fn read_fully_offset_length(
203+
jvm: &Jvm,
204+
_: &mut RuntimeContext,
205+
this: ClassInstanceRef<Self>,
206+
b: ClassInstanceRef<Array<i8>>,
207+
off: i32,
208+
len: i32,
209+
) -> Result<()> {
210+
tracing::debug!("java.io.DataInputStream::readFully({:?}, {:?}, {}, {})", &this, &b, off, len);
211+
212+
let mut read = 0;
213+
while read < len {
214+
let r: i32 = jvm.invoke_virtual(&this, "read", "([BII)I", (b.clone(), off + read, len - read)).await?;
215+
if r == -1 {
216+
return Err(jvm.exception("java/io/EOFException", "End of stream reached before reading fully").await);
217+
}
218+
read += r;
219+
}
220+
221+
Ok(())
222+
}
216223
}

java_runtime/src/classes/java/io/filter_input_stream.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use alloc::vec;
22

33
use java_class_proto::{JavaFieldProto, JavaMethodProto};
44
use java_constants::FieldAccessFlags;
5-
use jvm::{ClassInstanceRef, Jvm, Result};
5+
use jvm::{Array, ClassInstanceRef, Jvm, Result};
66

77
use crate::{RuntimeClassProto, RuntimeContext, classes::java::io::InputStream};
88

@@ -19,6 +19,9 @@ impl FilterInputStream {
1919
JavaMethodProto::new("<init>", "(Ljava/io/InputStream;)V", Self::init, Default::default()),
2020
JavaMethodProto::new("available", "()I", Self::available, Default::default()),
2121
JavaMethodProto::new("close", "()V", Self::close, Default::default()),
22+
JavaMethodProto::new("read", "()I", Self::read_byte_int, Default::default()),
23+
JavaMethodProto::new("read", "([B)I", Self::read, Default::default()),
24+
JavaMethodProto::new("read", "([BII)I", Self::read_with_offset_length, Default::default()),
2225
JavaMethodProto::new("reset", "()V", Self::reset, Default::default()),
2326
],
2427
fields: vec![JavaFieldProto::new("in", "Ljava/io/InputStream;", FieldAccessFlags::PROTECTED)],
@@ -61,4 +64,38 @@ impl FilterInputStream {
6164

6265
Ok(())
6366
}
67+
68+
async fn read(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, b: ClassInstanceRef<Array<i8>>) -> Result<i32> {
69+
tracing::debug!("java.io.FilterInputStream::read({:?}, {:?})", &this, &b);
70+
71+
let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?;
72+
let result: i32 = jvm.invoke_virtual(&r#in, "read", "([B)I", (b,)).await?;
73+
74+
Ok(result)
75+
}
76+
77+
async fn read_with_offset_length(
78+
jvm: &Jvm,
79+
_: &mut RuntimeContext,
80+
this: ClassInstanceRef<Self>,
81+
b: ClassInstanceRef<Array<i8>>,
82+
off: i32,
83+
len: i32,
84+
) -> Result<i32> {
85+
tracing::debug!("java.io.FilterInputStream::read({:?}, {:?}, {}, {})", &this, &b, off, len);
86+
87+
let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?;
88+
let result: i32 = jvm.invoke_virtual(&r#in, "read", "([BII)I", (b, off, len)).await?;
89+
90+
Ok(result)
91+
}
92+
93+
async fn read_byte_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<i32> {
94+
tracing::debug!("java.io.FilterInputStream::read({:?})", &this);
95+
96+
let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?;
97+
let result: i32 = jvm.invoke_virtual(&r#in, "read", "()I", ()).await?;
98+
99+
Ok(result)
100+
}
64101
}

java_runtime/tests/classes/java/io/test_data_input_stream.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ async fn test_data_input_stream_high_bit() -> Result<()> {
5959

6060
let data = cast_vec(vec![
6161
0x81u8, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
62-
0x98, 0x99, 0x9a, 0x9b,
62+
0x98, 0x99, 0x9a, 0x9b, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
6363
]);
6464
let data_len = data.len();
6565

@@ -92,5 +92,11 @@ async fn test_data_input_stream_high_bit() -> Result<()> {
9292
let double: f64 = jvm.invoke_virtual(&data_input_stream, "readDouble", "()D", ()).await?;
9393
assert_eq!(double, f64::from_be_bytes([0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b]));
9494

95+
let array = jvm.instantiate_array("B", 6).await?;
96+
let _: () = jvm.invoke_virtual(&data_input_stream, "readFully", "([B)V", (array.clone(),)).await?;
97+
let mut buffer = vec![0; 6];
98+
jvm.array_raw_buffer(&array).await?.read(0, &mut buffer)?;
99+
assert_eq!(buffer, vec![0x10, 0x11, 0x12, 0x13, 0x14, 0x15]);
100+
95101
Ok(())
96102
}

0 commit comments

Comments
 (0)