@ -68,11 +68,19 @@ impl Json {
}
}
pub fn set_string_from_bytes ( & self , key : & str , val : & [ u8 ] ) {
unsafe {
json_object_set_new ( self . js ,
CString ::new ( key ) . unwrap ( ) . as_ptr ( ) ,
json_string ( to_cstring ( val ) . as_ptr ( ) ) ) ;
}
}
pub fn set_string ( & self , key : & str , val : & str ) {
unsafe {
unsafe {
json_object_set_new ( self . js ,
CString ::new ( key ) . unwrap ( ) . as_ptr ( ) ,
json_string ( CString ::new ( val ) . unwrap ( ) . as_ptr ( ) ) ) ;
json_string ( to_cstring( val . as_bytes ( ) ) . as_ptr ( ) ) ) ;
}
}
@ -98,3 +106,43 @@ impl Json {
}
}
}
/// Convert an array of bytes into an ascii printable string replacing
/// non-printable characters (including NULL) with hex value.
///
/// Newer versions of Jansson have a json_stringn that will allow us
/// to create a string out of a byte array of unicode compliant bytes,
/// but until we can use it across all platforms this is probably the
/// best we can do.
fn to_cstring ( val : & [ u8 ] ) -> CString {
let mut safe = Vec ::with_capacity ( val . len ( ) ) ;
for c in val {
if * c = = 0 | | * c > 0x7f {
safe . extend ( format! ( "\\x{:02x}" , * c ) . as_bytes ( ) ) ;
} else {
safe . push ( * c ) ;
}
}
match CString ::new ( safe ) {
Ok ( cstr ) = > cstr ,
_ = > {
CString ::new ( "<failed to encode string>" ) . unwrap ( )
}
}
}
#[ cfg(test) ]
mod tests {
use json ::to_cstring ;
#[ test ]
fn test_to_string ( ) {
assert_eq! ( "A\\x00A" ,
to_cstring ( & [ 0x41 , 0x00 , 0x41 ] ) . into_string ( ) . unwrap ( ) ) ;
assert_eq! ( "" , to_cstring ( & [ ] ) . into_string ( ) . unwrap ( ) ) ;
assert_eq! ( "\\x80\\xf1\\xf2\\xf3" ,
to_cstring ( & [ 0x80 , 0xf1 , 0xf2 , 0xf3 ] ) . into_string ( ) . unwrap ( ) ) ;
}
}