reader.rs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. use std::{fs,io,iter,mem,slice,vec};
  2. use bzip2::bufread::BzDecoder;
  3. /// A `ByteReader` is just a tiny wrapper over a mutable byte iterator, so we
  4. /// can parse things more easily.
  5. pub struct ByteReader<Rd> {
  6. bytes: Rd,
  7. }
  8. impl<R: io::Read> ByteReader<iter::FilterMap<io::Bytes<R>, &'static Fn(io::Result<u8>) -> Option<u8>>>
  9. {
  10. /// Create a ByteReader from any type that implement Read
  11. pub fn from_reader(r: R) -> Self {
  12. const MK_OK: &'static Fn(io::Result<u8>) -> Option<u8> = &io::Result::<u8>::ok;
  13. let bytes = r.bytes().filter_map(MK_OK);
  14. ByteReader { bytes: bytes }
  15. }
  16. }
  17. impl ByteReader<iter::FilterMap<io::Bytes<fs::File>,
  18. &'static Fn(io::Result<u8>) -> Option<u8>>>
  19. {
  20. /// Create a reader by opening a named file for reading
  21. pub fn from_file(path: &str) -> io::Result<Self> {
  22. let f = try!(fs::File::open(path));
  23. Ok(ByteReader::from_reader(f))
  24. }
  25. }
  26. impl ByteReader<vec::IntoIter<u8>> {
  27. /// Create a reader from a vector of u8s
  28. pub fn from_vec(lst: Vec<u8>) -> Self {
  29. ByteReader { bytes: lst.into_iter() }
  30. }
  31. }
  32. impl<'a> ByteReader<iter::Cloned<slice::Iter<'a, u8>>> {
  33. /// Create a reader from a borrowed slice, with a copy on each access
  34. pub fn from_slice(lst: &'a [u8]) -> Self {
  35. ByteReader { bytes: lst.iter().cloned() }
  36. }
  37. }
  38. impl<R: io::BufRead> ByteReader<iter::FilterMap<io::Bytes<BzDecoder<R>>, &'static Fn(io::Result<u8>) -> Option<u8>>> {
  39. pub fn from_compressed_reader(r: R) -> Self {
  40. ByteReader::from_reader(BzDecoder::new(r))
  41. }
  42. }
  43. impl ByteReader<iter::FilterMap<io::Bytes<BzDecoder<io::BufReader<fs::File>>>, &'static Fn(io::Result<u8>) -> Option<u8>>> {
  44. pub fn from_compressed_file(path: &str) -> io::Result<Self> {
  45. let f = try!(fs::File::open(path));
  46. Ok(ByteReader::from_compressed_reader(io::BufReader::new(f)))
  47. }
  48. }
  49. #[test]
  50. fn reader_tests() {
  51. assert!(ByteReader::from_slice(&[0x00]).read_twip() == Ok(-32.0));
  52. assert!(ByteReader::from_slice(&[0x00]).read_prefix_int() == Ok(0x00));
  53. assert!(ByteReader::from_slice(&[0x7f]).read_prefix_int() == Ok(0x7f));
  54. assert!(ByteReader::from_slice(&[0x80,0xff]).read_prefix_int() == Ok(0xff));
  55. assert!(ByteReader::from_slice(&[0x03,0x00,0x00,0x00])
  56. .read_several(|r| r.read_twip()) ==
  57. Ok(vec![-32.0,-32.0,-32.0]));
  58. }
  59. impl<T> ByteReader<T> where T: Iterator<Item=u8> {
  60. /// This gets the next byte, or fails if it's out of input.
  61. pub fn next(&mut self) -> Result<u8, String> {
  62. Ok(try!(self.bytes.next().ok_or("out of input")))
  63. }
  64. /// This reads a one-byte or two-byte float in the rough range of
  65. /// (192 .. -128). We're going to treat all models as if they're
  66. /// supposed to be centered in a 64x64x64 square, so this gives
  67. /// us 128 units on either side of the central square, as well.
  68. pub fn read_twip(&mut self) -> Result<f32, String> {
  69. let b1 = try!(self.next());
  70. if (b1 & 0x80) != 0 {
  71. let b2 = try!(self.next());
  72. let val = ((b1 as u16 & 0x7f) << 8) | b2 as u16;
  73. Ok((val as f32 / 102.0) - 128.0)
  74. } else {
  75. Ok((b1 as f32) - 32.0)
  76. }
  77. }
  78. /// This reads a single byte and treats it as a ratio.
  79. pub fn read_ratio(&mut self) -> Result<f32, String> {
  80. let b = try!(self.next());
  81. Ok(b as f32 / 255.0)
  82. }
  83. pub fn read_u64be(&mut self) -> Result<u64, String> {
  84. let a = try!(self.next());
  85. let b = try!(self.next());
  86. let c = try!(self.next());
  87. let d = try!(self.next());
  88. let e = try!(self.next());
  89. let f = try!(self.next());
  90. let g = try!(self.next());
  91. let h = try!(self.next());
  92. let rs = [ h, g, f, e, d, c, b, a ];
  93. unsafe { Ok(mem::transmute::<[u8;8],u64>(rs)) }
  94. }
  95. pub fn read_u64le(&mut self) -> Result<u64, String> {
  96. let a = try!(self.next());
  97. let b = try!(self.next());
  98. let c = try!(self.next());
  99. let d = try!(self.next());
  100. let e = try!(self.next());
  101. let f = try!(self.next());
  102. let g = try!(self.next());
  103. let h = try!(self.next());
  104. let rs = [ a, b, c, d, e, f, g, h ];
  105. unsafe { Ok(mem::transmute::<[u8;8],u64>(rs)) }
  106. }
  107. pub fn read_u32be(&mut self) -> Result<u32, String> {
  108. let a = try!(self.next());
  109. let b = try!(self.next());
  110. let c = try!(self.next());
  111. let d = try!(self.next());
  112. let rs = [ d, c, b, a ];
  113. unsafe { Ok(mem::transmute::<[u8;4],u32>(rs)) }
  114. }
  115. pub fn read_u32le(&mut self) -> Result<u32, String> {
  116. let a = try!(self.next());
  117. let b = try!(self.next());
  118. let c = try!(self.next());
  119. let d = try!(self.next());
  120. let rs = [ a, b, c, d ];
  121. unsafe { Ok(mem::transmute::<[u8;4],u32>(rs)) }
  122. }
  123. pub fn read_u16be(&mut self) -> Result<u16, String> {
  124. let a = try!(self.next());
  125. let b = try!(self.next());
  126. let rs = [ b, a ];
  127. unsafe { Ok(mem::transmute::<[u8;2],u16>(rs)) }
  128. }
  129. pub fn read_u16le(&mut self) -> Result<u16, String> {
  130. let a = try!(self.next());
  131. let b = try!(self.next());
  132. let rs = [ a, b ];
  133. unsafe { Ok(mem::transmute::<[u8;2],u16>(rs)) }
  134. }
  135. /// This reads a 64-bit int with a packed PrefixInteger representation.
  136. /// The shorter the int, the shorter the representation.
  137. pub fn read_prefix_int(&mut self) -> Result<u64, String> {
  138. fn match_bits(n: u8, mask: u8) -> bool {
  139. n & mask == mask
  140. }
  141. let b = try!(self.next());
  142. if match_bits(b, 0xff) { self.continue_prefix_int(8, 0) }
  143. else if match_bits(b, 0xfe) { self.continue_prefix_int(7, 0) }
  144. else if match_bits(b, 0xfc) { self.continue_prefix_int(6, b & 0x01) }
  145. else if match_bits(b, 0xf8) { self.continue_prefix_int(5, b & 0x03) }
  146. else if match_bits(b, 0xf0) { self.continue_prefix_int(4, b & 0x07) }
  147. else if match_bits(b, 0xe0) { self.continue_prefix_int(3, b & 0x0f) }
  148. else if match_bits(b, 0xc0) { self.continue_prefix_int(2, b & 0x1f) }
  149. else if match_bits(b, 0x80) { self.continue_prefix_int(1, b & 0x3f) }
  150. else { self.continue_prefix_int(0, b) }
  151. }
  152. /// This is a helper function for parsing prefix ints, too.
  153. fn continue_prefix_int(&mut self, mut left: u8, upper: u8) -> Result<u64, String> {
  154. let mut ret = upper as u64;
  155. while left > 0 {
  156. left -= 1;
  157. ret = (ret << 8) | try!(self.next()) as u64;
  158. }
  159. Ok(ret)
  160. }
  161. /// This reads a PrefixInteger to find out how many other things to read,
  162. /// and then reads that number of things.
  163. pub fn read_several<F, R>(&mut self, reader: F) -> Result<Vec<R>, String>
  164. where F: Fn(&mut ByteReader<T>) -> Result<R, String>
  165. {
  166. let ct = try!(self.read_prefix_int());
  167. let mut ret = Vec::with_capacity(ct as usize);
  168. for _ in 0..ct {
  169. ret.push(try!(reader(self)))
  170. }
  171. Ok(ret)
  172. }
  173. /// This reads a PrefixInteger number of bytes, and then parses those
  174. /// bytes as a UTF-8 string. This means, importantly, that we cannot
  175. /// naïvely produce values intended to be parsed with this using a
  176. /// basic string length.
  177. pub fn read_string(&mut self) -> Result<String, String> {
  178. let raw_bytes = try!(self.read_several(|r| r.next()));
  179. match String::from_utf8(raw_bytes) {
  180. Ok(s) => Ok(s),
  181. Err(e) => Err(format!("Exception when parsing UTF-8: {:?}", e)),
  182. }
  183. }
  184. }