fork download
  1. extern crate base64;
  2.  
  3. fn read_float_vec_from_byte_vec(v: Vec<u8>) -> Result<Vec<f32>, &'static str> {
  4. #[inline(always)]
  5. fn float_from_u8_slice(s: &[u8]) -> f32 {
  6. let array = [s[0], s[1], s[2], s[3]];
  7. unsafe { std::mem::transmute(array) }
  8. }
  9.  
  10. match v.len() % 4 {
  11. 0 => Ok(v.chunks(4).map(float_from_u8_slice).collect()),
  12. _ => Err("Number not divisible by 4"),
  13. }
  14. }
  15.  
  16. fn float_vec_as_byte_vec(values: &Vec<f32>) -> Vec<u8> {
  17. let dest_len = values.len() * 4;
  18. let mut result = Vec::<u8>::with_capacity(dest_len);
  19. result.resize(dest_len, 0);
  20. for (i, x) in values.iter().enumerate() {
  21. let bytes: [u8; 4] = unsafe { std::mem::transmute(*x) };
  22. result[i*4..i*4+4].copy_from_slice(&bytes[..]);
  23. }
  24. result
  25. }
  26.  
  27. fn show_base64_decode_error(e: base64::DecodeError) -> String {
  28. use std::error::Error;
  29. format!("{:?}", e.description())
  30. }
  31.  
  32. fn base64_to_f32_16_array(base64_str: &str) -> Result<[f32; 16], String>
  33. {
  34. base64::decode(base64_str
  35. ).map_err(show_base64_decode_error
  36. ).and_then(read_float_vec_from_byte_vec
  37. ).map(
  38. |float_vec| {
  39. let mut result: [f32; 16] = [0.0; 16];
  40. result.copy_from_slice(&float_vec[..]);
  41. result
  42. }
  43. )
  44. }
  45.  
  46. fn f32_16_array_to_base64(vals: &[f32; 16]) -> String
  47. {
  48. base64::encode(&float_vec_as_byte_vec(&vals.to_vec()))
  49. }
  50.  
  51. #[cfg(test)]
  52. mod tests {
  53. static VALUES: [f32; 16] = [-0.35, -0.97, 0.05, 0.49, 1.35, 1.08, -0.71, 0.27, -0.44, 0.22, -1.34, -1.17, 0.68, 0.02, -0.52, 0.83];
  54. static BASE64_STR: &str = "MzOzvuxReL/NzEw9SOH6Ps3MrD9xPYo/j8I1v3E9ij6uR+G+rkdhPh+Fq7+PwpW/exQuPwrXozy4HgW/4XpUPw==";
  55. #[test]
  56. fn base64_to_f32_16_array_test() {
  57. assert_eq!(super::base64_to_f32_16_array(&BASE64_STR), Ok(VALUES));
  58. assert_eq!(
  59. super::base64_to_f32_16_array("foo"),
  60. Err("Number of bytes not divisible by 4.".to_string()));
  61. }
  62. #[test]
  63. fn f32_16_array_to_base64_test() {
  64. assert_eq!(super::f32_16_array_to_base64(&VALUES), BASE64_STR);
  65. }
  66. }
  67.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty