rusty-jvm 0.5.0

An implementation of a Java Virtual Machine (JVM).
Documentation
use crate::vm::error::Result;
use crate::vm::exception::helpers::{throw_file_not_found_exception, throw_ioexception};
use crate::vm::exception::throwing_result::ThrowingResult;
use crate::vm::heap::heap::with_heap_read_lock;
use crate::vm::stack::stack_frame::StackFrames;
use crate::vm::system_native::platform_file::Mode::Write;
use crate::vm::system_native::platform_file::PlatformFile;
use crate::vm::system_native::string::get_utf8_string_by_ref;
use crate::{throw_and_return, unwrap_or_return_err, unwrap_result_or_return_default};
use std::fs::OpenOptions;
use std::io::Write as IoWrite;

pub(crate) fn file_output_stream_open0_wrp(
    args: &[i32],
    stack_frames: &mut StackFrames,
) -> Result<Vec<i32>> {
    let obj_ref = args[0];
    let string_ref = args[1];
    let append = args[2] != 0;
    unwrap_result_or_return_default!(open0(obj_ref, string_ref, append, stack_frames), vec![]);
    Ok(vec![])
}

fn open0(
    obj_ref: i32,
    file_name_ref: i32,
    append: bool,
    stack_frames: &mut StackFrames,
) -> ThrowingResult<()> {
    let file_name = unwrap_or_return_err!(get_utf8_string_by_ref(file_name_ref));

    match OpenOptions::new()
        .write(true)
        .create(true)
        .truncate(!append)
        .append(append)
        .open(file_name)
    {
        Ok(file) => ThrowingResult::ok(unwrap_or_return_err!(PlatformFile::set_raw_id(
            obj_ref, file, Write
        ))),
        Err(e) => throw_and_return!(throw_file_not_found_exception(
            file_name_ref,
            &e.to_string(),
            stack_frames
        )),
    }
}

pub(crate) fn file_output_stream_write_wrp(
    args: &[i32],
    stack_frames: &mut StackFrames,
) -> Result<Vec<i32>> {
    let obj_ref = args[0];
    let byte = args[1];
    let append = args[2] != 0;
    unwrap_result_or_return_default!(write(obj_ref, byte, append, stack_frames), vec![]);
    Ok(vec![])
}
fn write(
    obj_ref: i32,
    byte: i32,
    _append: bool,
    stack_frames: &mut StackFrames,
) -> ThrowingResult<()> {
    let mut file = match PlatformFile::get_by_raw_id(obj_ref, Write, stack_frames) {
        ThrowingResult::Result(result) => unwrap_or_return_err!(result),
        ThrowingResult::ExceptionThrown => return ThrowingResult::ExceptionThrown,
    };

    match write!(file, "{}", byte as u8 as char) {
        Ok(_) => ThrowingResult::ok(()),
        Err(e) => throw_and_return!(throw_ioexception(&e.to_string(), stack_frames)),
    }
}

pub(crate) fn file_output_stream_write_bytes_wrp(
    args: &[i32],
    stack_frames: &mut StackFrames,
) -> Result<Vec<i32>> {
    let obj_ref = args[0];
    let bytes_ref = args[1];
    let off = args[2];
    let len = args[3];
    let append = args[4] != 0;
    unwrap_result_or_return_default!(
        write_bytes(obj_ref, bytes_ref, off, len, append, stack_frames),
        vec![]
    );
    Ok(vec![])
}
fn write_bytes(
    obj_ref: i32,
    bytes_ref: i32,
    off: i32,
    len: i32,
    _append: bool,
    stack_frames: &mut StackFrames,
) -> ThrowingResult<()> {
    let mut file = match PlatformFile::get_by_raw_id(obj_ref, Write, stack_frames) {
        ThrowingResult::Result(result) => unwrap_or_return_err!(result),
        ThrowingResult::ExceptionThrown => return ThrowingResult::ExceptionThrown,
    };
    let array =
        unwrap_or_return_err!(with_heap_read_lock(|heap| heap.get_entire_array(bytes_ref)));
    let raw = array.get_entire_value();
    let mut vec = Vec::with_capacity(raw.len());
    for i in off..off + len {
        vec.push(raw[i as usize][0] as i8 as u8);
    }

    match file.write_all(&vec) {
        Ok(_) => ThrowingResult::ok(()),
        Err(e) => throw_and_return!(throw_ioexception(&e.to_string(), stack_frames)),
    }
}