avm2: Implement writeByte and writeBytes

This commit is contained in:
sleepycatcoding 2023-07-14 14:48:31 +03:00 committed by Nathan Adams
parent 60de72fc3e
commit 3dfb6e3bb1
3 changed files with 67 additions and 8 deletions

View File

@ -140,13 +140,8 @@ package flash.net {
stub_method("flash.net.Socket", "writeBoolean");
}
public function writeByte(value:int):void {
stub_method("flash.net.Socket", "writeByte");
}
public function writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void {
stub_method("flash.net.Socket", "writeBytes");
}
public native function writeByte(value:int):void;
public native function writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void;
public function writeDouble(value:Number):void {
stub_method("flash.net.Socket", "writeDouble");

View File

@ -102,3 +102,61 @@ pub fn get_connected<'gc>(
Ok(Value::Bool(is_connected))
}
pub fn write_byte<'gc>(
activation: &mut Activation<'_, 'gc>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(socket) = this.as_socket() {
let byte = args
.get(0)
.cloned()
.unwrap_or(Value::Undefined)
.coerce_to_i32(activation)?;
socket.write_bytes(&[byte as u8]);
}
Ok(Value::Undefined)
}
pub fn write_bytes<'gc>(
activation: &mut Activation<'_, 'gc>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(socket) = this.as_socket() {
let bytearray = args
.get(0)
.unwrap_or(&Value::Undefined)
.coerce_to_object(activation)?;
let offset = args
.get(1)
.unwrap_or(&Value::Integer(0))
.coerce_to_u32(activation)? as usize;
let length = args
.get(2)
.unwrap_or(&Value::Integer(0))
.coerce_to_u32(activation)? as usize;
let ba_read = bytearray
.as_bytearray()
.ok_or("ArgumentError: Parameter must be a bytearray")?;
let to_write = ba_read
.read_at(
// If length is 0, lets read the remaining bytes of ByteArray from the supplied offset
if length != 0 {
length
} else {
ba_read.len().saturating_sub(offset)
},
offset,
)
.map_err(|e| e.to_avm(activation))?;
socket.write_bytes(to_write);
}
Ok(Value::Undefined)
}

View File

@ -7,7 +7,7 @@ use crate::socket::SocketHandle;
use gc_arena::barrier::unlock;
use gc_arena::{lock::RefLock, Collect, Gc};
use gc_arena::{GcWeak, Mutation};
use std::cell::{Cell, Ref, RefMut};
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::fmt;
/// A class instance allocator that allocates ShaderData objects.
@ -24,6 +24,7 @@ pub fn socket_allocator<'gc>(
// Default endianness is Big.
endian: Cell::new(Endian::Big),
handle: Cell::new(None),
write_buffer: RefCell::new(vec![]),
},
))
.into())
@ -75,6 +76,10 @@ impl<'gc> SocketObject<'gc> {
pub fn set_handle(&self, handle: SocketHandle) -> Option<SocketHandle> {
self.0.handle.replace(Some(handle))
}
pub fn write_bytes(&self, bytes: &[u8]) {
self.0.write_buffer.borrow_mut().extend_from_slice(bytes)
}
}
#[derive(Collect)]
@ -85,6 +90,7 @@ pub struct SocketObjectData<'gc> {
#[collect(require_static)]
handle: Cell<Option<SocketHandle>>,
endian: Cell<Endian>,
write_buffer: RefCell<Vec<u8>>,
}
impl fmt::Debug for SocketObject<'_> {