Bug 1318428 - Use the nsstring bindings in rust-url-capi, r=valentin

This patch also drops the pretense that rust-url-capi will be used from
outside of c++, or that it will be used outside of mozilla-central,
removing the ifdef __cplusplus code, and including the C++ header
"nsString.h".

MozReview-Commit-ID: BULhHf3DObe
This commit is contained in:
Michael Layzell 2016-11-19 14:22:14 -05:00
Родитель ee4f8a4ff1
Коммит d50e9eed2b
7 изменённых файлов: 183 добавлений и 257 удалений

Просмотреть файл

@ -6,21 +6,6 @@
#error "Should be defined" #error "Should be defined"
#endif #endif
// the following two functions will be replaced with the Rust
// nsstring bindings
// allows Rust to resize a nsACString
extern "C" int32_t c_fn_set_size(void * container, size_t size)
{
((nsACString *) container)->SetLength(size);
return 0;
}
// allows Rust to access the backing buffer of an nsACString
extern "C" char * c_fn_get_buffer(void * container)
{
return ((nsACString *) container)->BeginWriting();
}
using namespace mozilla::ipc; using namespace mozilla::ipc;
namespace mozilla { namespace mozilla {
@ -74,7 +59,7 @@ RustURL::SetSpec(const nsACString & aSpec)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
rusturl* ptr = rusturl_new(aSpec.BeginReading(), aSpec.Length()); rusturl* ptr = rusturl_new(&aSpec);
if (!ptr) { if (!ptr) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -127,7 +112,7 @@ RustURL::SetScheme(const nsACString & aScheme)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_scheme(mURL.get(), aScheme.BeginReading(), aScheme.Length())); return static_cast<nsresult>(rusturl_set_scheme(mURL.get(), &aScheme));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -168,10 +153,10 @@ RustURL::SetUserPass(const nsACString & aUserPass)
pass = Substring(aUserPass, colonPos + 1, aUserPass.Length()); pass = Substring(aUserPass, colonPos + 1, aUserPass.Length());
} }
if (rusturl_set_username(mURL.get(), user.BeginReading(), user.Length()) != 0) { if (rusturl_set_username(mURL.get(), &user) != 0) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
return static_cast<nsresult>(rusturl_set_password(mURL.get(), pass.BeginReading(), pass.Length())); return static_cast<nsresult>(rusturl_set_password(mURL.get(), &pass));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -184,7 +169,7 @@ NS_IMETHODIMP
RustURL::SetUsername(const nsACString & aUsername) RustURL::SetUsername(const nsACString & aUsername)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_username(mURL.get(), aUsername.BeginReading(), aUsername.Length())); return static_cast<nsresult>(rusturl_set_username(mURL.get(), &aUsername));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -197,7 +182,7 @@ NS_IMETHODIMP
RustURL::SetPassword(const nsACString & aPassword) RustURL::SetPassword(const nsACString & aPassword)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_password(mURL.get(), aPassword.BeginReading(), aPassword.Length())); return static_cast<nsresult>(rusturl_set_password(mURL.get(), &aPassword));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -225,14 +210,14 @@ NS_IMETHODIMP
RustURL::SetHostPort(const nsACString & aHostPort) RustURL::SetHostPort(const nsACString & aHostPort)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_host_port(mURL.get(), aHostPort.BeginReading(), aHostPort.Length())); return static_cast<nsresult>(rusturl_set_host_port(mURL.get(), &aHostPort));
} }
NS_IMETHODIMP NS_IMETHODIMP
RustURL::SetHostAndPort(const nsACString & hostport) RustURL::SetHostAndPort(const nsACString & hostport)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_host_and_port(mURL.get(), hostport.BeginReading(), hostport.Length())); return static_cast<nsresult>(rusturl_set_host_and_port(mURL.get(), &hostport));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -257,7 +242,7 @@ NS_IMETHODIMP
RustURL::SetHost(const nsACString & aHost) RustURL::SetHost(const nsACString & aHost)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_host(mURL.get(), aHost.BeginReading(), aHost.Length())); return static_cast<nsresult>(rusturl_set_host(mURL.get(), &aHost));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -357,7 +342,7 @@ RustURL::Clone(nsIURI * *aRetVal)
NS_IMETHODIMP NS_IMETHODIMP
RustURL::Resolve(const nsACString & relativePath, nsACString & aRetVal) RustURL::Resolve(const nsACString & relativePath, nsACString & aRetVal)
{ {
return static_cast<nsresult>(rusturl_resolve(mURL.get(), relativePath.BeginReading(), relativePath.Length(), &aRetVal)); return static_cast<nsresult>(rusturl_resolve(mURL.get(), &relativePath, &aRetVal));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -395,7 +380,7 @@ NS_IMETHODIMP
RustURL::SetRef(const nsACString & aRef) RustURL::SetRef(const nsACString & aRef)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_fragment(mURL.get(), aRef.BeginReading(), aRef.Length())); return static_cast<nsresult>(rusturl_set_fragment(mURL.get(), &aRef));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -481,7 +466,7 @@ NS_IMETHODIMP
RustURL::SetFilePath(const nsACString & aFilePath) RustURL::SetFilePath(const nsACString & aFilePath)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_path(mURL.get(), aFilePath.BeginReading(), aFilePath.Length())); return static_cast<nsresult>(rusturl_set_path(mURL.get(), &aFilePath));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -494,7 +479,7 @@ NS_IMETHODIMP
RustURL::SetQuery(const nsACString & aQuery) RustURL::SetQuery(const nsACString & aQuery)
{ {
ENSURE_MUTABLE(); ENSURE_MUTABLE();
return static_cast<nsresult>(rusturl_set_query(mURL.get(), aQuery.BeginReading(), aQuery.Length())); return static_cast<nsresult>(rusturl_set_query(mURL.get(), &aQuery));
} }
NS_IMETHODIMP NS_IMETHODIMP

Просмотреть файл

@ -17,3 +17,4 @@ name = "rust_url_capi"
[dependencies] [dependencies]
libc = "0.2.0" libc = "0.2.0"
url = "1.2.1" url = "1.2.1"
nsstring = { path = "../../../xpcom/rust/nsstring" }

Просмотреть файл

@ -1,3 +1,4 @@
/* -*- Mode: rust; rust-indent-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
@ -5,19 +6,21 @@
extern crate url; extern crate url;
use url::{Url, ParseError, ParseOptions, Position}; use url::{Url, ParseError, ParseOptions, Position};
use url::quirks; use url::quirks;
extern crate libc; extern crate libc;
use libc::size_t; use libc::size_t;
extern crate nsstring;
use nsstring::nsACString;
use std::mem; use std::mem;
use std::str; use std::str;
use std::ptr;
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub type rusturl_ptr = *const libc::c_void; pub type rusturl_ptr = *const libc::c_void;
mod string_utils;
pub use string_utils::*;
mod error_mapping; mod error_mapping;
use error_mapping::*; use error_mapping::*;
@ -41,20 +44,16 @@ fn default_port(scheme: &str) -> Option<u32> {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_new(spec: *mut libc::c_char, len: size_t) -> rusturl_ptr { pub unsafe extern "C" fn rusturl_new(spec: &nsACString) -> rusturl_ptr {
let slice = std::slice::from_raw_parts(spec as *const libc::c_uchar, len as usize); let url_spec = match str::from_utf8(spec) {
let url_spec = match str::from_utf8(slice) {
Ok(spec) => spec, Ok(spec) => spec,
Err(_) => return 0 as rusturl_ptr Err(_) => return ptr::null(),
}; };
let url = match parser().parse(url_spec) { match parser().parse(url_spec) {
Ok(url) => url, Ok(url) => Box::into_raw(Box::new(url)) as rusturl_ptr,
Err(_) => return 0 as rusturl_ptr Err(_) => return ptr::null(),
}; }
let url = Box::new(url);
Box::into_raw(url) as rusturl_ptr
} }
#[no_mangle] #[no_mangle]
@ -67,59 +66,58 @@ pub unsafe extern "C" fn rusturl_free(urlptr: rusturl_ptr) {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_get_spec(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_get_spec(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url = &*(urlptr as *const Url);
cont.assign(url.as_ref());
NSError::OK.error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_scheme(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url: &Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
cont.assign(&url.to_string()) cont.assign(&url.scheme());
NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_get_scheme(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_get_username(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
cont.assign(&url.scheme())
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_username(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url: &Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
if url.cannot_be_a_base() { if url.cannot_be_a_base() {
cont.set_size(0) cont.assign("");
} else { } else {
cont.assign(url.username()) cont.assign(url.username());
} }
NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_get_password(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_get_password(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url: &Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
match url.password() { cont.assign(url.password().unwrap_or(""));
Some(p) => cont.assign(&p.to_string()), NSError::OK.error_code()
None => cont.set_size(0)
}
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_get_host(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_get_host(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url: &Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
match url.host() { cont.assign(url.host_str().unwrap_or(""));
Some(h) => cont.assign(&h.to_string()), NSError::OK.error_code()
None => cont.set_size(0)
}
} }
#[no_mangle] #[no_mangle]
@ -136,41 +134,39 @@ pub unsafe extern "C" fn rusturl_get_port(urlptr: rusturl_ptr) -> i32 {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_get_path(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_get_path(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url: &Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
if url.cannot_be_a_base() { if url.cannot_be_a_base() {
cont.set_size(0) cont.assign("");
} else { } else {
cont.assign(&url[Position::BeforePath..]) cont.assign(&url[Position::BeforePath..]);
} }
NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_get_query(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_get_query(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.query() {
Some(ref s) => cont.assign(s),
None => cont.set_size(0)
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_fragment(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url: &Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
match url.fragment() { cont.assign(url.query().unwrap_or(""));
Some(ref fragment) => cont.assign(fragment), NSError::OK.error_code()
None => cont.set_size(0) }
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_fragment(urlptr: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
} }
let url: &Url = mem::transmute(urlptr);
cont.assign(url.fragment().unwrap_or(""));
NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]
@ -180,23 +176,19 @@ pub unsafe extern "C" fn rusturl_has_fragment(urlptr: rusturl_ptr) -> i32 {
} }
let url: &Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
match url.fragment() { url.fragment().is_some() as i32
Some(_) => return 1,
None => return 0
}
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_scheme(urlptr: rusturl_ptr, scheme: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_scheme(urlptr: rusturl_ptr, scheme: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(scheme as *const libc::c_uchar, len as usize);
let scheme_ = match str::from_utf8(slice).ok() { let scheme_ = match str::from_utf8(scheme) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_protocol(url, scheme_).error_code() quirks::set_protocol(url, scheme_).error_code()
@ -204,97 +196,91 @@ pub unsafe extern "C" fn rusturl_set_scheme(urlptr: rusturl_ptr, scheme: *mut li
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_username(urlptr: rusturl_ptr, username: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_username(urlptr: rusturl_ptr, username: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(username as *const libc::c_uchar, len as usize);
let username_ = match str::from_utf8(slice).ok() { let username_ = match str::from_utf8(username) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_username(url, username_).error_code() quirks::set_username(url, username_).error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_password(urlptr: rusturl_ptr, password: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_password(urlptr: rusturl_ptr, password: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(password as *const libc::c_uchar, len as usize);
let password_ = match str::from_utf8(slice).ok() { let password_ = match str::from_utf8(password) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_password(url, password_).error_code() quirks::set_password(url, password_).error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_host_port(urlptr: rusturl_ptr, host_port: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_host_port(urlptr: rusturl_ptr, host_port: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(host_port as *const libc::c_uchar, len as usize);
let host_port_ = match str::from_utf8(slice).ok() { let host_port_ = match str::from_utf8(host_port) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_host(url, host_port_).error_code() quirks::set_host(url, host_port_).error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_host_and_port(urlptr: rusturl_ptr, host_and_port: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_host_and_port(urlptr: rusturl_ptr, host_and_port: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
url.set_port(None); let _ = url.set_port(None);
let slice = std::slice::from_raw_parts(host_and_port as *const libc::c_uchar, len as usize);
let host_and_port_ = match str::from_utf8(slice).ok() { let host_and_port_ = match str::from_utf8(host_and_port) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_host(url, host_and_port_).error_code() quirks::set_host(url, host_and_port_).error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_host(urlptr: rusturl_ptr, host: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_host(urlptr: rusturl_ptr, host: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(host as *const libc::c_uchar, len as usize);
let hostname = match str::from_utf8(slice).ok() { let hostname = match str::from_utf8(host) {
Some(h) => h, Ok(h) => h,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_hostname(url, hostname).error_code() quirks::set_hostname(url, hostname).error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_port(urlptr: rusturl_ptr, port: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_port(urlptr: rusturl_ptr, port: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(port as *const libc::c_uchar, len as usize);
let port_ = match str::from_utf8(slice).ok() { let port_ = match str::from_utf8(port) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_port(url, port_).error_code() quirks::set_port(url, port_).error_code()
@ -329,34 +315,31 @@ pub unsafe extern "C" fn rusturl_set_port_no(urlptr: rusturl_ptr, new_port: i32)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_path(urlptr: rusturl_ptr, path: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_path(urlptr: rusturl_ptr, path: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(path as *const libc::c_uchar, len as usize);
let path_ = match str::from_utf8(slice).ok() { let path_ = match str::from_utf8(path) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_pathname(url, path_); quirks::set_pathname(url, path_);
NSError::OK.error_code() NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_query(urlptr: rusturl_ptr, query: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_query(urlptr: rusturl_ptr, query: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(query as *const libc::c_uchar, len as usize);
let query_ = match str::from_utf8(slice).ok() { let query_ = match str::from_utf8(query) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_search(url, query_); quirks::set_search(url, query_);
@ -364,16 +347,15 @@ pub unsafe extern "C" fn rusturl_set_query(urlptr: rusturl_ptr, query: *mut libc
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_set_fragment(urlptr: rusturl_ptr, fragment: *mut libc::c_char, len: size_t) -> i32 { pub unsafe extern "C" fn rusturl_set_fragment(urlptr: rusturl_ptr, fragment: &nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let mut url: &mut Url = mem::transmute(urlptr); let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(fragment as *const libc::c_uchar, len as usize);
let fragment_ = match str::from_utf8(slice).ok() { let fragment_ = match str::from_utf8(fragment) {
Some(p) => p, Ok(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
}; };
quirks::set_hash(url, fragment_); quirks::set_hash(url, fragment_);
@ -381,35 +363,38 @@ pub unsafe extern "C" fn rusturl_set_fragment(urlptr: rusturl_ptr, fragment: *mu
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_resolve(urlptr: rusturl_ptr, resolve: *mut libc::c_char, len: size_t, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_resolve(urlptr: rusturl_ptr, resolve: &nsACString, cont: &mut nsACString) -> i32 {
if urlptr.is_null() { if urlptr.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url: &mut Url = mem::transmute(urlptr); let url: &Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(resolve as *const libc::c_uchar, len as usize); let resolve_ = match str::from_utf8(resolve) {
Ok(p) => p,
let resolve_ = match str::from_utf8(slice).ok() { Err(_) => return NSError::Failure.error_code()
Some(p) => p,
None => return NSError::Failure.error_code()
}; };
match parser().base_url(Some(&url)).parse(resolve_).ok() { if let Ok(ref u) = parser().base_url(Some(&url)).parse(resolve_) {
Some(u) => cont.assign(&u.to_string()), cont.assign(u.as_ref());
None => cont.set_size(0) } else {
cont.assign("");
} }
NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_common_base_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_common_base_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr1.is_null() || urlptr2.is_null() { if urlptr1.is_null() || urlptr2.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url1: &Url = mem::transmute(urlptr1); let url1: &Url = mem::transmute(urlptr1);
let url2: &Url = mem::transmute(urlptr2); let url2: &Url = mem::transmute(urlptr2);
cont.assign("");
if url1 == url2 { if url1 == url2 {
return cont.assign(&url1.to_string()); cont.assign(url1.as_ref());
return NSError::OK.error_code();
} }
if url1.scheme() != url2.scheme() || if url1.scheme() != url2.scheme() ||
@ -417,16 +402,16 @@ pub unsafe extern "C" fn rusturl_common_base_spec(urlptr1: rusturl_ptr, urlptr2:
url1.username() != url2.username() || url1.username() != url2.username() ||
url1.password() != url2.password() || url1.password() != url2.password() ||
url1.port() != url2.port() { url1.port() != url2.port() {
return cont.set_size(0); return NSError::OK.error_code();
} }
let path1 = match url1.path_segments() { let path1 = match url1.path_segments() {
Some(path) => path, Some(path) => path,
None => return cont.set_size(0) None => return NSError::OK.error_code(),
}; };
let path2 = match url2.path_segments() { let path2 = match url2.path_segments() {
Some(path) => path, Some(path) => path,
None => return cont.set_size(0) None => return NSError::OK.error_code(),
}; };
let mut url = url1.clone(); let mut url = url1.clone();
@ -436,31 +421,34 @@ pub unsafe extern "C" fn rusturl_common_base_spec(urlptr1: rusturl_ptr, urlptr2:
let mut new_segments = if let Ok(segments) = url.path_segments_mut() { let mut new_segments = if let Ok(segments) = url.path_segments_mut() {
segments segments
} else { } else {
return cont.set_size(0) return NSError::OK.error_code();
}; };
for (p1, p2) in path1.zip(path2) { for (p1, p2) in path1.zip(path2) {
if p1 != p2 { if p1 != p2 {
break; break;
} else { } else {
new_segments.push(p1); new_segments.push(p1);
} }
} }
} }
cont.assign(&url.to_string()) cont.assign(url.as_ref());
NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn rusturl_relative_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: *mut libc::c_void) -> i32 { pub unsafe extern "C" fn rusturl_relative_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: &mut nsACString) -> i32 {
if urlptr1.is_null() || urlptr2.is_null() { if urlptr1.is_null() || urlptr2.is_null() {
return NSError::InvalidArg.error_code(); return NSError::InvalidArg.error_code();
} }
let url1: &Url = mem::transmute(urlptr1); let url1: &Url = mem::transmute(urlptr1);
let url2: &Url = mem::transmute(urlptr2); let url2: &Url = mem::transmute(urlptr2);
cont.assign("");
if url1 == url2 { if url1 == url2 {
return cont.set_size(0); return NSError::OK.error_code();
} }
if url1.scheme() != url2.scheme() || if url1.scheme() != url2.scheme() ||
@ -468,16 +456,23 @@ pub unsafe extern "C" fn rusturl_relative_spec(urlptr1: rusturl_ptr, urlptr2: ru
url1.username() != url2.username() || url1.username() != url2.username() ||
url1.password() != url2.password() || url1.password() != url2.password() ||
url1.port() != url2.port() { url1.port() != url2.port() {
return cont.assign(&url2.to_string()); cont.assign(url2.as_ref());
return NSError::OK.error_code();
} }
let mut path1 = match url1.path_segments() { let mut path1 = match url1.path_segments() {
Some(path) => path, Some(path) => path,
None => return cont.assign(&url2.to_string()) None => {
cont.assign(url2.as_ref());
return NSError::OK.error_code()
}
}; };
let mut path2 = match url2.path_segments() { let mut path2 = match url2.path_segments() {
Some(path) => path, Some(path) => path,
None => return cont.assign(&url2.to_string()) None => {
cont.assign(url2.as_ref());
return NSError::OK.error_code()
}
}; };
// TODO: file:// on WIN? // TODO: file:// on WIN?
@ -489,15 +484,17 @@ pub unsafe extern "C" fn rusturl_relative_spec(urlptr1: rusturl_ptr, urlptr2: ru
} }
} }
let mut buffer: String = "".to_string(); let mut buffer = String::new();
for _ in path1 { for _ in path1 {
buffer = buffer + "../"; buffer.push_str("../");
} }
for p2 in path2 { for p2 in path2 {
buffer = buffer + p2 + "/"; buffer.push_str(p2);
buffer.push('/');
} }
return cont.assign(&buffer); cont.assign(&buffer);
NSError::OK.error_code()
} }
#[no_mangle] #[no_mangle]

Просмотреть файл

@ -5,48 +5,50 @@
#ifndef __RUST_URL_CAPI #ifndef __RUST_URL_CAPI
#define __RUST_URL_CAPI #define __RUST_URL_CAPI
#include <stdlib.h> #include <stdlib.h>
#include "nsString.h"
#ifdef __cplusplus
extern "C" { extern "C" {
#endif
// NOTE: Preconditions
// * All nsACString* pointers are unchecked, and must be non-null
// * All rusturl_ptr pointers must refer to pointers which are returned
// by rusturl_new, and must be freed with rusturl_free.
struct rusturl; struct rusturl;
typedef struct rusturl* rusturl_ptr; typedef struct rusturl* rusturl_ptr;
rusturl_ptr rusturl_new(const char *spec, size_t src_len); rusturl_ptr rusturl_new(const nsACString* spec);
void rusturl_free(rusturl_ptr url); void rusturl_free(rusturl_ptr url);
int32_t rusturl_get_spec(rusturl_ptr url, void*); int32_t rusturl_get_spec(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_scheme(rusturl_ptr url, void*); int32_t rusturl_get_scheme(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_username(rusturl_ptr url, void*); int32_t rusturl_get_username(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_password(rusturl_ptr url, void*); int32_t rusturl_get_password(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_host(rusturl_ptr url, void*); int32_t rusturl_get_host(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_port(rusturl_ptr url); // returns port or -1 int32_t rusturl_get_port(const rusturl_ptr url); // returns port or -1
int32_t rusturl_get_path(rusturl_ptr url, void*); int32_t rusturl_get_path(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_query(rusturl_ptr url, void*); int32_t rusturl_get_query(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_fragment(rusturl_ptr url, void*); int32_t rusturl_get_fragment(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_has_fragment(rusturl_ptr url); // 1 true, 0 false, < 0 error int32_t rusturl_has_fragment(const rusturl_ptr url); // 1 true, 0 false, < 0 error
int32_t rusturl_set_scheme(rusturl_ptr url, const char *scheme, size_t len); int32_t rusturl_set_scheme(rusturl_ptr url, const nsACString* scheme);
int32_t rusturl_set_username(rusturl_ptr url, const char *user, size_t len); int32_t rusturl_set_username(rusturl_ptr url, const nsACString* user);
int32_t rusturl_set_password(rusturl_ptr url, const char *pass, size_t len); int32_t rusturl_set_password(rusturl_ptr url, const nsACString* password);
int32_t rusturl_set_host_port(rusturl_ptr url, const char *hostport, size_t len); int32_t rusturl_set_host_port(rusturl_ptr url, const nsACString* hostport);
int32_t rusturl_set_host_and_port(rusturl_ptr url, const char *hostport, size_t len); int32_t rusturl_set_host_and_port(rusturl_ptr url, const nsACString* hostport);
int32_t rusturl_set_host(rusturl_ptr url, const char *host, size_t len); int32_t rusturl_set_host(rusturl_ptr url, const nsACString* host);
int32_t rusturl_set_port(rusturl_ptr url, const char *port, size_t len); int32_t rusturl_set_port(rusturl_ptr url, const nsACString* port);
int32_t rusturl_set_port_no(rusturl_ptr url, const int32_t port); int32_t rusturl_set_port_no(rusturl_ptr url, const int32_t port);
int32_t rusturl_set_path(rusturl_ptr url, const char *path, size_t len); int32_t rusturl_set_path(rusturl_ptr url, const nsACString* path);
int32_t rusturl_set_query(rusturl_ptr url, const char *path, size_t len); int32_t rusturl_set_query(rusturl_ptr url, const nsACString* query);
int32_t rusturl_set_fragment(rusturl_ptr url, const char *path, size_t len); int32_t rusturl_set_fragment(rusturl_ptr url, const nsACString* fragment);
int32_t rusturl_resolve(rusturl_ptr url, const char *relative, size_t len, void*); int32_t rusturl_resolve(const rusturl_ptr url, const nsACString* relative, nsACString* cont);
int32_t rusturl_common_base_spec(rusturl_ptr url1, rusturl_ptr url2, void*); int32_t rusturl_common_base_spec(const rusturl_ptr url1, const rusturl_ptr url2, nsACString* cont);
int32_t rusturl_relative_spec(rusturl_ptr url1, rusturl_ptr url2, void*); int32_t rusturl_relative_spec(const rusturl_ptr url1, const rusturl_ptr url2, nsACString* cont);
size_t sizeof_rusturl(); size_t sizeof_rusturl();
#ifdef __cplusplus
} }
#endif
#endif // __RUST_URL_CAPI #endif // __RUST_URL_CAPI

Просмотреть файл

@ -1,61 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
extern crate libc;
use libc::size_t;
extern crate std;
use std::ptr;
use error_mapping::*;
extern "C" {
fn c_fn_set_size(user: *mut libc::c_void, size: size_t) -> i32;
fn c_fn_get_buffer(user: *mut libc::c_void) -> *mut libc::c_char;
}
pub trait StringContainer {
fn set_size(&self, size_t) -> i32;
fn get_buffer(&self) -> *mut libc::c_char;
fn assign(&self, content: &str) -> i32;
}
impl StringContainer for *mut libc::c_void {
fn set_size(&self, size: size_t) -> i32 {
if (*self).is_null() {
return NSError::InvalidArg.error_code();
}
unsafe {
c_fn_set_size(*self, size);
}
return NSError::OK.error_code();
}
fn get_buffer(&self) -> *mut libc::c_char {
if (*self).is_null() {
return 0 as *mut libc::c_char;
}
unsafe {
c_fn_get_buffer(*self)
}
}
fn assign(&self, content: &str) -> i32 {
if (*self).is_null() {
return NSError::InvalidArg.error_code();
}
unsafe {
let slice = content.as_bytes();
c_fn_set_size(*self, slice.len());
let buf = c_fn_get_buffer(*self);
if buf.is_null() {
return NSError::Failure.error_code();
}
ptr::copy(slice.as_ptr(), buf as *mut u8, slice.len());
}
NSError::OK.error_code()
}
}

1
toolkit/library/gtest/rust/Cargo.lock сгенерированный
Просмотреть файл

@ -76,6 +76,7 @@ name = "rust_url_capi"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"nsstring 0.1.0",
"url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

1
toolkit/library/rust/Cargo.lock сгенерированный
Просмотреть файл

@ -63,6 +63,7 @@ name = "rust_url_capi"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"nsstring 0.1.0",
"url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]