1use error::*;
2use formatter::*;
3use util;
4
5use std::{i32, usize};
6use std::borrow::Cow;
7use std::ops::Deref;
8use std::string::String;
9use std::io::{Seek, SeekFrom};
11use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
12
13impl<R> Formatter<u8> for R where R: Seek + ReadBytesExt + WriteBytesExt {
14
15 fn serialize(&mut self, offset: u64, value: u8) -> ZeroFormatterResult<i32> {
16 try!(self.seek(SeekFrom::Start(offset)));
17 try!(self.write_u8(value));
18 Ok(1)
19 }
20
21 fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<u8> {
22 try!(self.seek(SeekFrom::Start(*(offset as &u64))));
23 let n = try!(self.read_u8());
24 *offset += 1;
25 Ok(n)
26 }
27}
28
29impl<R> Formatter<bool> for R where R: Seek + ReadBytesExt + WriteBytesExt {
30
31 fn serialize(&mut self, offset: u64, value: bool) -> ZeroFormatterResult<i32> {
32 let i: u8 = if value { 1 } else { 0 };
33 self.serialize(offset, i)
34 }
35
36 fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<bool> {
37 let n: u8 = try!(self.deserialize(offset));
38 if n == 1 { Ok(true) }
39 else if n == 0 { Ok(false) }
40 else { ZeroFormatterError::invalid_binary(*offset) }
41 }
42}
43
44impl<R> Formatter<i8> for R where R: Seek + ReadBytesExt + WriteBytesExt {
45
46 fn serialize(&mut self, offset: u64, value: i8) -> ZeroFormatterResult<i32> {
47 try!(self.seek(SeekFrom::Start(offset)));
48 try!(self.write_i8(value));
49 Ok(1)
50 }
51
52 fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<i8> {
53 try!(self.seek(SeekFrom::Start(*(offset as &u64))));
54 let n = try!(self.read_i8());
55 *offset += 1;
56 Ok(n)
57 }
58}
59
60macro_rules! primitive_formatter_impl {
61 ($($t:ty; $w:tt; $r:tt; $l:expr),*) => ($(
62 impl<R> Formatter<$t> for R where R: Seek + ReadBytesExt + WriteBytesExt {
63
64 fn serialize(&mut self, offset: u64, value: $t) -> ZeroFormatterResult<i32> {
65 try!(self.seek(SeekFrom::Start(offset)));
66 try!(self.$w::<LittleEndian>(value));
67 Ok($l)
68 }
69
70 fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<$t> {
71 try!(self.seek(SeekFrom::Start(*(offset as &u64))));
72 let n = try!(self.$r::<LittleEndian>());
73 *offset += $l;
74 Ok(n)
75 }
76 }
77 )*)
78}
79
80primitive_formatter_impl! {
81 u16; write_u16; read_u16; 2,
82 u32; write_u32; read_u32; 4,
83 u64; write_u64; read_u64; 8,
84 i16; write_i16; read_i16; 2,
85 i32; write_i32; read_i32; 4,
86 i64; write_i64; read_i64; 8,
87 f32; write_f32; read_f32; 4,
88 f64; write_f64; read_f64; 8
89}
90
91impl<'a, R> Formatter<Cow<'a, str>> for R where R: Seek + ReadBytesExt + WriteBytesExt {
92
93 fn serialize(&mut self, offset: u64, value: Cow<'a, str>) -> ZeroFormatterResult<i32> {
94 let bytes = value.deref().as_bytes();
95 let l = bytes.len();
96 let i = l as i32;
98 try!(self.seek(SeekFrom::Start(offset)));
99 try!(self.write_i32::<LittleEndian>(i));
100 try!(self.write(bytes));
101 Ok(i + 4)
102 }
103
104 fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<Cow<'a, str>> {
105 let i: i32 = try!(util::check_non_null(self, offset));
106 let l = i as usize;
108 let mut buf = Vec::with_capacity(l);
109 unsafe { buf.set_len(l); }
110 try!(self.read(&mut buf));
111 *offset += l as u64;
112 let s = try!(String::from_utf8(buf));
113 Ok(s.into())
114 }
115}
116
117#[cfg(test)]
118mod tests {
119
120 use std::io::Cursor;
121 use std::borrow::Cow;
122 use formatter::*;
123
124 #[test]
125 fn serialize_true() {
126 let mut wtr = Cursor::new(Vec::new());
127 assert_eq!(wtr.serialize(0, true).unwrap(), 1);
128 assert_eq!(wtr.into_inner(), vec![1]);
129 }
130
131 #[test]
132 fn deserialize_true() {
133 let mut rdr = Cursor::new(vec![1]);
134 let mut offset = 0;
135 assert_eq!(true, rdr.deserialize(&mut offset).unwrap());
136 }
137
138 #[test]
139 fn serialize_false() {
140 let mut wtr = Cursor::new(Vec::new());
141 assert_eq!(wtr.serialize(0, false).unwrap(), 1);
142 assert_eq!(wtr.into_inner(), vec![0]);
143 }
144
145 #[test]
146 fn deserialize_false() {
147 let mut rdr = Cursor::new(vec![0]);
148 let mut offset = 0;
149 assert_eq!(false, rdr.deserialize(&mut offset).unwrap());
150 }
151
152 #[test]
153 fn serialize_u8() {
154 let mut wtr = Cursor::new(Vec::new());
155 assert_eq!(wtr.serialize(0, 1u8).unwrap(), 1);
156 assert_eq!(wtr.into_inner(), vec![1]);
157 }
158
159 #[test]
160 fn deserialize_u8() {
161 let mut rdr = Cursor::new(vec![1]);
162 let mut offset = 0;
163 assert_eq!(1u8, rdr.deserialize(&mut offset).unwrap());
164 }
165
166 #[test]
167 fn serialize_u16() {
168 let mut wtr = Cursor::new(Vec::new());
169 assert_eq!(wtr.serialize(0, 1u16).unwrap(), 2);
170 assert_eq!(wtr.into_inner(), vec![1, 0]);
171 }
172
173 #[test]
174 fn deserialize_u16() {
175 let mut rdr = Cursor::new(vec![1, 0]);
176 let mut offset = 0;
177 assert_eq!(1u16, rdr.deserialize(&mut offset).unwrap());
178 }
179
180 #[test]
181 fn serialize_u32() {
182 let mut wtr = Cursor::new(Vec::new());
183 assert_eq!(wtr.serialize(0, 1u32).unwrap(), 4);
184 assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0]);
185 }
186
187 #[test]
188 fn deserialize_u32() {
189 let mut rdr = Cursor::new(vec![1, 0, 0, 0]);
190 let mut offset = 0;
191 assert_eq!(1u32, rdr.deserialize(&mut offset).unwrap());
192 }
193
194 #[test]
195 fn serialize_u64() {
196 let mut wtr = Cursor::new(Vec::new());
197 assert_eq!(wtr.serialize(0, 1u64).unwrap(), 8);
198 assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
199 }
200
201 #[test]
202 fn deserialize_u64() {
203 let mut rdr = Cursor::new(vec![1, 0, 0, 0, 0, 0, 0, 0]);
204 let mut offset = 0;
205 assert_eq!(1u64, rdr.deserialize(&mut offset).unwrap());
206 }
207
208 #[test]
209 fn serialize_i8() {
210 let mut wtr = Cursor::new(Vec::new());
211 assert_eq!(wtr.serialize(0, 1i8).unwrap(), 1);
212 assert_eq!(wtr.into_inner(), vec![1]);
213 }
214
215 #[test]
216 fn deserialize_i8() {
217 let mut rdr = Cursor::new(vec![1]);
218 let mut offset = 0;
219 assert_eq!(1i8, rdr.deserialize(&mut offset).unwrap());
220 }
221
222 #[test]
223 fn serialize_i16() {
224 let mut wtr = Cursor::new(Vec::new());
225 assert_eq!(wtr.serialize(0, 1i16).unwrap(), 2);
226 assert_eq!(wtr.into_inner(), vec![1, 0]);
227 }
228
229 #[test]
230 fn deserialize_i16() {
231 let mut rdr = Cursor::new(vec![1, 0]);
232 let mut offset = 0;
233 assert_eq!(1i16, rdr.deserialize(&mut offset).unwrap());
234 }
235
236 #[test]
237 fn serialize_i32() {
238 let mut wtr = Cursor::new(Vec::new());
239 assert_eq!(wtr.serialize(0, 1i32).unwrap(), 4);
240 assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0]);
241 }
242
243 #[test]
244 fn deserialize_i32() {
245 let mut rdr = Cursor::new(vec![1, 0, 0, 0]);
246 let mut offset = 0;
247 assert_eq!(1i32, rdr.deserialize(&mut offset).unwrap());
248 }
249
250 #[test]
251 fn serialize_i64() {
252 let mut wtr = Cursor::new(Vec::new());
253 assert_eq!(wtr.serialize(0, 1i64).unwrap(), 8);
254 assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
255 }
256
257 #[test]
258 fn deserialize_i64() {
259 let mut rdr = Cursor::new(vec![1, 0, 0, 0, 0, 0, 0, 0]);
260 let mut offset = 0;
261 assert_eq!(1i64, rdr.deserialize(&mut offset).unwrap());
262 }
263
264 #[test]
265 fn serialize_f32() {
266 let mut wtr = Cursor::new(Vec::new());
267 assert_eq!(wtr.serialize(0, 123.0f32).unwrap(), 4);
268 assert_eq!(wtr.into_inner(), vec![0, 0, 0xf6, 0x42]);
269 }
270
271 #[test]
272 fn deserialize_f32() {
273 let mut rdr = Cursor::new(vec![0, 0, 0xf6, 0x42]);
274 let mut offset = 0;
275 assert_eq!(123.0f32, rdr.deserialize(&mut offset).unwrap());
276 }
277
278 #[test]
279 fn serialize_f64() {
280 let mut wtr = Cursor::new(Vec::new());
281 assert_eq!(wtr.serialize(0, 123.0f64).unwrap(), 8);
282 assert_eq!(wtr.into_inner(), vec![0, 0, 0, 0, 0, 0xc0, 0x5e, 0x40]);
283 }
284
285 #[test]
286 fn deserialize_f64() {
287 let mut rdr = Cursor::new(vec![0, 0, 0, 0, 0, 0xc0, 0x5e, 0x40]);
288 let mut offset = 0;
289 assert_eq!(123.0f64, rdr.deserialize(&mut offset).unwrap());
290 }
291
292 #[test]
293 fn serialize_str() {
294 let mut wtr = Cursor::new(Vec::new());
295 assert_eq!(wtr.serialize(0, Cow::Borrowed("あいうえお")).unwrap(), 19);
296 assert_eq!(wtr.into_inner(), vec![0x0f, 0, 0, 0, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a]);
297 }
298
299 #[test]
300 fn deserialize_str() {
301 let mut rdr = Cursor::new(vec![0x0f, 0, 0, 0, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a]);
302 let mut offset = 0;
303 let actual: Cow<'static, str> = rdr.deserialize(&mut offset).unwrap();
304 assert_eq!(offset, 19);
305 assert_eq!(Cow::Borrowed("あいうえお"), actual);
306 }
307}