diff --git a/ports/cef/eutil.rs b/ports/cef/eutil.rs index b71421f8c40..d5f9760f6bb 100644 --- a/ports/cef/eutil.rs +++ b/ports/cef/eutil.rs @@ -2,6 +2,18 @@ * 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/. */ +use libc::c_int; +use std::slice; +use std::str; + pub fn fptr_is_null(fptr: *const u8) -> bool { fptr.is_null() } + +pub fn slice_to_str(s: *const u8, l: uint, f: |&str| -> c_int) -> c_int { + unsafe { + slice::raw::buf_as_slice(s, l, |result| { + str::from_utf8(result).map(|s| f(s)).unwrap_or(0) + }) + } +} diff --git a/ports/cef/lib.rs b/ports/cef/lib.rs index 82949696abb..ca96b5283e2 100644 --- a/ports/cef/lib.rs +++ b/ports/cef/lib.rs @@ -51,6 +51,7 @@ pub mod mem; pub mod request; pub mod string; pub mod string_list; +pub mod string_map; pub mod task; pub mod types; pub mod urlrequest; diff --git a/ports/cef/string.rs b/ports/cef/string.rs index 9763651f9a0..c9f74af624f 100644 --- a/ports/cef/string.rs +++ b/ports/cef/string.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use eutil::fptr_is_null; +use eutil::{fptr_is_null, slice_to_str}; use libc::{size_t, c_int, c_ushort,c_void}; use libc::types::os::arch::c95::wchar_t; use mem::{new0,newarray0,delete,deletearray}; @@ -11,7 +11,6 @@ use std::mem; use std::ptr; use std::slice; use std::string; -use std::str; use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t}; use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t}; @@ -110,18 +109,11 @@ pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef #[no_mangle] pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int { - unsafe { - slice::raw::buf_as_slice(src, src_len as uint, |result| { - match str::from_utf8(result) { - Some(enc) => { - let conv = enc.utf16_units().collect::>(); - cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1); - 1 - }, - None => 0 - } - }) - } + slice_to_str(src, src_len as uint, |result| { + let conv = result.utf16_units().collect::>(); + cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1); + 1 + }) } #[no_mangle] diff --git a/ports/cef/string_map.rs b/ports/cef/string_map.rs new file mode 100644 index 00000000000..67753b3c5dc --- /dev/null +++ b/ports/cef/string_map.rs @@ -0,0 +1,121 @@ +/* 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/. */ + +use eutil::{fptr_is_null, slice_to_str}; +use libc::{c_int}; +use std::collections::TreeMap; +use std::mem; +use std::string::String; +use string::{cef_string_userfree_utf8_alloc, cef_string_userfree_utf8_free, cef_string_utf8_set}; +use types::{cef_string_map_t, cef_string_t}; + +fn string_map_to_treemap(sm: *mut cef_string_map_t) -> *mut TreeMap { + sm as *mut TreeMap +} + +//cef_string_map + +#[no_mangle] +pub extern "C" fn cef_string_map_alloc() -> *mut cef_string_map_t { + unsafe { + let sm: Box> = box TreeMap::new(); + mem::transmute(sm) + } +} + +#[no_mangle] +pub extern "C" fn cef_string_map_size(sm: *mut cef_string_map_t) -> c_int { + unsafe { + if fptr_is_null(mem::transmute(sm)) { return 0; } + let v = string_map_to_treemap(sm); + (*v).len() as c_int + } +} + +#[no_mangle] +pub extern "C" fn cef_string_map_append(sm: *mut cef_string_map_t, key: *const cef_string_t, value: *const cef_string_t) -> c_int { + unsafe { + if fptr_is_null(mem::transmute(sm)) { return 0; } + let v = string_map_to_treemap(sm); + slice_to_str((*key).str as *const u8, (*key).length as uint, |result| { + let s = String::from_str(result); + let csv = cef_string_userfree_utf8_alloc(); + cef_string_utf8_set((*value).str as *const u8, (*value).length, csv, 1); + (*v).insert(s, csv); + 1 + }) + } +} + +#[no_mangle] +pub extern "C" fn cef_string_map_find(sm: *mut cef_string_map_t, key: *const cef_string_t, value: *mut cef_string_t) -> c_int { + unsafe { + if fptr_is_null(mem::transmute(sm)) { return 0; } + let v = string_map_to_treemap(sm); + slice_to_str((*key).str as *const u8, (*key).length as uint, |result| { + match (*v).find(&String::from_str(result)) { + Some(s) => { + cef_string_utf8_set((**s).str as *const u8, (**s).length, value, 1); + 1 + } + None => 0 + } + }) + } +} + +#[no_mangle] +pub extern "C" fn cef_string_map_key(sm: *mut cef_string_map_t, index: c_int, value: *mut cef_string_t) -> c_int { + unsafe { + if index < 0 || fptr_is_null(mem::transmute(sm)) { return 0; } + let v = string_map_to_treemap(sm); + if index as uint > (*v).len() - 1 { return 0; } + + for (i, k) in (*v).keys().enumerate() { + if i == index as uint { + cef_string_utf8_set(k.as_bytes().as_ptr(), k.len() as u64, value, 1); + return 1; + } + } + } + 0 +} + +#[no_mangle] +pub extern "C" fn cef_string_map_value(sm: *mut cef_string_map_t, index: c_int, value: *mut cef_string_t) -> c_int { + unsafe { + if index < 0 || fptr_is_null(mem::transmute(sm)) { return 0; } + let v = string_map_to_treemap(sm); + if index as uint > (*v).len() - 1 { return 0; } + + for (i, val) in (*v).values().enumerate() { + if i == index as uint { + cef_string_utf8_set((**val).str as *const u8, (**val).length, value, 1); + return 1; + } + } + } + 0 +} + +#[no_mangle] +pub extern "C" fn cef_string_map_clear(sm: *mut cef_string_map_t) { + unsafe { + if fptr_is_null(mem::transmute(sm)) { return; } + let v = string_map_to_treemap(sm); + for val in (*v).values() { + cef_string_userfree_utf8_free(*val); + } + (*v).clear(); + } +} + +#[no_mangle] +pub extern "C" fn cef_string_map_free(sm: *mut cef_string_map_t) { + unsafe { + if fptr_is_null(mem::transmute(sm)) { return; } + let _v: Box> = mem::transmute(sm); + cef_string_map_clear(sm); + } +}