avm2: use WString in QName methods
This commit is contained in:
parent
5ca911209b
commit
053758d77c
|
@ -3,7 +3,6 @@
|
||||||
use crate::avm2::object::TObject;
|
use crate::avm2::object::TObject;
|
||||||
use crate::avm2::QName;
|
use crate::avm2::QName;
|
||||||
use crate::avm2::{Activation, Error, Object, Value};
|
use crate::avm2::{Activation, Error, Object, Value};
|
||||||
use crate::string::AvmString;
|
|
||||||
|
|
||||||
pub mod bytearray;
|
pub mod bytearray;
|
||||||
pub mod compression_algorithm;
|
pub mod compression_algorithm;
|
||||||
|
@ -42,15 +41,12 @@ pub fn get_qualified_class_name<'gc>(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(AvmString::new(
|
Ok(class
|
||||||
activation.context.gc_context,
|
.inner_class_definition()
|
||||||
class
|
.read()
|
||||||
.inner_class_definition()
|
.name()
|
||||||
.read()
|
.to_qualified_name(activation.context.gc_context)
|
||||||
.name()
|
.into())
|
||||||
.to_qualified_name(),
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements `flash.utils.getQualifiedSuperclassName`
|
/// Implements `flash.utils.getQualifiedSuperclassName`
|
||||||
|
@ -73,15 +69,12 @@ pub fn get_qualified_super_class_name<'gc>(
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(super_class) = class.superclass_object() {
|
if let Some(super_class) = class.superclass_object() {
|
||||||
Ok(AvmString::new(
|
Ok(super_class
|
||||||
activation.context.gc_context,
|
.inner_class_definition()
|
||||||
super_class
|
.read()
|
||||||
.inner_class_definition()
|
.name()
|
||||||
.read()
|
.to_qualified_name(activation.context.gc_context)
|
||||||
.name()
|
.into())
|
||||||
.to_qualified_name(),
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Value::Null)
|
Ok(Value::Null)
|
||||||
}
|
}
|
||||||
|
@ -98,6 +91,6 @@ pub fn get_definition_by_name<'gc>(
|
||||||
.get(0)
|
.get(0)
|
||||||
.unwrap_or(&Value::Undefined)
|
.unwrap_or(&Value::Undefined)
|
||||||
.coerce_to_string(activation)?;
|
.coerce_to_string(activation)?;
|
||||||
let qname = QName::from_qualified_name(&name, activation.context.gc_context);
|
let qname = QName::from_qualified_name(name, activation.context.gc_context);
|
||||||
appdomain.get_defined_value(activation, qname)
|
appdomain.get_defined_value(activation, qname)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::avm2::activation::Activation;
|
||||||
use crate::avm2::script::TranslationUnit;
|
use crate::avm2::script::TranslationUnit;
|
||||||
use crate::avm2::value::Value;
|
use crate::avm2::value::Value;
|
||||||
use crate::avm2::Error;
|
use crate::avm2::Error;
|
||||||
use crate::string::AvmString;
|
use crate::string::{AvmString, BorrowWStr, WStr, WString};
|
||||||
use gc_arena::{Collect, MutationContext};
|
use gc_arena::{Collect, MutationContext};
|
||||||
use swf::avm2::types::{
|
use swf::avm2::types::{
|
||||||
AbcFile, Index, Multiname as AbcMultiname, Namespace as AbcNamespace,
|
AbcFile, Index, Multiname as AbcMultiname, Namespace as AbcNamespace,
|
||||||
|
@ -206,32 +206,34 @@ impl<'gc> QName<'gc> {
|
||||||
/// NAMESPACE::LOCAL_NAME
|
/// NAMESPACE::LOCAL_NAME
|
||||||
/// NAMESPACE.LOCAL_NAME (Where the LAST dot is used to split the namespace & local_name)
|
/// NAMESPACE.LOCAL_NAME (Where the LAST dot is used to split the namespace & local_name)
|
||||||
/// LOCAL_NAME (Use the public namespace)
|
/// LOCAL_NAME (Use the public namespace)
|
||||||
pub fn from_qualified_name(name: &str, mc: MutationContext<'gc, '_>) -> Self {
|
pub fn from_qualified_name(name: AvmString<'gc>, mc: MutationContext<'gc, '_>) -> Self {
|
||||||
if let Some((package_name, local_name)) = name.rsplit_once("::") {
|
let parts = name
|
||||||
|
.rsplit_once(WStr::from_units(b"::"))
|
||||||
|
.or_else(|| name.rsplit_once(WStr::from_units(b".")));
|
||||||
|
|
||||||
|
if let Some((package_name, local_name)) = parts {
|
||||||
Self {
|
Self {
|
||||||
ns: Namespace::Package(AvmString::new(mc, package_name.to_string())),
|
ns: Namespace::Package(AvmString::new_ucs2(mc, package_name.into())),
|
||||||
name: AvmString::new(mc, local_name.to_string()),
|
name: AvmString::new_ucs2(mc, local_name.into()),
|
||||||
}
|
|
||||||
} else if let Some((package_name, local_name)) = name.rsplit_once('.') {
|
|
||||||
Self {
|
|
||||||
ns: Namespace::Package(AvmString::new(mc, package_name.to_string())),
|
|
||||||
name: AvmString::new(mc, local_name.to_string()),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Self {
|
Self {
|
||||||
ns: Namespace::public(),
|
ns: Namespace::public(),
|
||||||
name: AvmString::new(mc, name.to_string()),
|
name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts this `QName` to a fully qualified name.
|
/// Converts this `QName` to a fully qualified name.
|
||||||
pub fn to_qualified_name(&self) -> String {
|
pub fn to_qualified_name(&self, mc: MutationContext<'gc, '_>) -> AvmString<'gc> {
|
||||||
let uri = self.namespace().as_uri();
|
let uri = self.namespace().as_uri();
|
||||||
let name = self.local_name();
|
let name = self.local_name();
|
||||||
uri.is_empty()
|
uri.is_empty().then(|| name).unwrap_or_else(|| {
|
||||||
.then(|| name.to_string())
|
let mut buf = WString::from(uri.borrow());
|
||||||
.unwrap_or_else(|| format!("{}::{}", uri, name))
|
buf.push_str(WStr::from_units(b"::"));
|
||||||
|
buf.push_str(name.borrow());
|
||||||
|
AvmString::new_ucs2(mc, buf)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_name(&self) -> AvmString<'gc> {
|
pub fn local_name(&self) -> AvmString<'gc> {
|
||||||
|
@ -244,31 +246,25 @@ impl<'gc> QName<'gc> {
|
||||||
|
|
||||||
/// Get the string value of this QName, including the namespace URI.
|
/// Get the string value of this QName, including the namespace URI.
|
||||||
pub fn as_uri(&self, mc: MutationContext<'gc, '_>) -> AvmString<'gc> {
|
pub fn as_uri(&self, mc: MutationContext<'gc, '_>) -> AvmString<'gc> {
|
||||||
match self.ns {
|
let ns = match &self.ns {
|
||||||
Namespace::Namespace(s) if s != "" => {
|
Namespace::Namespace(s) => s.borrow(),
|
||||||
AvmString::new(mc, format!("{}::{}", &*s, &*self.name))
|
Namespace::Package(s) => s.borrow(),
|
||||||
}
|
Namespace::PackageInternal(s) => s.borrow(),
|
||||||
Namespace::Package(s) if s != "" => {
|
Namespace::Protected(s) => s.borrow(),
|
||||||
AvmString::new(mc, format!("{}::{}", &*s, &*self.name))
|
Namespace::Explicit(s) => s.borrow(),
|
||||||
}
|
Namespace::StaticProtected(s) => s.borrow(),
|
||||||
Namespace::PackageInternal(s) if s != "" => {
|
Namespace::Private(s) => s.borrow(),
|
||||||
AvmString::new(mc, format!("{}::{}", &*s, &*self.name))
|
Namespace::Any => WStr::from_units(b"*"),
|
||||||
}
|
};
|
||||||
Namespace::Protected(s) if s != "" => {
|
|
||||||
AvmString::new(mc, format!("{}::{}", &*s, &*self.name))
|
if ns.is_empty() {
|
||||||
}
|
return self.name;
|
||||||
Namespace::Explicit(s) if s != "" => {
|
|
||||||
AvmString::new(mc, format!("{}::{}", &*s, &*self.name))
|
|
||||||
}
|
|
||||||
Namespace::StaticProtected(s) if s != "" => {
|
|
||||||
AvmString::new(mc, format!("{}::{}", &*s, &*self.name))
|
|
||||||
}
|
|
||||||
Namespace::Private(s) if s != "" => {
|
|
||||||
AvmString::new(mc, format!("{}::{}", &*s, &*self.name))
|
|
||||||
}
|
|
||||||
Namespace::Any => AvmString::new(mc, format!("*::{}", &*self.name)),
|
|
||||||
_ => self.name,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut uri = WString::from(ns);
|
||||||
|
uri.push_str(WStr::from_units(b"::"));
|
||||||
|
uri.push_str(self.name.borrow());
|
||||||
|
AvmString::new_ucs2(mc, uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,8 +586,9 @@ impl<'gc> MovieClip<'gc> {
|
||||||
for _ in 0..num_symbols {
|
for _ in 0..num_symbols {
|
||||||
let id = reader.read_u16()?;
|
let id = reader.read_u16()?;
|
||||||
let class_name = reader.read_str()?.to_string_lossy(reader.encoding());
|
let class_name = reader.read_str()?.to_string_lossy(reader.encoding());
|
||||||
|
let class_name = AvmString::new(activation.context.gc_context, class_name);
|
||||||
|
|
||||||
let name = Avm2QName::from_qualified_name(&class_name, activation.context.gc_context);
|
let name = Avm2QName::from_qualified_name(class_name, activation.context.gc_context);
|
||||||
let library = activation
|
let library = activation
|
||||||
.context
|
.context
|
||||||
.library
|
.library
|
||||||
|
|
|
@ -204,13 +204,19 @@ macro_rules! impl_str_methods {
|
||||||
crate::string::ops::str_split($deref, separator)
|
crate::string::ops::str_split($deref, separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Analogue of [`str::split_at`]
|
/// Analogue of [`str::split_at`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn split_at($self: $receiver, index: usize) -> (crate::string::WStr<$lt>, crate::string::WStr<$lt>) {
|
pub fn split_at($self: $receiver, index: usize) -> (crate::string::WStr<$lt>, crate::string::WStr<$lt>) {
|
||||||
let s = $deref;
|
let s = $deref;
|
||||||
(s.slice(..index), s.slice(index..))
|
(s.slice(..index), s.slice(index..))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Analogue of [`str::rsplit_once`].
|
||||||
|
#[inline]
|
||||||
|
pub fn rsplit_once<$($pat_gen)* P: crate::string::Pattern<$pat_lt>>($self: $pat_self, pattern: P) -> Option<(WStr<$pat_lt>, WStr<$pat_lt>)> {
|
||||||
|
crate::string::ops::str_rsplit_once($deref, pattern)
|
||||||
|
}
|
||||||
|
|
||||||
/// Analogue of [`str::trim_matches`].
|
/// Analogue of [`str::trim_matches`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn trim_matches<$($pat_gen)* P: crate::string::Pattern<$pat_lt>>($self: $pat_self, pattern: P) -> WStr<$pat_lt> {
|
pub fn trim_matches<$($pat_gen)* P: crate::string::Pattern<$pat_lt>>($self: $pat_self, pattern: P) -> WStr<$pat_lt> {
|
||||||
|
|
|
@ -212,6 +212,14 @@ pub fn str_split<'a, P: Pattern<'a>>(string: WStr<'a>, pattern: P) -> Split<'a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn str_rsplit_once<'a, P: Pattern<'a>>(
|
||||||
|
string: WStr<'a>,
|
||||||
|
pattern: P,
|
||||||
|
) -> Option<(WStr<'a>, WStr<'a>)> {
|
||||||
|
let (start, end) = pattern.into_searcher(string).next_match_back()?;
|
||||||
|
Some((string.slice(..start), string.slice(end..)))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn starts_with<'a, P: Pattern<'a>>(string: WStr<'a>, pattern: P) -> bool {
|
pub fn starts_with<'a, P: Pattern<'a>>(string: WStr<'a>, pattern: P) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
pattern.into_searcher(string).next(),
|
pattern.into_searcher(string).next(),
|
||||||
|
|
Loading…
Reference in New Issue