core: replace `string::decode_swf_str` by a `SwfStrExt` extention trait

This commit is contained in:
Moulins 2023-04-10 17:20:07 +02:00 committed by Nathan Adams
parent e9a16ff5fe
commit cfde53cde2
6 changed files with 53 additions and 53 deletions

View File

@ -10,7 +10,7 @@ use crate::backend::navigator::{NavigationMethod, Request};
use crate::context::UpdateContext;
use crate::display_object::{DisplayObject, MovieClip, TDisplayObject, TDisplayObjectContainer};
use crate::ecma_conversions::f64_to_wrapping_u32;
use crate::string::{decode_swf_str, AvmString, WStr, WString};
use crate::string::{AvmString, SwfStrExt as _, WStr, WString};
use crate::tag_utils::SwfSlice;
use crate::vminterface::Instantiator;
use crate::{avm_error, avm_warn};
@ -866,10 +866,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
action
.strings
.iter()
.map(|s| {
let wstr = decode_swf_str(s, self.encoding());
AvmString::new(self.context.gc_context, wstr).into()
})
.map(|s| AvmString::new(self.context.gc_context, s.decode(self.encoding())).into())
.collect(),
));
self.set_constant_pool(self.context.avm1.constant_pool());
@ -1184,8 +1181,8 @@ impl<'a, 'gc> Activation<'a, 'gc> {
}
fn action_get_url(&mut self, action: GetUrl) -> Result<FrameControl<'gc>, Error<'gc>> {
let target = decode_swf_str(action.target, self.encoding());
let url = decode_swf_str(action.url, self.encoding());
let target = action.target.decode(self.encoding());
let url = action.url.decode(self.encoding());
// TODO: Use `StageObject::get_level_by_path`.
if target.starts_with(WStr::from_units(b"_level")) && target.len() > 6 {
match target[6..].parse::<i32>() {
@ -1411,7 +1408,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
fn action_goto_label(&mut self, action: GotoLabel) -> Result<FrameControl<'gc>, Error<'gc>> {
if let Some(clip) = self.target_clip() {
if let Some(clip) = clip.as_movie_clip() {
let label = decode_swf_str(action.label, self.encoding());
let label = action.label.decode(self.encoding());
if let Some(frame) = clip.frame_label_to_number(&label, &self.context) {
clip.goto_frame(&mut self.context, frame, true);
} else {
@ -1805,8 +1802,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
SwfValue::Float(v) => v.into(),
SwfValue::Double(v) => v.into(),
SwfValue::Str(v) => {
let v = decode_swf_str(v, self.encoding());
AvmString::new(self.context.gc_context, v).into()
AvmString::new(self.context.gc_context, v.decode(self.encoding())).into()
}
SwfValue::Register(v) => self.current_register(v),
SwfValue::ConstantPool(i) => {
@ -1917,7 +1913,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
}
fn action_set_target(&mut self, action: SetTarget) -> Result<FrameControl<'gc>, Error<'gc>> {
let target = decode_swf_str(action.target, self.encoding());
let target = action.target.decode(self.encoding());
self.set_target(&target)
}
@ -2219,8 +2215,10 @@ impl<'a, 'gc> Activation<'a, 'gc> {
match catch_vars {
CatchVar::Var(name) => {
let name = decode_swf_str(name, activation.encoding());
let name = AvmString::new(activation.context.gc_context, name);
let name = AvmString::new(
activation.context.gc_context,
name.decode(activation.encoding()),
);
activation.set_variable(name, value.to_owned())?
}
CatchVar::Register(id) => {

View File

@ -8,7 +8,7 @@ use crate::avm1::scope::Scope;
use crate::avm1::value::Value;
use crate::avm1::{ArrayObject, Object, ObjectPtr, ScriptObject, TObject};
use crate::display_object::{DisplayObject, TDisplayObject};
use crate::string::{decode_swf_str, AvmString};
use crate::string::{AvmString, SwfStrExt as _};
use crate::tag_utils::SwfSlice;
use gc_arena::{Collect, Gc, GcCell, MutationContext};
use std::{borrow::Cow, fmt, num::NonZeroU8};
@ -96,19 +96,18 @@ impl<'gc> Avm1Function<'gc> {
let name = if swf_function.name.is_empty() {
None
} else {
let name = decode_swf_str(swf_function.name, encoding);
Some(AvmString::new(gc_context, name))
Some(AvmString::new(
gc_context,
swf_function.name.decode(encoding),
))
};
let params = swf_function
.params
.iter()
.map(|p| {
let name = decode_swf_str(p.name, encoding);
Param {
register: p.register_index,
name: AvmString::new(gc_context, name),
}
.map(|p| Param {
register: p.register_index,
name: AvmString::new(gc_context, p.name.decode(encoding)),
})
.collect();

View File

@ -21,7 +21,7 @@ use crate::events::{ButtonKeyCode, ClipEvent, ClipEventResult, KeyCode};
use crate::font::{round_down_to_pixel, Glyph, TextRenderSettings};
use crate::html::{BoxBounds, FormatSpans, LayoutBox, LayoutContent, LayoutMetrics, TextFormat};
use crate::prelude::*;
use crate::string::{decode_swf_str, utils as string_utils, AvmString, WStr, WString};
use crate::string::{utils as string_utils, AvmString, SwfStrExt as _, WStr, WString};
use crate::tag_utils::SwfMovie;
use crate::vminterface::{AvmObject, Instantiator};
use chrono::Utc;
@ -198,10 +198,9 @@ impl<'gc> EditText<'gc> {
swf_movie: Arc<SwfMovie>,
swf_tag: swf::EditText,
) -> Self {
let text = swf_tag.initial_text().unwrap_or_default();
let default_format = TextFormat::from_swf_tag(swf_tag.clone(), swf_movie.clone(), context);
let encoding = swf_movie.encoding();
let text = decode_swf_str(text, encoding);
let text = swf_tag.initial_text().unwrap_or_default().decode(encoding);
let mut text_spans = if swf_tag.is_html() {
FormatSpans::from_html(&text, default_format, swf_tag.is_multiline())
@ -263,7 +262,7 @@ impl<'gc> EditText<'gc> {
layout: swf_tag.layout().cloned(),
initial_text: swf_tag
.initial_text()
.map(|s| decode_swf_str(s, encoding).into_owned()),
.map(|s| s.decode(encoding).into_owned()),
},
),
flags,

View File

@ -31,7 +31,7 @@ use crate::events::{ButtonKeyCode, ClipEvent, ClipEventResult};
use crate::font::Font;
use crate::limits::ExecutionLimit;
use crate::prelude::*;
use crate::string::{decode_swf_str, AvmString, WStr, WString};
use crate::string::{AvmString, SwfStrExt as _, WStr, WString};
use crate::tag_utils::{self, ControlFlow, DecodeResult, Error, SwfMovie, SwfSlice, SwfStream};
use crate::vminterface::{AvmObject, Instantiator};
use core::fmt;
@ -771,9 +771,7 @@ impl<'gc> MovieClip<'gc> {
if !do_abc.data.is_empty() {
let movie = self.movie();
let domain = context.library.library_for_movie_mut(movie).avm2_domain();
let name = decode_swf_str(do_abc.name, reader.encoding());
let name = AvmString::new(context.gc_context, name);
let name = AvmString::new(context.gc_context, do_abc.name.decode(reader.encoding()));
if let Err(e) = Avm2::do_abc(context, do_abc.data, Some(name), do_abc.flags, domain) {
let mut activation = Avm2Activation::from_nothing(context.reborrow());
@ -800,8 +798,10 @@ impl<'gc> MovieClip<'gc> {
for _ in 0..num_symbols {
let id = reader.read_u16()?;
let class_name = decode_swf_str(reader.read_str()?, reader.encoding());
let class_name = AvmString::new(activation.context.gc_context, class_name);
let class_name = AvmString::new(
activation.context.gc_context,
reader.read_str()?.decode(reader.encoding()),
);
let name = Avm2QName::from_qualified_name(class_name, &mut activation);
let library = activation
@ -897,9 +897,8 @@ impl<'gc> MovieClip<'gc> {
.map(|fld| fld.frame_num as u16 + 1)
.unwrap_or_else(|| static_data.total_frames + 1);
let label = decode_swf_str(label, reader.encoding());
let scene = Scene {
name: label.into_owned(),
name: label.decode(reader.encoding()).into_owned(),
start,
length: end - start,
};
@ -914,7 +913,7 @@ impl<'gc> MovieClip<'gc> {
}
for FrameLabelData { frame_num, label } in sfl_data.frame_labels {
let label = decode_swf_str(label, reader.encoding()).into_owned();
let label = label.decode(reader.encoding()).into_owned();
static_data
.frame_labels
.push((frame_num as u16 + 1, label.clone()));
@ -1558,9 +1557,8 @@ impl<'gc> MovieClip<'gc> {
child.apply_place_object(context, place_object);
if let Some(name) = &place_object.name {
let encoding = swf::SwfStr::encoding_for_version(self.swf_version());
let name = decode_swf_str(name, encoding);
child
.set_name(context.gc_context, AvmString::new(context.gc_context, name));
let name = AvmString::new(context.gc_context, name.decode(encoding));
child.set_name(context.gc_context, name);
child.set_has_explicit_name(context.gc_context, true);
}
if let Some(clip_depth) = place_object.clip_depth {
@ -3789,7 +3787,7 @@ impl<'gc, 'a> MovieClipData<'gc> {
) -> Result<(), Error> {
let exports = reader.read_export_assets()?;
for export in exports {
let name = decode_swf_str(export.name, reader.encoding());
let name = export.name.decode(reader.encoding());
let name = AvmString::new(context.gc_context, name);
let character = context
.library
@ -3823,7 +3821,7 @@ impl<'gc, 'a> MovieClipData<'gc> {
}
let frame_label = reader.read_frame_label()?;
let mut label = decode_swf_str(frame_label.label, reader.encoding()).into_owned();
let mut label = frame_label.label.decode(reader.encoding()).into_owned();
// In AVM1, frame labels are case insensitive (ASCII), but in AVM2 they are case sensitive.
if !context.is_action_script_3() {

View File

@ -2,7 +2,7 @@
use crate::context::UpdateContext;
use crate::html::iterators::TextSpanIter;
use crate::string::{decode_swf_str, Integer, Units, WStr, WString};
use crate::string::{Integer, SwfStrExt as _, Units, WStr, WString};
use crate::tag_utils::SwfMovie;
use gc_arena::Collect;
use quick_xml::{escape::escape, events::Event, Reader};
@ -145,7 +145,7 @@ impl TextFormat {
let font = et.font_id().and_then(|fid| movie_library.get_font(fid));
let font_class = et
.font_class()
.map(|s| decode_swf_str(s, encoding).into_owned())
.map(|s| s.decode(encoding).into_owned())
.or_else(|| font.map(|font| WString::from_utf8(font.descriptor().class())))
.unwrap_or_else(|| WString::from_utf8("Times New Roman"));
let align = et.layout().map(|l| l.align);

View File

@ -5,11 +5,17 @@ use std::ops::Deref;
use gc_arena::{Collect, Gc, MutationContext};
use std::borrow::Cow;
/// Converts a SWF-encoded string into a `WStr`.
pub fn decode_swf_str<'a>(s: &'a swf::SwfStr, encoding: &'static swf::Encoding) -> Cow<'a, WStr> {
match s.to_str_lossy(encoding) {
Cow::Borrowed(utf8) => from_utf8(utf8),
Cow::Owned(utf8) => WString::from_utf8_owned(utf8).into(),
pub trait SwfStrExt {
/// Converts a SWF-encoded string into a `WStr`.
fn decode(&self, encoding: &'static swf::Encoding) -> Cow<'_, WStr>;
}
impl SwfStrExt for swf::SwfStr {
fn decode(&self, encoding: &'static swf::Encoding) -> Cow<'_, WStr> {
match self.to_str_lossy(encoding) {
Cow::Borrowed(utf8) => from_utf8(utf8),
Cow::Owned(utf8) => WString::from_utf8_owned(utf8).into(),
}
}
}
@ -31,6 +37,12 @@ pub struct AvmString<'gc> {
}
impl<'gc> AvmString<'gc> {
pub fn new<S: Into<WString>>(gc_context: MutationContext<'gc, '_>, string: S) -> Self {
Self {
source: Source::Owned(Gc::allocate(gc_context, OwnedWStr(string.into()))),
}
}
pub fn new_utf8<'s, S: Into<Cow<'s, str>>>(
gc_context: MutationContext<'gc, '_>,
string: S,
@ -49,12 +61,6 @@ impl<'gc> AvmString<'gc> {
Self::new(gc_context, buf.into_owned())
}
pub fn new<S: Into<WString>>(gc_context: MutationContext<'gc, '_>, string: S) -> Self {
Self {
source: Source::Owned(Gc::allocate(gc_context, OwnedWStr(string.into()))),
}
}
pub fn as_wstr(&self) -> &WStr {
match &self.source {
Source::Owned(s) => &s.0,