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
parent ee4f8a4ff1
commit d50e9eed2b
7 changed files with 183 additions and 257 deletions

View File

@ -6,21 +6,6 @@
#error "Should be defined"
#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;
namespace mozilla {
@ -74,7 +59,7 @@ RustURL::SetSpec(const nsACString & aSpec)
{
ENSURE_MUTABLE();
rusturl* ptr = rusturl_new(aSpec.BeginReading(), aSpec.Length());
rusturl* ptr = rusturl_new(&aSpec);
if (!ptr) {
return NS_ERROR_FAILURE;
}
@ -127,7 +112,7 @@ RustURL::SetScheme(const nsACString & aScheme)
{
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
@ -168,10 +153,10 @@ RustURL::SetUserPass(const nsACString & aUserPass)
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 static_cast<nsresult>(rusturl_set_password(mURL.get(), pass.BeginReading(), pass.Length()));
return static_cast<nsresult>(rusturl_set_password(mURL.get(), &pass));
}
NS_IMETHODIMP
@ -184,7 +169,7 @@ NS_IMETHODIMP
RustURL::SetUsername(const nsACString & aUsername)
{
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
@ -197,7 +182,7 @@ NS_IMETHODIMP
RustURL::SetPassword(const nsACString & aPassword)
{
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
@ -225,14 +210,14 @@ NS_IMETHODIMP
RustURL::SetHostPort(const nsACString & aHostPort)
{
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
RustURL::SetHostAndPort(const nsACString & hostport)
{
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
@ -257,7 +242,7 @@ NS_IMETHODIMP
RustURL::SetHost(const nsACString & aHost)
{
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
@ -357,7 +342,7 @@ RustURL::Clone(nsIURI * *aRetVal)
NS_IMETHODIMP
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
@ -395,7 +380,7 @@ NS_IMETHODIMP
RustURL::SetRef(const nsACString & aRef)
{
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
@ -481,7 +466,7 @@ NS_IMETHODIMP
RustURL::SetFilePath(const nsACString & aFilePath)
{
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
@ -494,7 +479,7 @@ NS_IMETHODIMP
RustURL::SetQuery(const nsACString & aQuery)
{
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

View File

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

View File

@ -1,3 +1,4 @@
/* -*- Mode: rust; rust-indent-offset: 2 -*- */
/* 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/. */
@ -5,19 +6,21 @@
extern crate url;
use url::{Url, ParseError, ParseOptions, Position};
use url::quirks;
extern crate libc;
use libc::size_t;
extern crate nsstring;
use nsstring::nsACString;
use std::mem;
use std::str;
use std::ptr;
#[allow(non_camel_case_types)]
pub type rusturl_ptr = *const libc::c_void;
mod string_utils;
pub use string_utils::*;
mod error_mapping;
use error_mapping::*;
@ -41,20 +44,16 @@ fn default_port(scheme: &str) -> Option<u32> {
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_new(spec: *mut libc::c_char, len: size_t) -> 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(slice) {
pub unsafe extern "C" fn rusturl_new(spec: &nsACString) -> rusturl_ptr {
let url_spec = match str::from_utf8(spec) {
Ok(spec) => spec,
Err(_) => return 0 as rusturl_ptr
Err(_) => return ptr::null(),
};
let url = match parser().parse(url_spec) {
Ok(url) => url,
Err(_) => return 0 as rusturl_ptr
};
let url = Box::new(url);
Box::into_raw(url) as rusturl_ptr
match parser().parse(url_spec) {
Ok(url) => Box::into_raw(Box::new(url)) as rusturl_ptr,
Err(_) => return ptr::null(),
}
}
#[no_mangle]
@ -67,59 +66,58 @@ pub unsafe extern "C" fn rusturl_free(urlptr: rusturl_ptr) {
}
#[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() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
cont.assign(&url.to_string())
cont.assign(&url.scheme());
NSError::OK.error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_scheme(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> 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 {
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);
if url.cannot_be_a_base() {
cont.set_size(0)
cont.assign("");
} else {
cont.assign(url.username())
cont.assign(url.username());
}
NSError::OK.error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.password() {
Some(p) => cont.assign(&p.to_string()),
None => cont.set_size(0)
}
cont.assign(url.password().unwrap_or(""));
NSError::OK.error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.host() {
Some(h) => cont.assign(&h.to_string()),
None => cont.set_size(0)
}
cont.assign(url.host_str().unwrap_or(""));
NSError::OK.error_code()
}
#[no_mangle]
@ -136,41 +134,39 @@ pub unsafe extern "C" fn rusturl_get_port(urlptr: rusturl_ptr) -> i32 {
}
#[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() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
if url.cannot_be_a_base() {
cont.set_size(0)
cont.assign("");
} else {
cont.assign(&url[Position::BeforePath..])
cont.assign(&url[Position::BeforePath..]);
}
NSError::OK.error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_query(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> 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 {
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.fragment() {
Some(ref fragment) => cont.assign(fragment),
None => cont.set_size(0)
cont.assign(url.query().unwrap_or(""));
NSError::OK.error_code()
}
#[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]
@ -180,23 +176,19 @@ pub unsafe extern "C" fn rusturl_has_fragment(urlptr: rusturl_ptr) -> i32 {
}
let url: &Url = mem::transmute(urlptr);
match url.fragment() {
Some(_) => return 1,
None => return 0
}
url.fragment().is_some() as i32
}
#[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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let scheme_ = match str::from_utf8(scheme) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
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]
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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let username_ = match str::from_utf8(username) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_username(url, username_).error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let password_ = match str::from_utf8(password) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_password(url, password_).error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let host_port_ = match str::from_utf8(host_port) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_host(url, host_port_).error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
url.set_port(None);
let slice = std::slice::from_raw_parts(host_and_port as *const libc::c_uchar, len as usize);
let _ = url.set_port(None);
let host_and_port_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let host_and_port_ = match str::from_utf8(host_and_port) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_host(url, host_and_port_).error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(h) => h,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let hostname = match str::from_utf8(host) {
Ok(h) => h,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_hostname(url, hostname).error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let port_ = match str::from_utf8(port) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
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]
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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let path_ = match str::from_utf8(path) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_pathname(url, path_);
NSError::OK.error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let query_ = match str::from_utf8(query) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
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]
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() {
return NSError::InvalidArg.error_code();
}
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() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
let fragment_ = match str::from_utf8(fragment) {
Ok(p) => p,
Err(_) => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_hash(url, fragment_);
@ -381,35 +363,38 @@ pub unsafe extern "C" fn rusturl_set_fragment(urlptr: rusturl_ptr, fragment: *mu
}
#[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() {
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(slice).ok() {
Some(p) => p,
None => return NSError::Failure.error_code()
let resolve_ = match str::from_utf8(resolve) {
Ok(p) => p,
Err(_) => return NSError::Failure.error_code()
};
match parser().base_url(Some(&url)).parse(resolve_).ok() {
Some(u) => cont.assign(&u.to_string()),
None => cont.set_size(0)
if let Ok(ref u) = parser().base_url(Some(&url)).parse(resolve_) {
cont.assign(u.as_ref());
} else {
cont.assign("");
}
NSError::OK.error_code()
}
#[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() {
return NSError::InvalidArg.error_code();
}
let url1: &Url = mem::transmute(urlptr1);
let url2: &Url = mem::transmute(urlptr2);
cont.assign("");
if url1 == url2 {
return cont.assign(&url1.to_string());
cont.assign(url1.as_ref());
return NSError::OK.error_code();
}
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.password() != url2.password() ||
url1.port() != url2.port() {
return cont.set_size(0);
return NSError::OK.error_code();
}
let path1 = match url1.path_segments() {
Some(path) => path,
None => return cont.set_size(0)
None => return NSError::OK.error_code(),
};
let path2 = match url2.path_segments() {
Some(path) => path,
None => return cont.set_size(0)
None => return NSError::OK.error_code(),
};
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() {
segments
} else {
return cont.set_size(0)
return NSError::OK.error_code();
};
for (p1, p2) in path1.zip(path2) {
if p1 != p2 {
break;
} 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]
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() {
return NSError::InvalidArg.error_code();
}
let url1: &Url = mem::transmute(urlptr1);
let url2: &Url = mem::transmute(urlptr2);
cont.assign("");
if url1 == url2 {
return cont.set_size(0);
return NSError::OK.error_code();
}
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.password() != url2.password() ||
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() {
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() {
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?
@ -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 {
buffer = buffer + "../";
buffer.push_str("../");
}
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]

View File

@ -5,48 +5,50 @@
#ifndef __RUST_URL_CAPI
#define __RUST_URL_CAPI
#include <stdlib.h>
#include "nsString.h"
#ifdef __cplusplus
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;
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);
int32_t rusturl_get_spec(rusturl_ptr url, void*);
int32_t rusturl_get_scheme(rusturl_ptr url, void*);
int32_t rusturl_get_username(rusturl_ptr url, void*);
int32_t rusturl_get_password(rusturl_ptr url, void*);
int32_t rusturl_get_host(rusturl_ptr url, void*);
int32_t rusturl_get_port(rusturl_ptr url); // returns port or -1
int32_t rusturl_get_path(rusturl_ptr url, void*);
int32_t rusturl_get_query(rusturl_ptr url, void*);
int32_t rusturl_get_fragment(rusturl_ptr url, void*);
int32_t rusturl_has_fragment(rusturl_ptr url); // 1 true, 0 false, < 0 error
int32_t rusturl_get_spec(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_scheme(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_username(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_password(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_host(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_port(const rusturl_ptr url); // returns port or -1
int32_t rusturl_get_path(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_query(const rusturl_ptr url, nsACString* cont);
int32_t rusturl_get_fragment(const rusturl_ptr url, nsACString* cont);
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_username(rusturl_ptr url, const char *user, size_t len);
int32_t rusturl_set_password(rusturl_ptr url, const char *pass, size_t len);
int32_t rusturl_set_host_port(rusturl_ptr url, const char *hostport, size_t len);
int32_t rusturl_set_host_and_port(rusturl_ptr url, const char *hostport, size_t len);
int32_t rusturl_set_host(rusturl_ptr url, const char *host, size_t len);
int32_t rusturl_set_port(rusturl_ptr url, const char *port, size_t len);
int32_t rusturl_set_scheme(rusturl_ptr url, const nsACString* scheme);
int32_t rusturl_set_username(rusturl_ptr url, const nsACString* user);
int32_t rusturl_set_password(rusturl_ptr url, const nsACString* password);
int32_t rusturl_set_host_port(rusturl_ptr url, const nsACString* hostport);
int32_t rusturl_set_host_and_port(rusturl_ptr url, const nsACString* hostport);
int32_t rusturl_set_host(rusturl_ptr url, const nsACString* host);
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_path(rusturl_ptr url, const char *path, size_t len);
int32_t rusturl_set_query(rusturl_ptr url, const char *path, size_t len);
int32_t rusturl_set_fragment(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 nsACString* query);
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_common_base_spec(rusturl_ptr url1, rusturl_ptr url2, void*);
int32_t rusturl_relative_spec(rusturl_ptr url1, rusturl_ptr url2, void*);
int32_t rusturl_resolve(const rusturl_ptr url, const nsACString* relative, nsACString* cont);
int32_t rusturl_common_base_spec(const rusturl_ptr url1, const rusturl_ptr url2, nsACString* cont);
int32_t rusturl_relative_spec(const rusturl_ptr url1, const rusturl_ptr url2, nsACString* cont);
size_t sizeof_rusturl();
#ifdef __cplusplus
}
#endif
#endif // __RUST_URL_CAPI

View File

@ -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()
}
}

View File

@ -76,6 +76,7 @@ name = "rust_url_capi"
version = "0.0.1"
dependencies = [
"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)",
]

View File

@ -63,6 +63,7 @@ name = "rust_url_capi"
version = "0.0.1"
dependencies = [
"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)",
]