avm2: Implement read/writeUTFBytes
This commit is contained in:
parent
ad51041457
commit
6ca6bb1d78
|
@ -87,10 +87,7 @@ package flash.net {
|
|||
return "";
|
||||
}
|
||||
|
||||
public function readUTFBytes(length:uint):String {
|
||||
stub_method("flash.net.Socket", "readUTFBytes");
|
||||
return "";
|
||||
}
|
||||
public native function readUTFBytes(length:uint):String;
|
||||
|
||||
public native function writeBoolean(value:Boolean):void;
|
||||
public native function writeByte(value:int):void;
|
||||
|
@ -114,8 +111,6 @@ package flash.net {
|
|||
stub_method("flash.net.Socket", "writeUTF");
|
||||
}
|
||||
|
||||
public function writeUTFBytes(value:String):void {
|
||||
stub_method("flash.net.Socket", "writeUTFBytes");
|
||||
}
|
||||
public native function writeUTFBytes(value:String):void;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::avm2::bytearray::Endian;
|
|||
use crate::avm2::error::{io_error, make_error_2008, security_error};
|
||||
pub use crate::avm2::object::socket_allocator;
|
||||
use crate::avm2::parameters::ParametersExt;
|
||||
use crate::avm2::string::AvmString;
|
||||
use crate::avm2::{Activation, Error, Object, TObject, Value};
|
||||
use crate::context::UpdateContext;
|
||||
|
||||
|
@ -293,6 +294,26 @@ pub fn read_unsigned_short<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn read_utf_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 length = args.get_u32(activation, 0)?;
|
||||
|
||||
return Ok(AvmString::new_utf8_bytes(
|
||||
activation.gc(),
|
||||
&socket
|
||||
.read_utf_bytes(length as usize)
|
||||
.map_err(|e| e.to_avm(activation))?,
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn write_boolean<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
|
@ -416,6 +437,20 @@ pub fn write_unsigned_int<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn write_utf_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 string = args.get_string(activation, 0)?;
|
||||
|
||||
socket.write_bytes(string.to_utf8_lossy().as_bytes());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
fn invalid_socket_error<'gc>(activation: &mut Activation<'_, 'gc>) -> Error<'gc> {
|
||||
match io_error(
|
||||
activation,
|
||||
|
|
|
@ -110,6 +110,20 @@ impl<'gc> SocketObject<'gc> {
|
|||
pub fn write_boolean(&self, val: bool) {
|
||||
self.write_bytes(&[val as u8; 1])
|
||||
}
|
||||
|
||||
/// Same as `read_bytes`, but:
|
||||
/// - cuts the result at the first null byte to recreate a bug in FP
|
||||
/// - strips off an optional UTF8 BOM at the beginning
|
||||
pub fn read_utf_bytes(&self, amnt: usize) -> Result<Vec<u8>, EofError> {
|
||||
let mut bytes = &*self.read_bytes(amnt)?;
|
||||
if let Some(without_bom) = bytes.strip_prefix(&[0xEF, 0xBB, 0xBF]) {
|
||||
bytes = without_bom;
|
||||
}
|
||||
if let Some(null) = bytes.iter().position(|b| *b == b'\0') {
|
||||
bytes = &bytes[..null];
|
||||
}
|
||||
Ok(bytes.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_write{
|
||||
|
|
Loading…
Reference in New Issue