style: Document gecko_string_cache.

This commit is contained in:
Emilio Cobos Álvarez 2017-01-02 04:58:35 +01:00
parent e9d3ac03a9
commit 2cebd3bc96
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
2 changed files with 30 additions and 2 deletions

View file

@ -4,6 +4,8 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
//! A drop-in replacement for string_cache, but backed by Gecko `nsIAtom`s.
use gecko_bindings::bindings::Gecko_AddRefAtom; use gecko_bindings::bindings::Gecko_AddRefAtom;
use gecko_bindings::bindings::Gecko_Atomize; use gecko_bindings::bindings::Gecko_Atomize;
use gecko_bindings::bindings::Gecko_ReleaseAtom; use gecko_bindings::bindings::Gecko_ReleaseAtom;
@ -19,7 +21,7 @@ use std::ops::Deref;
use std::slice; use std::slice;
#[macro_use] #[macro_use]
#[allow(improper_ctypes, non_camel_case_types)] #[allow(improper_ctypes, non_camel_case_types, missing_docs)]
pub mod atom_macro; pub mod atom_macro;
#[macro_use] #[macro_use]
pub mod namespace; pub mod namespace;
@ -40,6 +42,8 @@ pub struct Atom(*mut WeakAtom);
/// where `'a` is the lifetime of something that holds a strong reference to that atom. /// where `'a` is the lifetime of something that holds a strong reference to that atom.
pub struct WeakAtom(nsIAtom); pub struct WeakAtom(nsIAtom);
/// A BorrowedAtom for Gecko is just a weak reference to a `nsIAtom`, that
/// hasn't been bumped.
pub type BorrowedAtom<'a> = &'a WeakAtom; pub type BorrowedAtom<'a> = &'a WeakAtom;
impl Deref for Atom { impl Deref for Atom {
@ -75,21 +79,26 @@ unsafe impl Sync for Atom {}
unsafe impl Sync for WeakAtom {} unsafe impl Sync for WeakAtom {}
impl WeakAtom { impl WeakAtom {
/// Construct a `WeakAtom` from a raw `nsIAtom`.
#[inline] #[inline]
pub unsafe fn new<'a>(atom: *mut nsIAtom) -> &'a mut Self { pub unsafe fn new<'a>(atom: *mut nsIAtom) -> &'a mut Self {
&mut *(atom as *mut WeakAtom) &mut *(atom as *mut WeakAtom)
} }
/// Clone this atom, bumping the refcount if the atom is not static.
#[inline] #[inline]
pub fn clone(&self) -> Atom { pub fn clone(&self) -> Atom {
Atom::from(self.as_ptr()) Atom::from(self.as_ptr())
} }
/// Get the atom hash.
#[inline] #[inline]
pub fn get_hash(&self) -> u32 { pub fn get_hash(&self) -> u32 {
self.0.mHash self.0.mHash
} }
/// Get the atom as a slice of utf-16 chars.
#[inline]
pub fn as_slice(&self) -> &[u16] { pub fn as_slice(&self) -> &[u16] {
unsafe { unsafe {
slice::from_raw_parts((*self.as_ptr()).mString, self.len() as usize) slice::from_raw_parts((*self.as_ptr()).mString, self.len() as usize)
@ -101,20 +110,29 @@ impl WeakAtom {
char::decode_utf16(self.as_slice().iter().cloned()) char::decode_utf16(self.as_slice().iter().cloned())
} }
/// Execute `cb` with the string that this atom represents.
///
/// Find alternatives to this function when possible, please, since it's
/// pretty slow.
pub fn with_str<F, Output>(&self, cb: F) -> Output pub fn with_str<F, Output>(&self, cb: F) -> Output
where F: FnOnce(&str) -> Output where F: FnOnce(&str) -> Output
{ {
// FIXME(bholley): We should measure whether it makes more sense to // FIXME(bholley): We should measure whether it makes more sense to
// cache the UTF-8 version in the Gecko atom table somehow. // cache the UTF-8 version in the Gecko atom table somehow.
let owned = String::from_utf16(self.as_slice()).unwrap(); let owned = self.to_string();
cb(&owned) cb(&owned)
} }
/// Convert this Atom into a string, decoding the UTF-16 bytes.
///
/// Find alternatives to this function when possible, please, since it's
/// pretty slow.
#[inline] #[inline]
pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
String::from_utf16(self.as_slice()).unwrap() String::from_utf16(self.as_slice()).unwrap()
} }
/// Returns whether this atom is static.
#[inline] #[inline]
pub fn is_static(&self) -> bool { pub fn is_static(&self) -> bool {
unsafe { unsafe {
@ -122,6 +140,7 @@ impl WeakAtom {
} }
} }
/// Returns the length of the atom string.
#[inline] #[inline]
pub fn len(&self) -> u32 { pub fn len(&self) -> u32 {
unsafe { unsafe {
@ -129,6 +148,7 @@ impl WeakAtom {
} }
} }
/// Returns the atom as a mutable pointer.
#[inline] #[inline]
pub fn as_ptr(&self) -> *mut nsIAtom { pub fn as_ptr(&self) -> *mut nsIAtom {
let const_ptr: *const nsIAtom = &self.0; let const_ptr: *const nsIAtom = &self.0;
@ -152,6 +172,7 @@ impl fmt::Display for WeakAtom {
} }
impl Atom { impl Atom {
/// Execute a callback with the atom represented by `ptr`.
pub unsafe fn with<F>(ptr: *mut nsIAtom, callback: &mut F) where F: FnMut(&Atom) { pub unsafe fn with<F>(ptr: *mut nsIAtom, callback: &mut F) where F: FnMut(&Atom) {
let atom = Atom(WeakAtom::new(ptr)); let atom = Atom(WeakAtom::new(ptr));
callback(&atom); callback(&atom);

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! A type to represent a namespace.
use gecko_bindings::structs::nsIAtom; use gecko_bindings::structs::nsIAtom;
use std::borrow::{Borrow, Cow}; use std::borrow::{Borrow, Cow};
use std::fmt; use std::fmt;
@ -13,9 +15,11 @@ macro_rules! ns {
() => { $crate::string_cache::Namespace(atom!("")) } () => { $crate::string_cache::Namespace(atom!("")) }
} }
/// A Gecko namespace is just a wrapped atom.
#[derive(Debug, PartialEq, Eq, Clone, Default, Hash)] #[derive(Debug, PartialEq, Eq, Clone, Default, Hash)]
pub struct Namespace(pub Atom); pub struct Namespace(pub Atom);
/// A Gecko WeakNamespace is a wrapped WeakAtom.
#[derive(Hash)] #[derive(Hash)]
pub struct WeakNamespace(WeakAtom); pub struct WeakNamespace(WeakAtom);
@ -51,11 +55,14 @@ impl Borrow<WeakNamespace> for Namespace {
} }
impl WeakNamespace { impl WeakNamespace {
/// Trivially construct a WeakNamespace.
#[inline] #[inline]
pub unsafe fn new<'a>(atom: *mut nsIAtom) -> &'a Self { pub unsafe fn new<'a>(atom: *mut nsIAtom) -> &'a Self {
&*(atom as *const WeakNamespace) &*(atom as *const WeakNamespace)
} }
/// Clone this WeakNamespace to obtain a strong reference to the same
/// underlying namespace.
#[inline] #[inline]
pub fn clone(&self) -> Namespace { pub fn clone(&self) -> Namespace {
Namespace(self.0.clone()) Namespace(self.0.clone())