diff --git a/ports/cef/lib.rs b/ports/cef/lib.rs index ca96b5283e2..ae689e33ee1 100644 --- a/ports/cef/lib.rs +++ b/ports/cef/lib.rs @@ -52,6 +52,7 @@ pub mod request; pub mod string; pub mod string_list; pub mod string_map; +pub mod string_multimap; pub mod task; pub mod types; pub mod urlrequest; diff --git a/ports/cef/string_map.rs b/ports/cef/string_map.rs index 2ca2e4e0f9c..91434c556f3 100644 --- a/ports/cef/string_map.rs +++ b/ports/cef/string_map.rs @@ -54,7 +54,7 @@ pub extern "C" fn cef_string_map_find(sm: *mut cef_string_map_t, key: *const cef if sm.is_null() { 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)) { + match (*v).get(&String::from_str(result)) { Some(s) => { cef_string_utf8_set((**s).str as *const u8, (**s).length, value, 1); 1 diff --git a/ports/cef/string_multimap.rs b/ports/cef/string_multimap.rs new file mode 100644 index 00000000000..b8edfa041a7 --- /dev/null +++ b/ports/cef/string_multimap.rs @@ -0,0 +1,150 @@ +/* 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::slice_to_str; +use libc::{c_int}; +use std::collections::TreeMap; +use std::iter::AdditiveIterator; +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_multimap_t,cef_string_t}; + +fn string_multimap_to_treemap(smm: *mut cef_string_multimap_t) -> *mut TreeMap> { + smm as *mut TreeMap> +} + +//cef_string_multimap + +#[no_mangle] +pub extern "C" fn cef_string_multimap_alloc() -> *mut cef_string_multimap_t { + unsafe { + let smm: Box>> = box TreeMap::new(); + mem::transmute(smm) + } +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_size(smm: *mut cef_string_multimap_t) -> c_int { + unsafe { + if smm.is_null() { return 0; } + let v = string_multimap_to_treemap(smm); + (*v).values().map(|val| (*val).len()).sum() as c_int + } +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_find_count(smm: *mut cef_string_multimap_t, key: *const cef_string_t) -> c_int { + unsafe { + if smm.is_null() { return 0; } + let v = string_multimap_to_treemap(smm); + slice_to_str((*key).str as *const u8, (*key).length as uint, |result| { + match (*v).get(&String::from_str(result)) { + Some(s) => s.len() as c_int, + None => 0 + } + }) + } +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_append(smm: *mut cef_string_multimap_t, key: *const cef_string_t, value: *const cef_string_t) -> c_int { + unsafe { + if smm.is_null() { return 0; } + let v = string_multimap_to_treemap(smm); + 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); + match (*v).get_mut(&s) { + Some(vc) => (*vc).push(csv), + None => { (*v).insert(s, vec!(csv)); } + } + 1 + }) + } +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_enumerate(smm: *mut cef_string_multimap_t, key: *const cef_string_t, index: c_int, value: *mut cef_string_t) -> c_int { + unsafe { + if smm.is_null() { return 0; } + let v = string_multimap_to_treemap(smm); + slice_to_str((*key).str as *const u8, (*key).length as uint, |result| { + match (*v).get(&String::from_str(result)) { + Some(s) => { + if (*s).len() <= index as uint { + return 0; + } + let cs = (*s)[index as uint]; + cef_string_utf8_set((*cs).str as *const u8, (*cs).length, value, 1) + } + None => 0 + } + }) + } +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_key(smm: *mut cef_string_multimap_t, index: c_int, value: *mut cef_string_t) -> c_int { + unsafe { + if index < 0 || smm.is_null() { return 0; } + let v = string_multimap_to_treemap(smm); + let mut rem = index as uint; + + for (key, val) in (*v).iter() { + if rem < (*val).len() { + return cef_string_utf8_set((*key).as_bytes().as_ptr(), (*key).len() as u64, value, 1); + } else { + rem -= (*val).len(); + } + } + } + 0 +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_value(smm: *mut cef_string_multimap_t, index: c_int, value: *mut cef_string_t) -> c_int { + unsafe { + if index < 0 || smm.is_null() { return 0; } + let v = string_multimap_to_treemap(smm); + let mut rem = index as uint; + + for val in (*v).values() { + if rem < (*val).len() { + let cs = (*val)[rem as uint]; + return cef_string_utf8_set((*cs).str as *const u8, (*cs).length, value, 1); + } else { + rem -= (*val).len(); + } + } + } + 0 +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_clear(smm: *mut cef_string_multimap_t) { + unsafe { + if smm.is_null() { return; } + let v = string_multimap_to_treemap(smm); + if (*v).len() == 0 { return; } + for (_, val) in (*v).iter_mut() { + while (*val).len() != 0 { + let cs = (*val).pop(); + cef_string_userfree_utf8_free(cs.unwrap()); + } + } + (*v).clear(); + } +} + +#[no_mangle] +pub extern "C" fn cef_string_multimap_free(smm: *mut cef_string_multimap_t) { + unsafe { + if smm.is_null() { return; } + let v: Box>> = mem::transmute(smm); + cef_string_multimap_clear(smm); + drop(v); + } +} diff --git a/ports/cef/types.rs b/ports/cef/types.rs index 4484ffe7787..b6abf2e7d38 100644 --- a/ports/cef/types.rs +++ b/ports/cef/types.rs @@ -6,6 +6,7 @@ use libc::{c_uint, c_ushort, c_int, c_double, size_t, c_void, c_longlong}; use libc::types::os::arch::c95::wchar_t; pub enum cef_string_map_t {} +pub enum cef_string_multimap_t {} pub enum cef_string_list_t {} pub enum cef_text_input_context_t {} pub enum cef_event_handle_t {}