/* -*- Mode: rust; rust-indent-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
externcrate url; use url::quirks; use url::{ParseOptions, Position, Url};
externcrate nsstring; use nsstring::{nsACString, nsCString};
externcrate nserror; use nserror::*;
externcrate xpcom; use xpcom::{AtomicRefcnt, RefCounted, RefPtr};
externcrate uuid; use uuid::Uuid;
use std::fmt::Write; use std::marker::PhantomData; use std::mem; use std::ops; use std::ptr; use std::str;
/// A slice into the backing string. This type is only valid as long as the /// MozURL which it was pulled from is valid. In C++, this type implicitly /// converts to a nsDependentCString, and is an implementation detail. /// /// This type exists because, unlike &str, this type is safe to return over FFI. #[repr(C)] pubstruct SpecSlice<'a> {
data: *const u8,
len: u32,
_marker: PhantomData<&'a [u8]>,
}
/// The MozURL reference-counted threadsafe URL type. This type intentionally /// implements no XPCOM interfaces, and all method calls are non-virtual. #[repr(C)] pubstruct MozURL { pub url: Url,
refcnt: AtomicRefcnt,
}
impl MozURL { pubfn from_url(url: Url) -> RefPtr<MozURL> { // Actually allocate the URL on the heap. This is the only place we actually // create a MozURL, other than in clone(). unsafe {
RefPtr::from_raw(Box::into_raw(Box::new(MozURL {
url: url,
refcnt: AtomicRefcnt::new(),
})))
.unwrap()
}
}
}
#[no_mangle] pubunsafeextern"C"fn mozurl_release(url: &MozURL) { let rc = url.refcnt.dec(); if rc == 0 {
mem::drop(Box::from_raw(url as *const MozURL as *mut MozURL));
}
}
// xpcom::RefPtr support unsafeimpl RefCounted for MozURL { unsafefn addref(&self) {
mozurl_addref(self);
} unsafefn release(&self) {
mozurl_release(self);
}
}
// Allocate a new MozURL object with a RefCnt of 1, and store a pointer to it // into url. #[no_mangle] pubextern"C"fn mozurl_new(
result: &mut *const MozURL,
spec: &nsACString,
base: Option<&MozURL>,
) -> nsresult {
*result = ptr::null_mut();
let spec = try_or_malformed!(str::from_utf8(spec)); let url = iflet Some(base) = base {
try_or_malformed!(base.url.join(spec))
} else {
try_or_malformed!(parser().parse(spec))
};
MozURL::from_url(url).forget(result);
NS_OK
}
/// Allocate a new MozURL object which is a clone of the original, and store a /// pointer to it into newurl. #[no_mangle] pubextern"C"fn mozurl_clone(url: &MozURL, newurl: &mut *const MozURL) {
MozURL::from_url(url.url.clone()).forget(newurl);
}
#[no_mangle] pubextern"C"fn mozurl_origin(url: &MozURL, origin: &mut nsACString) { let origin_str = if !url.as_ref().starts_with("about:blank") {
get_origin(url)
} else {
None
};
let origin_str = origin_str.unwrap_or_else(|| { // nsIPrincipal stores the uuid, so the same uuid is returned everytime. // We can't do that for MozURL because it can be used across threads. // Storing uuid would mutate the object which would cause races between // threads.
format!("moz-nullprincipal:{{{}}}", Uuid::new_v4())
});
// NOTE: Try to re-use the allocation we got from rust-url, and transfer // ownership of the buffer to C++. letmut o = nsCString::from(origin_str);
origin.take_from(&mut o);
}
// Helper macro for debug asserting that we're the only reference to MozURL.
macro_rules! debug_assert_mut {
($e:expr) => {
debug_assert_eq!($e.refcnt.get(), 1, "Cannot mutate an aliased MozURL!");
};
}
if new_port > u16::MAX as i32 { return NS_ERROR_UNEXPECTED;
}
if url.cannot_be_a_base() { return NS_ERROR_MALFORMED_URI;
}
let port = match new_port {
new if new < 0 || u16::max_value() as i32 <= new => None,
new if Some(new as u16) == default_port(url.scheme()) => None,
new => Some(new as u16),
};
try_or_malformed!(url.set_port(port));
NS_OK
}
match (url1.path_segments(), url2.path_segments()) {
(Some(mut path1), Some(mut path2)) => { // Exhaust the part of the iterators that match whilelet (Some(ref p1), Some(ref p2)) = (path1.next(), path2.next()) { if p1 != p2 { break;
}
}
result.truncate(); for _ in path1 {
result.append("../");
} for p2 in path2 {
result.append(p2);
result.append("/");
}
}
_ => {
result.assign(url2.as_ref());
}
}
NS_OK
}
/// This type is used by nsStandardURL #[no_mangle] pubextern"C"fn rusturl_parse_ipv6addr(input: &nsACString, addr: &mut nsACString) -> nsresult { let ip6 = try_or_malformed!(str::from_utf8(input)); let host = try_or_malformed!(url::Host::parse(ip6)); let _ = write!(addr, "{}", host);
NS_OK
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.