Rust implementation of protocol_list_supports_protocol_or_later()

This commit is contained in:
Nick Mathewson
2017-11-09 09:42:09 -05:00
parent 6ea3db6fa7
commit c80bb04542
2 changed files with 80 additions and 0 deletions
+33
View File
@@ -100,6 +100,39 @@ pub extern "C" fn protocol_list_supports_protocol(
return if is_supported { 1 } else { 0 };
}
/// Provide an interface for C to translate arguments and return types for
/// protover::list_supports_protocol_or_later
#[no_mangle]
pub extern "C" fn protocol_list_supports_protocol_or_later(
c_protocol_list: *const c_char,
c_protocol: uint32_t,
version: uint32_t,
) -> c_int {
if c_protocol_list.is_null() {
return 1;
}
// Require an unsafe block to read the version from a C string. The pointer
// is checked above to ensure it is not null.
let c_str: &CStr = unsafe { CStr::from_ptr(c_protocol_list) };
let protocol_list = match c_str.to_str() {
Ok(n) => n,
Err(_) => return 1,
};
let protocol = match translate_to_rust(c_protocol) {
Ok(n) => n,
Err(_) => return 0,
};
let is_supported =
protover_string_supports_protocol_or_later(
protocol_list, protocol, version);
return if is_supported { 1 } else { 0 };
}
/// Provide an interface for C to translate arguments and return types for
/// protover::get_supported_protocols
#[no_mangle]
+47
View File
@@ -325,6 +325,53 @@ pub fn protover_string_supports_protocol(
supported_versions.contains(&vers)
}
/// As protover_string_supports_protocol(), but also returns True if
/// any later version of the protocol is supported.
///
/// # Examples
/// ```
/// use protover::*;
///
/// let is_supported = protover_string_supports_protocol_or_later(
/// "Link=3-4 Cons=5", Proto::Cons, 5);
///
/// assert_eq!(true, is_supported);
///
/// let is_supported = protover_string_supports_protocol_or_later(
/// "Link=3-4 Cons=5", Proto::Cons, 4);
///
/// assert_eq!(true, is_supported);
///
/// let is_supported = protover_string_supports_protocol_or_later(
/// "Link=3-4 Cons=5", Proto::Cons, 6);
///
/// assert_eq!(false, is_supported);
/// ```
pub fn protover_string_supports_protocol_or_later(
list: &str,
proto: Proto,
vers: u32,
) -> bool {
let supported: HashMap<Proto, HashSet<u32>>;
match parse_protocols_from_string(list) {
Ok(result) => supported = result,
Err(_) => return false,
}
let supported_versions = match supported.get(&proto) {
Some(n) => n,
None => return false,
};
for v in supported_versions.iter() {
if v >= &vers {
return true;
}
}
return false;
}
/// Fully expand a version range. For example, 1-3 expands to 1,2,3
/// Helper for get_versions
///