mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Update version of nsstring bindings used by stylo
This commit is contained in:
parent
4450bbdb0c
commit
cc8b69bae1
3 changed files with 385 additions and 113 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -2045,6 +2045,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "nsstring_vendor"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
|
|
|
@ -9,6 +9,7 @@ description = "Rust bindings to xpcom string types"
|
|||
# Revendoring nsstring from m-c into Servo
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.8"
|
||||
|
||||
[features]
|
||||
gecko_debug = []
|
||||
|
|
|
@ -9,12 +9,18 @@
|
|||
//! Use `&{mut,} nsA[C]String` for functions in rust which wish to take or
|
||||
//! mutate XPCOM strings. The other string types `Deref` to this type.
|
||||
//!
|
||||
//! Use `ns[C]String<'a>` (`ns[C]String` in C++) for string struct members, and
|
||||
//! as an intermediate between rust string data structures (such as `String`,
|
||||
//! `Vec<u16>`, `&str`, and `&[u16]`) and `&{mut,} nsA[C]String` (using
|
||||
//! `ns[C]String::from(value)`). These conversions, when possible, will not
|
||||
//! perform any allocations. When using this type in structs shared with C++,
|
||||
//! the correct lifetime argument is usually `'static`.
|
||||
//! Use `ns[C]String` (`ns[C]String` in C++) for string struct members, and as
|
||||
//! an intermediate between rust string data structures (such as `String` or
|
||||
//! `Vec<u16>`) and `&{mut,} nsA[C]String` (using `ns[C]String::from(value)`).
|
||||
//! These conversions will attempt to re-use the passed-in buffer, appending a
|
||||
//! null.
|
||||
//!
|
||||
//! Use `ns[C]Str` (`nsDependent[C]String` in C++) as an intermediate between
|
||||
//! borrowed rust data structures (such as `&str` and `&[u16]`) and `&{mut,}
|
||||
//! nsA[C]String` (using `ns[C]Str::from(value)`). These conversions should not
|
||||
//! perform any allocations. This type is not safe to share with `C++` as a
|
||||
//! struct field, but passing the borrowed `&{mut,} nsA[C]String` over FFI is
|
||||
//! safe.
|
||||
//!
|
||||
//! Use `nsFixed[C]String` or `ns_auto_[c]string!` for dynamic stack allocated
|
||||
//! strings which are expected to hold short string values.
|
||||
|
@ -52,7 +58,7 @@
|
|||
//! with the methods `.append`, `.append_utf{8,16}`, and with the `write!`
|
||||
//! macro, and can be assigned to with `.assign`.
|
||||
//!
|
||||
//! ## `ns[C]String<'a>`
|
||||
//! ## `ns[C]Str<'a>`
|
||||
//!
|
||||
//! This type is an maybe-owned string type. It acts similarially to a
|
||||
//! `Cow<[{u8,u16}]>`. This type provides `Deref` and `DerefMut` implementations
|
||||
|
@ -61,20 +67,36 @@
|
|||
//! storage. When modified this type may re-allocate in order to ensure that it
|
||||
//! does not mutate its backing storage.
|
||||
//!
|
||||
//! `ns[C]String`s can be constructed either with `ns[C]String::new()`, which
|
||||
//! creates an empty `ns[C]String<'static>`, or through one of the provided
|
||||
//! `From` implementations. Both string types may be constructed `From<&'a
|
||||
//! str>`, with `nsCString` having a `'a` lifetime, as the storage is shared
|
||||
//! with the `str`, while `nsString` has a `'static` lifetime, as its storage
|
||||
//! has to be transcoded.
|
||||
//! `ns[C]Str`s can be constructed either with `ns[C]Str::new()`, which creates
|
||||
//! an empty `ns[C]Str<'static>`, or through one of the provided `From`
|
||||
//! implementations. Only `nsCStr` can be constructed `From<'a str>`, as
|
||||
//! constructing a `nsStr` would require transcoding. Use `ns[C]String` instead.
|
||||
//!
|
||||
//! When passing this type by reference, prefer passing a `&nsA[C]String` or
|
||||
//! `&mut nsA[C]String`. to passing this type.
|
||||
//!
|
||||
//! When passing this type across the language boundary, pass it as `*const
|
||||
//! nsA[C]String` for an immutable reference, or `*mut nsA[C]String` for a
|
||||
//! mutable reference. This struct may also be included in `#[repr(C)]`
|
||||
//! structs shared with C++.
|
||||
//! mutable reference.
|
||||
//!
|
||||
//! ## `ns[C]String`
|
||||
//!
|
||||
//! This type is an owned, null-terminated string type. This type provides
|
||||
//! `Deref` and `DerefMut` implementations to `nsA[C]String`, which provides the
|
||||
//! methods for manipulating this type.
|
||||
//!
|
||||
//! `ns[C]String`s can be constructed either with `ns[C]String::new()`, which
|
||||
//! creates an empty `ns[C]String`, or through one of the provided `From`
|
||||
//! implementations, which will try to avoid reallocating when possible,
|
||||
//! although a terminating `null` will be added.
|
||||
//!
|
||||
//! When passing this type by reference, prefer passing a `&nsA[C]String` or
|
||||
//! `&mut nsA[C]String`. to passing this type.
|
||||
//!
|
||||
//! When passing this type across the language boundary, pass it as `*const
|
||||
//! nsA[C]String` for an immutable reference, or `*mut nsA[C]String` for a
|
||||
//! mutable reference. This struct may also be included in `#[repr(C)]` structs
|
||||
//! shared with C++.
|
||||
//!
|
||||
//! ## `nsFixed[C]String<'a>`
|
||||
//!
|
||||
|
@ -109,7 +131,7 @@
|
|||
//! ## `ns[C]StringRepr`
|
||||
//!
|
||||
//! This crate also provides the type `ns[C]StringRepr` which acts conceptually
|
||||
//! similar to an `ns[C]String<'static>`, however, it does not have a `Drop`
|
||||
//! similar to an `ns[C]String`, however, it does not have a `Drop`
|
||||
//! implementation.
|
||||
//!
|
||||
//! If this type is dropped in rust, it will not free its backing storage. This
|
||||
|
@ -119,11 +141,13 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
#![deny(warnings)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::marker::PhantomData;
|
||||
use std::borrow;
|
||||
use std::slice;
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::fmt;
|
||||
use std::cmp;
|
||||
|
@ -135,13 +159,36 @@ use std::os::raw::c_void;
|
|||
// Internal Implemenation Flags //
|
||||
//////////////////////////////////
|
||||
|
||||
const F_NONE: u32 = 0; // no flags
|
||||
mod data_flags {
|
||||
bitflags! {
|
||||
// While this has the same layout as u16, it cannot be passed
|
||||
// over FFI safely as a u16.
|
||||
#[repr(C)]
|
||||
pub flags DataFlags : u16 {
|
||||
const TERMINATED = 1 << 0, // IsTerminated returns true
|
||||
const VOIDED = 1 << 1, // IsVoid returns true
|
||||
const SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
|
||||
const OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
|
||||
const FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
|
||||
const LITERAL = 1 << 5, // mData points to a string literal; TERMINATED will also be set
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// data flags are in the lower 16-bits
|
||||
const F_OWNED: u32 = 1 << 3; // mData points to a heap-allocated, raw buffer
|
||||
mod class_flags {
|
||||
bitflags! {
|
||||
// While this has the same layout as u16, it cannot be passed
|
||||
// over FFI safely as a u16.
|
||||
#[repr(C)]
|
||||
pub flags ClassFlags : u16 {
|
||||
const FIXED = 1 << 0, // |this| is of type nsTFixedString
|
||||
const NULL_TERMINATED = 1 << 1, // |this| requires its buffer is null-terminated
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// class flags are in the upper 16-bits
|
||||
const F_CLASS_FIXED: u32 = 1 << 16; // indicates that |this| is of type nsTFixedString
|
||||
use data_flags::DataFlags;
|
||||
use class_flags::ClassFlags;
|
||||
|
||||
////////////////////////////////////
|
||||
// Generic String Bindings Macros //
|
||||
|
@ -153,6 +200,7 @@ macro_rules! define_string_types {
|
|||
|
||||
AString = $AString: ident;
|
||||
String = $String: ident;
|
||||
Str = $Str: ident;
|
||||
FixedString = $FixedString: ident;
|
||||
|
||||
StringLike = $StringLike: ident;
|
||||
|
@ -162,8 +210,10 @@ macro_rules! define_string_types {
|
|||
|
||||
drop = $drop: ident;
|
||||
assign = $assign: ident, $fallible_assign: ident;
|
||||
take_from = $take_from: ident, $fallible_take_from: ident;
|
||||
append = $append: ident, $fallible_append: ident;
|
||||
set_length = $set_length: ident, $fallible_set_length: ident;
|
||||
begin_writing = $begin_writing: ident, $fallible_begin_writing: ident;
|
||||
} => {
|
||||
/// The representation of a ns[C]String type in C++. This type is
|
||||
/// used internally by our definition of ns[C]String to ensure layout
|
||||
|
@ -180,7 +230,20 @@ macro_rules! define_string_types {
|
|||
pub struct $StringRepr {
|
||||
data: *const $char_t,
|
||||
length: u32,
|
||||
flags: u32,
|
||||
dataflags: DataFlags,
|
||||
classflags: ClassFlags,
|
||||
}
|
||||
|
||||
impl $StringRepr {
|
||||
fn new(classflags: ClassFlags) -> $StringRepr {
|
||||
static NUL: $char_t = 0;
|
||||
$StringRepr {
|
||||
data: &NUL,
|
||||
length: 0,
|
||||
dataflags: data_flags::TERMINATED | data_flags::LITERAL,
|
||||
classflags: classflags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for $StringRepr {
|
||||
|
@ -239,6 +302,25 @@ macro_rules! define_string_types {
|
|||
}
|
||||
}
|
||||
|
||||
/// Take the value of `other` and set `self`, overwriting any value
|
||||
/// currently stored. The passed-in string will be truncated.
|
||||
pub fn take_from(&mut self, other: &mut $AString) {
|
||||
unsafe { $take_from(self, other) };
|
||||
}
|
||||
|
||||
/// Take the value of `other` and set `self`, overwriting any value
|
||||
/// currently stored. If this function fails, the source string will
|
||||
/// be left untouched, otherwise it will be truncated.
|
||||
///
|
||||
/// Returns Ok(()) on success, and Err(()) if the allocation failed.
|
||||
pub fn fallible_take_from(&mut self, other: &mut $AString) -> Result<(), ()> {
|
||||
if unsafe { $fallible_take_from(self, other) } {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Append the value of `other` into self.
|
||||
pub fn append<T: $StringLike + ?Sized>(&mut self, other: &T) {
|
||||
unsafe { $append(self, other.adapt().as_ptr()) };
|
||||
|
@ -282,6 +364,45 @@ macro_rules! define_string_types {
|
|||
self.set_length(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a `&mut` reference to the backing data for this string.
|
||||
/// This method will allocate and copy if the current backing buffer
|
||||
/// is immutable or shared.
|
||||
pub fn to_mut(&mut self) -> &mut [$char_t] {
|
||||
unsafe {
|
||||
let len = self.len();
|
||||
if len == 0 {
|
||||
// Use an arbitrary non-null value as the pointer
|
||||
slice::from_raw_parts_mut(0x1 as *mut $char_t, 0)
|
||||
} else {
|
||||
slice::from_raw_parts_mut($begin_writing(self), len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a `&mut` reference to the backing data for this string.
|
||||
/// This method will allocate and copy if the current backing buffer
|
||||
/// is immutable or shared.
|
||||
///
|
||||
/// Returns `Ok(&mut [T])` on success, and `Err(())` if the
|
||||
/// allocation failed.
|
||||
pub fn fallible_to_mut(&mut self) -> Result<&mut [$char_t], ()> {
|
||||
unsafe {
|
||||
let len = self.len();
|
||||
if len == 0 {
|
||||
// Use an arbitrary non-null value as the pointer
|
||||
Ok(slice::from_raw_parts_mut(0x1 as *mut $char_t, 0))
|
||||
} else {
|
||||
let ptr = $fallible_begin_writing(self);
|
||||
if ptr.is_null() {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(slice::from_raw_parts_mut(ptr, len))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Deref for $AString {
|
||||
|
@ -322,8 +443,14 @@ macro_rules! define_string_types {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq<$String<'a>> for $AString {
|
||||
fn eq(&self, other: &$String<'a>) -> bool {
|
||||
impl cmp::PartialEq<$String> for $AString {
|
||||
fn eq(&self, other: &$String) -> bool {
|
||||
self.eq(&**other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq<$Str<'a>> for $AString {
|
||||
fn eq(&self, other: &$Str<'a>) -> bool {
|
||||
self.eq(&**other)
|
||||
}
|
||||
}
|
||||
|
@ -335,25 +462,21 @@ macro_rules! define_string_types {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct $String<'a> {
|
||||
pub struct $Str<'a> {
|
||||
hdr: $StringRepr,
|
||||
_marker: PhantomData<&'a [$char_t]>,
|
||||
}
|
||||
|
||||
impl $String<'static> {
|
||||
pub fn new() -> $String<'static> {
|
||||
$String {
|
||||
hdr: $StringRepr {
|
||||
data: ptr::null(),
|
||||
length: 0,
|
||||
flags: F_NONE,
|
||||
},
|
||||
impl $Str<'static> {
|
||||
pub fn new() -> $Str<'static> {
|
||||
$Str {
|
||||
hdr: $StringRepr::new(ClassFlags::empty()),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for $String<'a> {
|
||||
impl<'a> Drop for $Str<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
$drop(&mut **self);
|
||||
|
@ -361,64 +484,184 @@ macro_rules! define_string_types {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for $String<'a> {
|
||||
impl<'a> Deref for $Str<'a> {
|
||||
type Target = $AString;
|
||||
fn deref(&self) -> &$AString {
|
||||
&self.hdr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DerefMut for $String<'a> {
|
||||
impl<'a> DerefMut for $Str<'a> {
|
||||
fn deref_mut(&mut self) -> &mut $AString {
|
||||
&mut self.hdr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AsRef<[$char_t]> for $String<'a> {
|
||||
impl<'a> AsRef<[$char_t]> for $Str<'a> {
|
||||
fn as_ref(&self) -> &[$char_t] {
|
||||
&self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for $String<'a> {
|
||||
fn from(s: &'a String) -> $String<'a> {
|
||||
$String::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Vec<$char_t>> for $String<'a> {
|
||||
fn from(s: &'a Vec<$char_t>) -> $String<'a> {
|
||||
$String::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [$char_t]> for $String<'a> {
|
||||
fn from(s: &'a [$char_t]) -> $String<'a> {
|
||||
impl<'a> From<&'a [$char_t]> for $Str<'a> {
|
||||
fn from(s: &'a [$char_t]) -> $Str<'a> {
|
||||
assert!(s.len() < (u32::MAX as usize));
|
||||
$String {
|
||||
if s.is_empty() {
|
||||
return $Str::new();
|
||||
}
|
||||
$Str {
|
||||
hdr: $StringRepr {
|
||||
data: if s.is_empty() { ptr::null() } else { s.as_ptr() },
|
||||
data: s.as_ptr(),
|
||||
length: s.len() as u32,
|
||||
flags: F_NONE,
|
||||
dataflags: DataFlags::empty(),
|
||||
classflags: ClassFlags::empty(),
|
||||
},
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<[$char_t]>> for $String<'static> {
|
||||
fn from(s: Box<[$char_t]>) -> $String<'static> {
|
||||
impl<'a> From<&'a Vec<$char_t>> for $Str<'a> {
|
||||
fn from(s: &'a Vec<$char_t>) -> $Str<'a> {
|
||||
$Str::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a $AString> for $Str<'a> {
|
||||
fn from(s: &'a $AString) -> $Str<'a> {
|
||||
$Str::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Write for $Str<'a> {
|
||||
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
||||
$AString::write_str(self, s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for $Str<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
<$AString as fmt::Display>::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for $Str<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
<$AString as fmt::Debug>::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq for $Str<'a> {
|
||||
fn eq(&self, other: &$Str<'a>) -> bool {
|
||||
$AString::eq(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq<[$char_t]> for $Str<'a> {
|
||||
fn eq(&self, other: &[$char_t]) -> bool {
|
||||
$AString::eq(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> cmp::PartialEq<&'b [$char_t]> for $Str<'a> {
|
||||
fn eq(&self, other: &&'b [$char_t]) -> bool {
|
||||
$AString::eq(self, *other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq<str> for $Str<'a> {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
$AString::eq(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> cmp::PartialEq<&'b str> for $Str<'a> {
|
||||
fn eq(&self, other: &&'b str) -> bool {
|
||||
$AString::eq(self, *other)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct $String {
|
||||
hdr: $StringRepr,
|
||||
}
|
||||
|
||||
impl $String {
|
||||
pub fn new() -> $String {
|
||||
$String {
|
||||
hdr: $StringRepr::new(class_flags::NULL_TERMINATED),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for $String {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
$drop(&mut **self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for $String {
|
||||
type Target = $AString;
|
||||
fn deref(&self) -> &$AString {
|
||||
&self.hdr
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for $String {
|
||||
fn deref_mut(&mut self) -> &mut $AString {
|
||||
&mut self.hdr
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[$char_t]> for $String {
|
||||
fn as_ref(&self) -> &[$char_t] {
|
||||
&self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [$char_t]> for $String {
|
||||
fn from(s: &'a [$char_t]) -> $String {
|
||||
let mut res = $String::new();
|
||||
res.assign(&$Str::from(&s[..]));
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Vec<$char_t>> for $String {
|
||||
fn from(s: &'a Vec<$char_t>) -> $String {
|
||||
$String::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a $AString> for $String {
|
||||
fn from(s: &'a $AString) -> $String {
|
||||
$String::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<[$char_t]>> for $String {
|
||||
fn from(s: Box<[$char_t]>) -> $String {
|
||||
s.to_vec().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<$char_t>> for $String {
|
||||
fn from(mut s: Vec<$char_t>) -> $String {
|
||||
assert!(s.len() < (u32::MAX as usize));
|
||||
if s.is_empty() {
|
||||
return $String::new();
|
||||
}
|
||||
|
||||
// SAFETY NOTE: This method produces an F_OWNED ns[C]String from
|
||||
// a Box<[$char_t]>. this is only safe because in the Gecko
|
||||
// tree, we use the same allocator for Rust code as for C++
|
||||
// code, meaning that our box can be legally freed with
|
||||
// libc::free().
|
||||
let length = s.len() as u32;
|
||||
s.push(0); // null terminator
|
||||
|
||||
// SAFETY NOTE: This method produces an data_flags::OWNED
|
||||
// ns[C]String from a Box<[$char_t]>. this is only safe
|
||||
// because in the Gecko tree, we use the same allocator for
|
||||
// Rust code as for C++ code, meaning that our box can be
|
||||
// legally freed with libc::free().
|
||||
let ptr = s.as_ptr();
|
||||
mem::forget(s);
|
||||
unsafe {
|
||||
|
@ -428,71 +671,57 @@ macro_rules! define_string_types {
|
|||
hdr: $StringRepr {
|
||||
data: ptr,
|
||||
length: length,
|
||||
flags: F_OWNED,
|
||||
},
|
||||
_marker: PhantomData,
|
||||
dataflags: data_flags::OWNED | data_flags::TERMINATED,
|
||||
classflags: class_flags::NULL_TERMINATED,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<$char_t>> for $String<'static> {
|
||||
fn from(s: Vec<$char_t>) -> $String<'static> {
|
||||
s.into_boxed_slice().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a $AString> for $String<'static> {
|
||||
fn from(s: &'a $AString) -> $String<'static> {
|
||||
let mut string = $String::new();
|
||||
string.assign(s);
|
||||
string
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Write for $String<'a> {
|
||||
impl fmt::Write for $String {
|
||||
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
||||
$AString::write_str(self, s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for $String<'a> {
|
||||
impl fmt::Display for $String {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
<$AString as fmt::Display>::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for $String<'a> {
|
||||
impl fmt::Debug for $String {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
<$AString as fmt::Debug>::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq for $String<'a> {
|
||||
fn eq(&self, other: &$String<'a>) -> bool {
|
||||
impl cmp::PartialEq for $String {
|
||||
fn eq(&self, other: &$String) -> bool {
|
||||
$AString::eq(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq<[$char_t]> for $String<'a> {
|
||||
impl cmp::PartialEq<[$char_t]> for $String {
|
||||
fn eq(&self, other: &[$char_t]) -> bool {
|
||||
$AString::eq(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> cmp::PartialEq<&'b [$char_t]> for $String<'a> {
|
||||
fn eq(&self, other: &&'b [$char_t]) -> bool {
|
||||
impl<'a> cmp::PartialEq<&'a [$char_t]> for $String {
|
||||
fn eq(&self, other: &&'a [$char_t]) -> bool {
|
||||
$AString::eq(self, *other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> cmp::PartialEq<str> for $String<'a> {
|
||||
impl cmp::PartialEq<str> for $String {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
$AString::eq(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> cmp::PartialEq<&'b str> for $String<'a> {
|
||||
fn eq(&self, other: &&'b str) -> bool {
|
||||
impl<'a> cmp::PartialEq<&'a str> for $String {
|
||||
fn eq(&self, other: &&'a str) -> bool {
|
||||
$AString::eq(self, *other)
|
||||
}
|
||||
}
|
||||
|
@ -502,7 +731,7 @@ macro_rules! define_string_types {
|
|||
/// buffer, rather than using heap allocations.
|
||||
#[repr(C)]
|
||||
pub struct $FixedString<'a> {
|
||||
base: $String<'a>,
|
||||
base: $String,
|
||||
capacity: u32,
|
||||
buffer: *mut $char_t,
|
||||
_marker: PhantomData<&'a mut [$char_t]>,
|
||||
|
@ -515,12 +744,7 @@ macro_rules! define_string_types {
|
|||
let buf_ptr = buf.as_mut_ptr();
|
||||
$FixedString {
|
||||
base: $String {
|
||||
hdr: $StringRepr {
|
||||
data: ptr::null(),
|
||||
length: 0,
|
||||
flags: F_CLASS_FIXED,
|
||||
},
|
||||
_marker: PhantomData,
|
||||
hdr: $StringRepr::new(class_flags::FIXED | class_flags::NULL_TERMINATED),
|
||||
},
|
||||
capacity: len as u32,
|
||||
buffer: buf_ptr,
|
||||
|
@ -600,7 +824,7 @@ macro_rules! define_string_types {
|
|||
/// &[$char_type], and &$AString to a function, while still performing
|
||||
/// optimized operations when passed the $AString.
|
||||
pub enum $StringAdapter<'a> {
|
||||
Borrowed($String<'a>),
|
||||
Borrowed($Str<'a>),
|
||||
Abstract(&'a $AString),
|
||||
}
|
||||
|
||||
|
@ -653,7 +877,13 @@ macro_rules! define_string_types {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> $StringLike for $String<'a> {
|
||||
impl<'a> $StringLike for $Str<'a> {
|
||||
fn adapt(&self) -> $StringAdapter {
|
||||
$StringAdapter::Abstract(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl $StringLike for $String {
|
||||
fn adapt(&self) -> $StringAdapter {
|
||||
$StringAdapter::Abstract(self)
|
||||
}
|
||||
|
@ -667,19 +897,19 @@ macro_rules! define_string_types {
|
|||
|
||||
impl $StringLike for [$char_t] {
|
||||
fn adapt(&self) -> $StringAdapter {
|
||||
$StringAdapter::Borrowed($String::from(self))
|
||||
$StringAdapter::Borrowed($Str::from(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl $StringLike for Vec<$char_t> {
|
||||
fn adapt(&self) -> $StringAdapter {
|
||||
$StringAdapter::Borrowed($String::from(&self[..]))
|
||||
$StringAdapter::Borrowed($Str::from(&self[..]))
|
||||
}
|
||||
}
|
||||
|
||||
impl $StringLike for Box<[$char_t]> {
|
||||
fn adapt(&self) -> $StringAdapter {
|
||||
$StringAdapter::Borrowed($String::from(&self[..]))
|
||||
$StringAdapter::Borrowed($Str::from(&self[..]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -694,6 +924,7 @@ define_string_types! {
|
|||
|
||||
AString = nsACString;
|
||||
String = nsCString;
|
||||
Str = nsCStr;
|
||||
FixedString = nsFixedCString;
|
||||
|
||||
StringLike = nsCStringLike;
|
||||
|
@ -703,8 +934,10 @@ define_string_types! {
|
|||
|
||||
drop = Gecko_FinalizeCString;
|
||||
assign = Gecko_AssignCString, Gecko_FallibleAssignCString;
|
||||
take_from = Gecko_TakeFromCString, Gecko_FallibleTakeFromCString;
|
||||
append = Gecko_AppendCString, Gecko_FallibleAppendCString;
|
||||
set_length = Gecko_SetLengthCString, Gecko_FallibleSetLengthCString;
|
||||
begin_writing = Gecko_BeginWritingCString, Gecko_FallibleBeginWritingCString;
|
||||
}
|
||||
|
||||
impl nsACString {
|
||||
|
@ -737,20 +970,38 @@ impl nsACString {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for nsCString<'a> {
|
||||
fn from(s: &'a str) -> nsCString<'a> {
|
||||
impl<'a> From<&'a str> for nsCStr<'a> {
|
||||
fn from(s: &'a str) -> nsCStr<'a> {
|
||||
s.as_bytes().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for nsCString<'static> {
|
||||
fn from(s: Box<str>) -> nsCString<'static> {
|
||||
impl<'a> From<&'a String> for nsCStr<'a> {
|
||||
fn from(s: &'a String) -> nsCStr<'a> {
|
||||
nsCStr::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for nsCString {
|
||||
fn from(s: &'a str) -> nsCString {
|
||||
s.as_bytes().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for nsCString {
|
||||
fn from(s: &'a String) -> nsCString {
|
||||
nsCString::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for nsCString {
|
||||
fn from(s: Box<str>) -> nsCString {
|
||||
s.into_string().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for nsCString<'static> {
|
||||
fn from(s: String) -> nsCString<'static> {
|
||||
impl From<String> for nsCString {
|
||||
fn from(s: String) -> nsCString {
|
||||
s.into_bytes().into()
|
||||
}
|
||||
}
|
||||
|
@ -783,19 +1034,19 @@ impl cmp::PartialEq<str> for nsACString {
|
|||
|
||||
impl nsCStringLike for str {
|
||||
fn adapt(&self) -> nsCStringAdapter {
|
||||
nsCStringAdapter::Borrowed(nsCString::from(self))
|
||||
nsCStringAdapter::Borrowed(nsCStr::from(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl nsCStringLike for String {
|
||||
fn adapt(&self) -> nsCStringAdapter {
|
||||
nsCStringAdapter::Borrowed(nsCString::from(&self[..]))
|
||||
nsCStringAdapter::Borrowed(nsCStr::from(&self[..]))
|
||||
}
|
||||
}
|
||||
|
||||
impl nsCStringLike for Box<str> {
|
||||
fn adapt(&self) -> nsCStringAdapter {
|
||||
nsCStringAdapter::Borrowed(nsCString::from(&self[..]))
|
||||
nsCStringAdapter::Borrowed(nsCStr::from(&self[..]))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -816,6 +1067,7 @@ define_string_types! {
|
|||
|
||||
AString = nsAString;
|
||||
String = nsString;
|
||||
Str = nsStr;
|
||||
FixedString = nsFixedString;
|
||||
|
||||
StringLike = nsStringLike;
|
||||
|
@ -825,8 +1077,10 @@ define_string_types! {
|
|||
|
||||
drop = Gecko_FinalizeString;
|
||||
assign = Gecko_AssignString, Gecko_FallibleAssignString;
|
||||
take_from = Gecko_TakeFromString, Gecko_FallibleTakeFromString;
|
||||
append = Gecko_AppendString, Gecko_FallibleAppendString;
|
||||
set_length = Gecko_SetLengthString, Gecko_FallibleSetLengthString;
|
||||
begin_writing = Gecko_BeginWritingString, Gecko_FallibleBeginWritingString;
|
||||
}
|
||||
|
||||
impl nsAString {
|
||||
|
@ -857,12 +1111,18 @@ impl nsAString {
|
|||
|
||||
// NOTE: The From impl for a string slice for nsString produces a <'static>
|
||||
// lifetime, as it allocates.
|
||||
impl<'a> From<&'a str> for nsString<'static> {
|
||||
fn from(s: &'a str) -> nsString<'static> {
|
||||
impl<'a> From<&'a str> for nsString {
|
||||
fn from(s: &'a str) -> nsString {
|
||||
s.encode_utf16().collect::<Vec<u16>>().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for nsString {
|
||||
fn from(s: &'a String) -> nsString {
|
||||
nsString::from(&s[..])
|
||||
}
|
||||
}
|
||||
|
||||
// Support for the write!() macro for writing to nsStrings
|
||||
impl fmt::Write for nsAString {
|
||||
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
||||
|
@ -911,20 +1171,28 @@ extern "C" {
|
|||
fn Gecko_FinalizeCString(this: *mut nsACString);
|
||||
|
||||
fn Gecko_AssignCString(this: *mut nsACString, other: *const nsACString);
|
||||
fn Gecko_TakeFromCString(this: *mut nsACString, other: *mut nsACString);
|
||||
fn Gecko_AppendCString(this: *mut nsACString, other: *const nsACString);
|
||||
fn Gecko_SetLengthCString(this: *mut nsACString, length: u32);
|
||||
fn Gecko_BeginWritingCString(this: *mut nsACString) -> *mut u8;
|
||||
fn Gecko_FallibleAssignCString(this: *mut nsACString, other: *const nsACString) -> bool;
|
||||
fn Gecko_FallibleTakeFromCString(this: *mut nsACString, other: *mut nsACString) -> bool;
|
||||
fn Gecko_FallibleAppendCString(this: *mut nsACString, other: *const nsACString) -> bool;
|
||||
fn Gecko_FallibleSetLengthCString(this: *mut nsACString, length: u32) -> bool;
|
||||
fn Gecko_FallibleBeginWritingCString(this: *mut nsACString) -> *mut u8;
|
||||
|
||||
fn Gecko_FinalizeString(this: *mut nsAString);
|
||||
|
||||
fn Gecko_AssignString(this: *mut nsAString, other: *const nsAString);
|
||||
fn Gecko_TakeFromString(this: *mut nsAString, other: *mut nsAString);
|
||||
fn Gecko_AppendString(this: *mut nsAString, other: *const nsAString);
|
||||
fn Gecko_SetLengthString(this: *mut nsAString, length: u32);
|
||||
fn Gecko_BeginWritingString(this: *mut nsAString) -> *mut u16;
|
||||
fn Gecko_FallibleAssignString(this: *mut nsAString, other: *const nsAString) -> bool;
|
||||
fn Gecko_FallibleTakeFromString(this: *mut nsAString, other: *mut nsAString) -> bool;
|
||||
fn Gecko_FallibleAppendString(this: *mut nsAString, other: *const nsAString) -> bool;
|
||||
fn Gecko_FallibleSetLengthString(this: *mut nsAString, length: u32) -> bool;
|
||||
fn Gecko_FallibleBeginWritingString(this: *mut nsAString) -> *mut u16;
|
||||
|
||||
// Gecko implementation in nsReadableUtils.cpp
|
||||
fn Gecko_AppendUTF16toCString(this: *mut nsACString, other: *const nsAString);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue