/animation/src/serializer/source.rs

https://github.com/Logicalshift/flowbetween · Rust · 394 lines · 273 code · 73 blank · 48 comment · 66 complexity · 3bac274210795064b213bf2255bbf645 MD5 · raw file

  1. use smallvec::*;
  2. use flo_float_encoder::*;
  3. use std::io;
  4. use std::io::{Read};
  5. use std::str::{Chars};
  6. use std::time::{Duration};
  7. use std::convert::{TryInto};
  8. ///
  9. /// Decodes a character to a 6-bit value (ie, from ENCODING_CHAR_SET)
  10. ///
  11. fn decode_chr(c: char) -> u8 {
  12. if c >= 'A' && c <= 'Z' {
  13. ((c as u8) - ('A' as u8)) as u8
  14. } else if c >= 'a' && c <= 'z' {
  15. (((c as u8) - ('a' as u8)) as u8) + 26
  16. } else if c >= '0' && c <= '9' {
  17. (((c as u8) - ('0' as u8)) as u8) + 52
  18. } else if c == '+' {
  19. 62
  20. } else if c == '/' {
  21. 63
  22. } else {
  23. 0
  24. }
  25. }
  26. ///
  27. /// Reader implementation that can read bytes from an animation data source
  28. ///
  29. struct ByteReader<'a, Src: AnimationDataSource> {
  30. /// The data source (this will call next_chr only so this is suitable for implementing next_bytes)
  31. src: &'a mut Src,
  32. /// The current byte
  33. current: u8,
  34. /// The current bit pos
  35. bit_pos: usize
  36. }
  37. impl<'a, Src: AnimationDataSource> Read for ByteReader<'a, Src> {
  38. fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
  39. let mut pos = 0;
  40. // Iterate until we've read enough bytes from the source
  41. while pos < buf.len() {
  42. // Process a character from the input
  43. let byte = decode_chr(self.src.next_chr());
  44. if self.bit_pos + 6 >= 8 {
  45. // Add the remaining bits the current value
  46. let mask = (1<<(8-self.bit_pos))-1;
  47. self.current |= (byte&mask)<<self.bit_pos;
  48. buf[pos] = self.current;
  49. pos += 1;
  50. // Remaining bits go in 'current'
  51. self.current = byte >> (8-self.bit_pos);
  52. self.bit_pos = 6-(8-self.bit_pos);
  53. } else {
  54. // Just add the bits to 'current' and carry on
  55. self.current |= byte << self.bit_pos;
  56. self.bit_pos += 6;
  57. }
  58. }
  59. Ok(pos)
  60. }
  61. }
  62. ///
  63. /// Represents a source for serialized animation data
  64. ///
  65. pub trait AnimationDataSource : Sized {
  66. ///
  67. /// Reads the next character from this data source
  68. ///
  69. fn next_chr(&mut self) -> char;
  70. ///
  71. /// Reads len bytes from this data source
  72. ///
  73. fn next_bytes(&mut self, len: usize) -> SmallVec<[u8;8]> {
  74. // Build the result into a smallvec
  75. let mut res = smallvec![0; len];
  76. // Read using a ByteReader (defined above)
  77. let mut reader = ByteReader { src: self, current: 0, bit_pos: 0 };
  78. reader.read(&mut res[0..len]).ok();
  79. res
  80. }
  81. ///
  82. /// Reads a usize from this source
  83. ///
  84. fn next_usize(&mut self) -> usize {
  85. let mut result = 0usize;
  86. let mut shift = 0;
  87. loop {
  88. // Decode the next character
  89. let byte = decode_chr(self.next_chr());
  90. // Lower 5 bits contain the value
  91. let lower = byte & 0x1f;
  92. result |= (lower as usize) << shift;
  93. shift += 5;
  94. // If the upper bit is set there are more bytes
  95. if (byte & 0x20) == 0 {
  96. break;
  97. }
  98. }
  99. result
  100. }
  101. ///
  102. /// Reads a u64 (in the format where it's expected to have a small value) from this source
  103. ///
  104. fn next_small_u64(&mut self) -> u64 {
  105. let mut result = 0u64;
  106. let mut shift = 0;
  107. loop {
  108. // Decode the next character
  109. let byte = decode_chr(self.next_chr());
  110. // Lower 5 bits contain the value
  111. let lower = byte & 0x1f;
  112. result |= (lower as u64) << shift;
  113. shift += 5;
  114. // If the upper bit is set there are more bytes
  115. if (byte & 0x20) == 0 {
  116. break;
  117. }
  118. }
  119. result
  120. }
  121. ///
  122. /// Reads a string from the source
  123. ///
  124. fn next_string(&mut self) -> String {
  125. let num_bytes = self.next_usize();
  126. let utf8 = self.next_bytes(num_bytes);
  127. String::from_utf8_lossy(&utf8).to_string()
  128. }
  129. fn next_u32(&mut self) -> u32 {
  130. u32::from_le_bytes(*&self.next_bytes(4)[0..4].try_into().unwrap())
  131. }
  132. fn next_i32(&mut self) -> i32 {
  133. i32::from_le_bytes(*&self.next_bytes(4)[0..4].try_into().unwrap())
  134. }
  135. fn next_u64(&mut self) -> u64 {
  136. u64::from_le_bytes(*&self.next_bytes(8)[0..8].try_into().unwrap())
  137. }
  138. fn next_i64(&mut self) -> i64 {
  139. i64::from_le_bytes(*&self.next_bytes(8)[0..8].try_into().unwrap())
  140. }
  141. fn next_f32(&mut self) -> f32 {
  142. f32::from_le_bytes(*&self.next_bytes(4)[0..4].try_into().unwrap())
  143. }
  144. fn next_f64(&mut self) -> f64 {
  145. f64::from_le_bytes(*&self.next_bytes(8)[0..8].try_into().unwrap())
  146. }
  147. ///
  148. /// Writes a f64 value to this target that's relative to a previous value (this uses a more compact format to save space)
  149. ///
  150. fn next_f64_offset(&mut self, last: f64) -> f64 {
  151. // Read using a ByteReader (defined above)
  152. let mut reader = ByteReader { src: self, current: 0, bit_pos: 0 };
  153. unsquish_float(&mut reader, last).unwrap()
  154. }
  155. ///
  156. /// Writes a time to the target
  157. ///
  158. fn next_duration(&mut self) -> Duration {
  159. match self.next_chr() {
  160. 't' => Duration::from_micros(self.next_u32() as u64),
  161. 'T' => Duration::from_micros(self.next_u64()),
  162. _ => Duration::from_millis(0)
  163. }
  164. }
  165. }
  166. impl AnimationDataSource for Chars<'_> {
  167. fn next_chr(&mut self) -> char {
  168. self.next().unwrap_or('A')
  169. }
  170. }
  171. #[cfg(test)]
  172. mod test {
  173. use super::*;
  174. use super::super::target::*;
  175. #[test]
  176. fn decode_bytes() {
  177. let bytes = (0u8..=255u8).into_iter().collect::<Vec<_>>();
  178. let mut encoded = String::new();
  179. encoded.write_bytes(&bytes);
  180. for end in 0u8..255u8 {
  181. let decoded = encoded.chars().next_bytes((end as usize)+1);
  182. assert!(decoded == (0u8..=end).into_iter().collect::<SmallVec<[u8; 8]>>());
  183. }
  184. }
  185. #[test]
  186. fn decode_usize() {
  187. let mut encoded = String::new();
  188. encoded.write_usize(1234);
  189. assert!(encoded.chars().next_usize() == 1234);
  190. }
  191. #[test]
  192. fn decode_small_u64() {
  193. let mut encoded = String::new();
  194. encoded.write_small_u64(1234);
  195. assert!(encoded.chars().next_small_u64() == 1234);
  196. }
  197. #[test]
  198. fn decode_string() {
  199. let mut encoded = String::new();
  200. encoded.write_str("Hello, world");
  201. assert!(encoded.chars().next_string() == "Hello, world".to_string());
  202. }
  203. #[test]
  204. fn decode_u32() {
  205. let mut encoded = String::new();
  206. encoded.write_u32(1234);
  207. assert!(encoded.chars().next_u32() == 1234);
  208. }
  209. #[test]
  210. fn decode_i32() {
  211. let mut encoded = String::new();
  212. encoded.write_i32(-1234);
  213. assert!(encoded.chars().next_i32() == -1234);
  214. }
  215. #[test]
  216. fn decode_u64() {
  217. let mut encoded = String::new();
  218. encoded.write_u64(1234);
  219. assert!(encoded.chars().next_u64() == 1234);
  220. }
  221. #[test]
  222. fn decode_i64() {
  223. let mut encoded = String::new();
  224. encoded.write_i64(-1234);
  225. assert!(encoded.chars().next_i64() == -1234);
  226. }
  227. #[test]
  228. fn decode_f32() {
  229. let mut encoded = String::new();
  230. encoded.write_f32(1234.1234);
  231. assert!(encoded.chars().next_f32() == 1234.1234);
  232. }
  233. #[test]
  234. fn decode_f64() {
  235. let mut encoded = String::new();
  236. encoded.write_f64(1234.1234);
  237. assert!(encoded.chars().next_f64() == 1234.1234);
  238. }
  239. #[test]
  240. fn decode_short_duration() {
  241. let mut encoded = String::new();
  242. encoded.write_duration(Duration::from_millis(1234));
  243. assert!(encoded.chars().next_duration() == Duration::from_millis(1234));
  244. }
  245. #[test]
  246. fn decode_long_duration() {
  247. let mut encoded = String::new();
  248. encoded.write_duration(Duration::from_secs(1000000));
  249. assert!(encoded.chars().next_duration() == Duration::from_secs(1000000));
  250. }
  251. #[test]
  252. fn decode_f64_small_offset() {
  253. let mut encoded = String::new();
  254. encoded.write_next_f64(14.0, 64.0);
  255. assert!(encoded.chars().next_f64_offset(14.0) == 64.0);
  256. }
  257. #[test]
  258. fn decode_f64_large_offset() {
  259. let mut encoded = String::new();
  260. encoded.write_next_f64(14.0, 64000.0);
  261. assert!(encoded.chars().next_f64_offset(14.0) == 64000.0);
  262. }
  263. #[test]
  264. fn decode_all() {
  265. // Encodes everything next to each other so we know the decoder is always left in a valid state afterwards (doesn't read an extra character)
  266. let mut encoded = String::new();
  267. encoded.write_usize(1234);
  268. encoded.write_small_u64(1234);
  269. encoded.write_str("Hello, world");
  270. encoded.write_u32(1234);
  271. encoded.write_i32(-1234);
  272. encoded.write_u64(1234);
  273. encoded.write_i64(-1234);
  274. encoded.write_f32(1234.1234);
  275. encoded.write_f64(1234.1234);
  276. encoded.write_duration(Duration::from_millis(1234));
  277. encoded.write_duration(Duration::from_secs(1000000));
  278. encoded.write_next_f64(14.0, 64.0);
  279. encoded.write_next_f64(14.0, 64000.0);
  280. encoded.write_usize(1234);
  281. encoded.write_small_u64(1234);
  282. encoded.write_str("Hello, world");
  283. encoded.write_u32(1234);
  284. encoded.write_i32(-1234);
  285. encoded.write_u64(1234);
  286. encoded.write_i64(-1234);
  287. encoded.write_f32(1234.1234);
  288. encoded.write_f64(1234.1234);
  289. encoded.write_duration(Duration::from_millis(1234));
  290. encoded.write_duration(Duration::from_secs(1000000));
  291. encoded.write_next_f64(14.0, 64.0);
  292. encoded.write_next_f64(14.0, 64000.0);
  293. let mut src = encoded.chars();
  294. assert!(src.next_usize() == 1234);
  295. assert!(src.next_small_u64() == 1234);
  296. assert!(src.next_string() == "Hello, world".to_string());
  297. assert!(src.next_u32() == 1234);
  298. assert!(src.next_i32() == -1234);
  299. assert!(src.next_u64() == 1234);
  300. assert!(src.next_i64() == -1234);
  301. assert!(src.next_f32() == 1234.1234);
  302. assert!(src.next_f64() == 1234.1234);
  303. assert!(src.next_duration() == Duration::from_millis(1234));
  304. assert!(src.next_duration() == Duration::from_secs(1000000));
  305. assert!(src.next_f64_offset(14.0) == 64.0);
  306. assert!(src.next_f64_offset(14.0) == 64000.0);
  307. assert!(src.next_usize() == 1234);
  308. assert!(src.next_small_u64() == 1234);
  309. assert!(src.next_string() == "Hello, world".to_string());
  310. assert!(src.next_u32() == 1234);
  311. assert!(src.next_i32() == -1234);
  312. assert!(src.next_u64() == 1234);
  313. assert!(src.next_i64() == -1234);
  314. assert!(src.next_f32() == 1234.1234);
  315. assert!(src.next_f64() == 1234.1234);
  316. assert!(src.next_duration() == Duration::from_millis(1234));
  317. assert!(src.next_duration() == Duration::from_secs(1000000));
  318. assert!(src.next_f64_offset(14.0) == 64.0);
  319. assert!(src.next_f64_offset(14.0) == 64000.0);
  320. }
  321. }