Skip to content

Commit 56d6c61

Browse files
committed
Implement DataOutputStream::writeUTF
1 parent c6bd1c3 commit 56d6c61

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ impl DataOutputStream {
2121
JavaMethodProto::new("write", "(I)V", Self::write, Default::default()),
2222
JavaMethodProto::new("writeByte", "(I)V", Self::write, Default::default()),
2323
JavaMethodProto::new("writeInt", "(I)V", Self::write_int, Default::default()),
24+
JavaMethodProto::new("writeShort", "(I)V", Self::write_short, Default::default()),
2425
JavaMethodProto::new("writeLong", "(J)V", Self::write_long, Default::default()),
2526
JavaMethodProto::new("writeChars", "(Ljava/lang/String;)V", Self::write_chars, Default::default()),
27+
JavaMethodProto::new("writeUTF", "(Ljava/lang/String;)V", Self::write_utf, Default::default()),
2628
JavaMethodProto::new("close", "()V", Self::close, Default::default()),
2729
JavaMethodProto::new("flush", "()V", Self::flush, Default::default()),
2830
],
@@ -49,6 +51,19 @@ impl DataOutputStream {
4951
Ok(())
5052
}
5153

54+
async fn write_short(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, s: i32) -> Result<()> {
55+
tracing::debug!("java.io.DataOutputStream::writeShort({:?}, {:?})", &this, s);
56+
57+
let bytes = (s as i16).to_be_bytes();
58+
let mut byte_array = jvm.instantiate_array("B", bytes.len() as _).await?;
59+
jvm.store_array(&mut byte_array, 0, cast_vec::<u8, i8>(bytes.to_vec())).await?;
60+
61+
let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?;
62+
let _: () = jvm.invoke_virtual(&out, "write", "([B)V", (byte_array,)).await?;
63+
64+
Ok(())
65+
}
66+
5267
async fn write_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, i: i32) -> Result<()> {
5368
tracing::debug!("java.io.DataOutputStream::writeInt({:?}, {:?})", &this, i);
5469

@@ -86,6 +101,21 @@ impl DataOutputStream {
86101
Ok(())
87102
}
88103

104+
async fn write_utf(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, s: ClassInstanceRef<JavaChar>) -> Result<()> {
105+
tracing::debug!("java.io.DataOutputStream::writeUTF({:?}, {:?})", &this, &s);
106+
107+
// TODO handle modified utf-8
108+
let bytes: ClassInstanceRef<Array<i8>> = jvm.invoke_virtual(&s, "getBytes", "()[B", ()).await?;
109+
let length = jvm.array_length(&bytes).await?;
110+
111+
let _: () = jvm.invoke_virtual(&this, "writeShort", "(I)V", (length as i32,)).await?;
112+
113+
let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?;
114+
let _: () = jvm.invoke_virtual(&out, "write", "([B)V", (bytes,)).await?;
115+
116+
Ok(())
117+
}
118+
89119
async fn close(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<()> {
90120
tracing::debug!("java.io.DataInputStream::close({:?})", &this);
91121

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

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

33
use bytemuck::cast_vec;
44

5-
use jvm::Result;
5+
use java_runtime::classes::java::lang::String;
6+
use jvm::{ClassInstanceRef, Result, runtime::JavaLangString};
67

78
use test_utils::test_jvm;
89

@@ -12,7 +13,7 @@ async fn test_data_input_stream() -> Result<()> {
1213

1314
let data = vec![
1415
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
15-
0x18, 0x19, 0x1a, 0x1b,
16+
0x18, 0x19, 0x1a, 0x1b, 0, 5, b'a', b'b', b'c', b'b', b'd',
1617
];
1718
let data_len = data.len();
1819

@@ -45,6 +46,10 @@ async fn test_data_input_stream() -> Result<()> {
4546
let double: f64 = jvm.invoke_virtual(&data_input_stream, "readDouble", "()D", ()).await?;
4647
assert_eq!(double, f64::from_be_bytes([0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b]));
4748

49+
let utf: ClassInstanceRef<String> = jvm.invoke_virtual(&data_input_stream, "readUTF", "()Ljava/lang/String;", ()).await?;
50+
let string = JavaLangString::to_rust_string(&jvm, &utf).await?;
51+
assert_eq!(string, "abcbd");
52+
4853
Ok(())
4954
}
5055

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,28 @@ async fn test_data_output_stream() -> Result<()> {
3636

3737
Ok(())
3838
}
39+
40+
#[tokio::test]
41+
async fn test_data_output_stream_utf() -> Result<()> {
42+
let jvm = test_jvm().await?;
43+
44+
let stream = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?;
45+
let data_output_stream = jvm
46+
.new_class("java/io/DataOutputStream", "(Ljava/io/OutputStream;)V", (stream.clone(),))
47+
.await?;
48+
49+
let string = JavaLangString::from_rust_string(&jvm, "hello, world").await?;
50+
let _: () = jvm
51+
.invoke_virtual(&data_output_stream, "writeUTF", "(Ljava/lang/String;)V", (string,))
52+
.await?;
53+
54+
let bytes = jvm.invoke_virtual(&stream, "toByteArray", "()[B", ()).await?;
55+
56+
let length = jvm.array_length(&bytes).await?;
57+
let mut buf = vec![0; length];
58+
jvm.array_raw_buffer(&bytes).await?.read(0, &mut buf)?;
59+
60+
assert_eq!(buf, vec![0, 12, b'h', b'e', b'l', b'l', b'o', b',', b' ', b'w', b'o', b'r', b'l', b'd']);
61+
62+
Ok(())
63+
}

0 commit comments

Comments
 (0)