avm1: Implement onData()
This commit is contained in:
parent
2b18a5999b
commit
25b1ed7e9c
|
@ -7,7 +7,7 @@ use crate::avm_warn;
|
||||||
use crate::context::{GcContext, UpdateContext};
|
use crate::context::{GcContext, UpdateContext};
|
||||||
use crate::socket::SocketHandle;
|
use crate::socket::SocketHandle;
|
||||||
use gc_arena::{Collect, Gc};
|
use gc_arena::{Collect, Gc};
|
||||||
use std::cell::Cell;
|
use std::cell::{Cell, RefCell, RefMut};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Collect)]
|
#[derive(Clone, Debug, Collect)]
|
||||||
#[collect(require_static)]
|
#[collect(require_static)]
|
||||||
|
@ -15,6 +15,7 @@ struct XmlSocketData {
|
||||||
handle: Cell<Option<SocketHandle>>,
|
handle: Cell<Option<SocketHandle>>,
|
||||||
/// Connection timeout in milliseconds.
|
/// Connection timeout in milliseconds.
|
||||||
timeout: Cell<u32>,
|
timeout: Cell<u32>,
|
||||||
|
read_buffer: RefCell<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Collect)]
|
#[derive(Clone, Debug, Collect)]
|
||||||
|
@ -34,6 +35,10 @@ impl<'gc> XmlSocket<'gc> {
|
||||||
self.0.timeout.get()
|
self.0.timeout.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_buffer(&self) -> RefMut<'_, Vec<u8>> {
|
||||||
|
self.0.read_buffer.borrow_mut()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cast(value: Value<'gc>) -> Option<Self> {
|
pub fn cast(value: Value<'gc>) -> Option<Self> {
|
||||||
if let Value::Object(object) = value {
|
if let Value::Object(object) = value {
|
||||||
if let NativeObject::XmlSocket(xml_socket) = object.native() {
|
if let NativeObject::XmlSocket(xml_socket) = object.native() {
|
||||||
|
@ -212,6 +217,7 @@ pub fn constructor<'gc>(
|
||||||
handle: Cell::new(None),
|
handle: Cell::new(None),
|
||||||
/// Default timeout is 20_000 milliseconds (20 seconds)
|
/// Default timeout is 20_000 milliseconds (20 seconds)
|
||||||
timeout: Cell::new(20000),
|
timeout: Cell::new(20000),
|
||||||
|
read_buffer: RefCell::new(Vec::new()),
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
backend::navigator::NavigatorBackend,
|
backend::navigator::NavigatorBackend,
|
||||||
context::UpdateContext,
|
context::UpdateContext,
|
||||||
|
string::AvmString,
|
||||||
};
|
};
|
||||||
use async_channel::{unbounded, Sender as AsyncSender};
|
use async_channel::{unbounded, Sender as AsyncSender};
|
||||||
use gc_arena::Collect;
|
use gc_arena::Collect;
|
||||||
|
@ -296,12 +297,36 @@ impl<'gc> Sockets<'gc> {
|
||||||
target.into(),
|
target.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: Implement this.
|
SocketKind::Avm1(target) => {
|
||||||
SocketKind::Avm1(_) => {
|
|
||||||
let mut activation = Activation::from_stub(
|
let mut activation = Activation::from_stub(
|
||||||
context.reborrow(),
|
context.reborrow(),
|
||||||
ActivationIdentifier::root("[XMLSocket]"),
|
ActivationIdentifier::root("[XMLSocket]"),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// NOTE: This is enforced in connect_avm1() function.
|
||||||
|
let xml_socket =
|
||||||
|
XmlSocket::cast(target.into()).expect("target should be XmlSocket");
|
||||||
|
|
||||||
|
let mut buffer = xml_socket.read_buffer();
|
||||||
|
buffer.extend(data);
|
||||||
|
|
||||||
|
// Check for a message.
|
||||||
|
if let Some((index, _)) =
|
||||||
|
buffer.iter().enumerate().find(|(_, &b)| b == 0)
|
||||||
|
{
|
||||||
|
let message = buffer.drain(..index).collect::<Vec<_>>();
|
||||||
|
// Remove null byte.
|
||||||
|
let _ = buffer.drain(..1);
|
||||||
|
|
||||||
|
let message = AvmString::new_utf8_bytes(activation.gc(), &message);
|
||||||
|
|
||||||
|
let _ = target.call_method(
|
||||||
|
"onData".into(),
|
||||||
|
&[message.into()],
|
||||||
|
&mut activation,
|
||||||
|
ExecutionReason::Special,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue