Move back AvmString into ruffle_core::string

This allows removing the gc_arena dependency in ruffle_wstr
This commit is contained in:
Moulins 2022-03-23 22:15:40 +01:00 committed by Mike Welsh
parent bd576639d5
commit 1bff5c517a
8 changed files with 124 additions and 134 deletions

3
Cargo.lock generated
View File

@ -3154,9 +3154,6 @@ dependencies = [
[[package]]
name = "ruffle_wstr"
version = "0.1.0"
dependencies = [
"gc-arena",
]
[[package]]
name = "rustc-hash"

View File

@ -3341,6 +3341,7 @@ impl Default for Scene {
struct MovieClipStatic<'gc> {
id: CharacterId,
swf: SwfSlice,
#[collect(require_static)]
frame_labels: HashMap<WString, FrameNumber>,
#[collect(require_static)]
scene_labels: HashMap<WString, Scene>,

View File

@ -1 +1,124 @@
pub use ruffle_wstr::*;
use std::ops::Deref;
use gc_arena::{Collect, Gc, MutationContext};
use std::borrow::Cow;
#[derive(Clone, Copy, Collect)]
#[collect(no_drop)]
enum Source<'gc> {
Owned(Gc<'gc, OwnedWStr>),
Static(&'static WStr),
}
#[derive(Collect)]
#[collect(require_static)]
struct OwnedWStr(WString);
#[derive(Clone, Copy, Collect)]
#[collect(no_drop)]
pub struct AvmString<'gc> {
source: Source<'gc>,
}
impl<'gc> AvmString<'gc> {
pub fn new_utf8<'s, S: Into<Cow<'s, str>>>(
gc_context: MutationContext<'gc, '_>,
string: S,
) -> Self {
let buf = match string.into() {
Cow::Owned(utf8) => WString::from_utf8_owned(utf8),
Cow::Borrowed(utf8) => WString::from_utf8(utf8),
};
Self {
source: Source::Owned(Gc::allocate(gc_context, OwnedWStr(buf))),
}
}
pub fn new_utf8_bytes<'b, B: Into<Cow<'b, [u8]>>>(
gc_context: MutationContext<'gc, '_>,
bytes: B,
) -> Result<Self, std::str::Utf8Error> {
let utf8 = match bytes.into() {
Cow::Owned(b) => Cow::Owned(String::from_utf8(b).map_err(|e| e.utf8_error())?),
Cow::Borrowed(b) => Cow::Borrowed(std::str::from_utf8(b)?),
};
Ok(Self::new_utf8(gc_context, utf8))
}
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,
Source::Static(s) => s,
}
}
pub fn concat(
gc_context: MutationContext<'gc, '_>,
left: AvmString<'gc>,
right: AvmString<'gc>,
) -> AvmString<'gc> {
if left.is_empty() {
right
} else if right.is_empty() {
left
} else {
let mut out = WString::from(left.as_wstr());
out.push_str(&right);
Self::new(gc_context, out)
}
}
#[inline]
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
match (this.source, other.source) {
(Source::Owned(this), Source::Owned(other)) => Gc::ptr_eq(this, other),
(Source::Static(this), Source::Static(other)) => std::ptr::eq(this, other),
_ => false,
}
}
}
impl Default for AvmString<'_> {
fn default() -> Self {
Self {
source: Source::Static(WStr::empty()),
}
}
}
impl<'gc> From<&'static str> for AvmString<'gc> {
#[inline]
fn from(str: &'static str) -> Self {
// TODO(moulins): actually check that `str` is valid ASCII.
Self {
source: Source::Static(WStr::from_units(str.as_bytes())),
}
}
}
impl<'gc> From<&'static WStr> for AvmString<'gc> {
#[inline]
fn from(str: &'static WStr) -> Self {
Self {
source: Source::Static(str),
}
}
}
impl<'gc> Deref for AvmString<'gc> {
type Target = WStr;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_wstr()
}
}
wstr_impl_traits!(impl['gc] for AvmString<'gc>);

View File

@ -6,4 +6,3 @@ authors = ["Arthur Heuillard <arthur.heuillard<orange.fr>"]
license = "MIT OR Apache-2.0"
[dependencies]
gc-arena = { git = "https://github.com/ruffle-rs/gc-arena" }

View File

@ -1,120 +0,0 @@
use std::ops::Deref;
use gc_arena::{Collect, Gc, MutationContext};
use std::borrow::Cow;
use super::{WStr, WString};
#[derive(Clone, Copy, Collect)]
#[collect(no_drop)]
enum Source<'gc> {
Owned(Gc<'gc, WString>),
Static(&'static WStr),
}
#[derive(Clone, Copy, Collect)]
#[collect(no_drop)]
pub struct AvmString<'gc> {
source: Source<'gc>,
}
impl<'gc> AvmString<'gc> {
pub fn new_utf8<'s, S: Into<Cow<'s, str>>>(
gc_context: MutationContext<'gc, '_>,
string: S,
) -> Self {
let buf = match string.into() {
Cow::Owned(utf8) => WString::from_utf8_owned(utf8),
Cow::Borrowed(utf8) => WString::from_utf8(utf8),
};
Self {
source: Source::Owned(Gc::allocate(gc_context, buf)),
}
}
pub fn new_utf8_bytes<'b, B: Into<Cow<'b, [u8]>>>(
gc_context: MutationContext<'gc, '_>,
bytes: B,
) -> Result<Self, std::str::Utf8Error> {
let utf8 = match bytes.into() {
Cow::Owned(b) => Cow::Owned(String::from_utf8(b).map_err(|e| e.utf8_error())?),
Cow::Borrowed(b) => Cow::Borrowed(std::str::from_utf8(b)?),
};
Ok(Self::new_utf8(gc_context, utf8))
}
pub fn new<S: Into<WString>>(gc_context: MutationContext<'gc, '_>, string: S) -> Self {
Self {
source: Source::Owned(Gc::allocate(gc_context, string.into())),
}
}
pub fn as_wstr(&self) -> &WStr {
match &self.source {
Source::Owned(s) => s,
Source::Static(s) => s,
}
}
pub fn concat(
gc_context: MutationContext<'gc, '_>,
left: AvmString<'gc>,
right: AvmString<'gc>,
) -> AvmString<'gc> {
if left.is_empty() {
right
} else if right.is_empty() {
left
} else {
let mut out = WString::from(left.as_wstr());
out.push_str(&right);
Self::new(gc_context, out)
}
}
#[inline]
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
match (this.source, other.source) {
(Source::Owned(this), Source::Owned(other)) => Gc::ptr_eq(this, other),
(Source::Static(this), Source::Static(other)) => std::ptr::eq(this, other),
_ => false,
}
}
}
impl Default for AvmString<'_> {
fn default() -> Self {
Self {
source: Source::Static(WStr::empty()),
}
}
}
impl<'gc> From<&'static str> for AvmString<'gc> {
#[inline]
fn from(str: &'static str) -> Self {
// TODO(moulins): actually check that `str` is valid ASCII.
Self {
source: Source::Static(WStr::from_units(str.as_bytes())),
}
}
}
impl<'gc> From<&'static WStr> for AvmString<'gc> {
#[inline]
fn from(str: &'static WStr) -> Self {
Self {
source: Source::Static(str),
}
}
}
impl<'gc> Deref for AvmString<'gc> {
type Target = WStr;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_wstr()
}
}
wstr_impl_traits!(impl['gc] for AvmString<'gc>);

View File

@ -2,14 +2,10 @@ use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use gc_arena::Collect;
use super::utils::split_ascii_prefix;
use super::{Units, WStr, MAX_STRING_LEN};
/// An owned, extensible UCS2 string, analoguous to `String`.
#[derive(Collect)]
#[collect(require_static)]
pub struct WString {
// TODO: better packing on 64bit targets
//

View File

@ -9,7 +9,6 @@
#[macro_use]
mod common;
mod avm;
mod buf;
mod ops;
mod parse;
@ -21,7 +20,6 @@ pub mod utils;
#[cfg(test)]
mod tests;
pub use avm::AvmString;
pub use buf::WString;
pub use common::Units;
pub use ops::{CharIndices, Chars, Iter, Split, WStrToUtf8};

View File

@ -1,8 +1,6 @@
use std::ops::Range;
use std::ptr::slice_from_raw_parts_mut;
use gc_arena::Collect;
use super::Units;
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
@ -13,8 +11,6 @@ pub const MAX_STRING_LEN: usize = 0x7FFF_FFFF;
const WIDE_MASK: usize = MAX_STRING_LEN + 1;
/// A UCS2 string slice, analoguous to `&'a str`.
#[derive(Collect)]
#[collect(require_static)]
#[repr(transparent)]
pub struct WStr {
/// The internal `WStr` representation.