Add Atom::to_ascii_lowercase
authorSimon Sapin <simon.sapin@exyr.org>
Thu, 08 Jun 2017 13:44:25 +0200
changeset 1152263 db423dda721f960e8089c37a37f7976a272478da
parent 1152262 634b361b1b9db2b26d64a5944c7ebaa88fd5991a
child 1152264 845a69f84eabb8b9ebb81de25008b96d4cfc184e
push id196469
push usersimon.sapin@exyr.org
push dateThu, 08 Jun 2017 13:30:23 +0000
treeherdertry@9bd0e6e32446 [default view] [failures only]
milestone55.0a1
Add Atom::to_ascii_lowercase
servo/Cargo.lock
servo/components/style/gecko_string_cache/mod.rs
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -1624,17 +1624,17 @@ name = "markup5ever"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tendril 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "matches"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2698,17 +2698,17 @@ dependencies = [
  "nodrop 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "servo_atoms"
 version = "0.0.1"
 dependencies = [
- "string_cache 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "servo_config"
 version = "0.0.1"
 dependencies = [
  "android_injected_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2847,17 +2847,17 @@ name = "smallvec"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "string_cache"
-version = "0.5.1"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3733,17 +3733,17 @@ dependencies = [
 "checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d"
 "checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5"
 "checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>"
 "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
 "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
 "checksum skeptic 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7d8dc1315094150052d0ab767840376335a98ac66ef313ff911cdf439a5b69"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"
-"checksum string_cache 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c77392ab481a7b315078ae0cbfd827c7fcd7b0840235f0f9c24d8c7443593b5"
+"checksum string_cache 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c8ba7515dd502b75080d989b819d31fb72686a82320d8006f665003c42ef79"
 "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum swapper 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca610b32bb8bfc5e7f705480c3a1edfeb70b6582495d343872c8bee0dcf758c"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
 "checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
 "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e"
--- a/servo/components/style/gecko_string_cache/mod.rs
+++ b/servo/components/style/gecko_string_cache/mod.rs
@@ -6,17 +6,17 @@
 
 //! A drop-in replacement for string_cache, but backed by Gecko `nsIAtom`s.
 
 use gecko_bindings::bindings::Gecko_AddRefAtom;
 use gecko_bindings::bindings::Gecko_Atomize;
 use gecko_bindings::bindings::Gecko_Atomize16;
 use gecko_bindings::bindings::Gecko_ReleaseAtom;
 use gecko_bindings::structs::nsIAtom;
-use nsstring::nsAString;
+use nsstring::{nsAString, nsString};
 use precomputed_hash::PrecomputedHash;
 use std::ascii::AsciiExt;
 use std::borrow::{Cow, Borrow};
 use std::char::{self, DecodeUtf16};
 use std::fmt::{self, Write};
 use std::hash::{Hash, Hasher};
 use std::iter::Cloned;
 use std::mem;
@@ -174,16 +174,41 @@ impl WeakAtom {
     }
 
     /// Returns the atom as a mutable pointer.
     #[inline]
     pub fn as_ptr(&self) -> *mut nsIAtom {
         let const_ptr: *const nsIAtom = &self.0;
         const_ptr as *mut nsIAtom
     }
+
+    /// Convert this atom to ASCII lower-case
+    pub fn to_ascii_lowercase(&self) -> Atom {
+        let slice = self.as_slice();
+        match slice.iter().position(|&char16| (b'A' as u16) <= char16 && char16 <= (b'Z' as u16)) {
+            None => self.clone(),
+            Some(i) => {
+                let mut buffer: [u16; 64] = unsafe { mem::uninitialized() };
+                let mut vec;
+                let mutable_slice = if let Some(buffer_prefix) = buffer.get_mut(..slice.len()) {
+                    buffer_prefix.copy_from_slice(slice);
+                    buffer_prefix
+                } else {
+                    vec = slice.to_vec();
+                    &mut vec
+                };
+                for char16 in &mut mutable_slice[i..] {
+                    if *char16 <= 0x7F {
+                        *char16 = (*char16 as u8).to_ascii_lowercase() as u16
+                    }
+                }
+                Atom::from(&*mutable_slice)
+            }
+        }
+    }
 }
 
 impl fmt::Debug for WeakAtom {
     fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
         write!(w, "Gecko WeakAtom({:p}, {})", self, self)
     }
 }
 
@@ -319,16 +344,23 @@ impl<'a> From<&'a str> for Atom {
         unsafe {
             Atom(WeakAtom::new(
                 Gecko_Atomize(string.as_ptr() as *const _, string.len() as u32)
             ))
         }
     }
 }
 
+impl<'a> From<&'a [u16]> for Atom {
+    #[inline]
+    fn from(slice: &[u16]) -> Atom {
+        Atom::from(&*nsString::from(slice))
+    }
+}
+
 impl<'a> From<&'a nsAString> for Atom {
     #[inline]
     fn from(string: &nsAString) -> Atom {
         unsafe {
             Atom(WeakAtom::new(
                 Gecko_Atomize16(string)
             ))
         }