]> git.lizzy.rs Git - rust.git/blob - src/libserialize/opaque.rs
Auto merge of #56962 - nivkner:fixme_fixup4, r=pnkfelix
[rust.git] / src / libserialize / opaque.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use leb128::{self, read_signed_leb128, write_signed_leb128};
12 use std::borrow::Cow;
13 use serialize;
14
15 // -----------------------------------------------------------------------------
16 // Encoder
17 // -----------------------------------------------------------------------------
18
19 pub type EncodeResult = Result<(), !>;
20
21 pub struct Encoder {
22     pub data: Vec<u8>,
23 }
24
25 impl Encoder {
26     pub fn new(data: Vec<u8>) -> Encoder {
27         Encoder { data }
28     }
29
30     pub fn into_inner(self) -> Vec<u8> {
31         self.data
32     }
33
34     #[inline]
35     pub fn emit_raw_bytes(&mut self, s: &[u8]) {
36         self.data.extend_from_slice(s);
37     }
38 }
39
40 macro_rules! write_uleb128 {
41     ($enc:expr, $value:expr, $fun:ident) => {{
42         leb128::$fun(&mut $enc.data, $value);
43         Ok(())
44     }}
45 }
46
47 macro_rules! write_sleb128 {
48     ($enc:expr, $value:expr) => {{
49         write_signed_leb128(&mut $enc.data, $value as i128);
50         Ok(())
51     }}
52 }
53
54 impl serialize::Encoder for Encoder {
55     type Error = !;
56
57     #[inline]
58     fn emit_unit(&mut self) -> EncodeResult {
59         Ok(())
60     }
61
62     #[inline]
63     fn emit_usize(&mut self, v: usize) -> EncodeResult {
64         write_uleb128!(self, v, write_usize_leb128)
65     }
66
67     #[inline]
68     fn emit_u128(&mut self, v: u128) -> EncodeResult {
69         write_uleb128!(self, v, write_u128_leb128)
70     }
71
72     #[inline]
73     fn emit_u64(&mut self, v: u64) -> EncodeResult {
74         write_uleb128!(self, v, write_u64_leb128)
75     }
76
77     #[inline]
78     fn emit_u32(&mut self, v: u32) -> EncodeResult {
79         write_uleb128!(self, v, write_u32_leb128)
80     }
81
82     #[inline]
83     fn emit_u16(&mut self, v: u16) -> EncodeResult {
84         write_uleb128!(self, v, write_u16_leb128)
85     }
86
87     #[inline]
88     fn emit_u8(&mut self, v: u8) -> EncodeResult {
89         self.data.push(v);
90         Ok(())
91     }
92
93     #[inline]
94     fn emit_isize(&mut self, v: isize) -> EncodeResult {
95         write_sleb128!(self, v)
96     }
97
98     #[inline]
99     fn emit_i128(&mut self, v: i128) -> EncodeResult {
100         write_sleb128!(self, v)
101     }
102
103     #[inline]
104     fn emit_i64(&mut self, v: i64) -> EncodeResult {
105         write_sleb128!(self, v)
106     }
107
108     #[inline]
109     fn emit_i32(&mut self, v: i32) -> EncodeResult {
110         write_sleb128!(self, v)
111     }
112
113     #[inline]
114     fn emit_i16(&mut self, v: i16) -> EncodeResult {
115         write_sleb128!(self, v)
116     }
117
118     #[inline]
119     fn emit_i8(&mut self, v: i8) -> EncodeResult {
120         let as_u8: u8 = unsafe { ::std::mem::transmute(v) };
121         self.emit_u8(as_u8)
122     }
123
124     #[inline]
125     fn emit_bool(&mut self, v: bool) -> EncodeResult {
126         self.emit_u8(if v {
127             1
128         } else {
129             0
130         })
131     }
132
133     #[inline]
134     fn emit_f64(&mut self, v: f64) -> EncodeResult {
135         let as_u64: u64 = unsafe { ::std::mem::transmute(v) };
136         self.emit_u64(as_u64)
137     }
138
139     #[inline]
140     fn emit_f32(&mut self, v: f32) -> EncodeResult {
141         let as_u32: u32 = unsafe { ::std::mem::transmute(v) };
142         self.emit_u32(as_u32)
143     }
144
145     #[inline]
146     fn emit_char(&mut self, v: char) -> EncodeResult {
147         self.emit_u32(v as u32)
148     }
149
150     #[inline]
151     fn emit_str(&mut self, v: &str) -> EncodeResult {
152         self.emit_usize(v.len())?;
153         self.emit_raw_bytes(v.as_bytes());
154         Ok(())
155     }
156 }
157
158 impl Encoder {
159     #[inline]
160     pub fn position(&self) -> usize {
161         self.data.len()
162     }
163 }
164
165 // -----------------------------------------------------------------------------
166 // Decoder
167 // -----------------------------------------------------------------------------
168
169 pub struct Decoder<'a> {
170     pub data: &'a [u8],
171     position: usize,
172 }
173
174 impl<'a> Decoder<'a> {
175     #[inline]
176     pub fn new(data: &'a [u8], position: usize) -> Decoder<'a> {
177         Decoder {
178             data,
179             position,
180         }
181     }
182
183     #[inline]
184     pub fn position(&self) -> usize {
185         self.position
186     }
187
188     #[inline]
189     pub fn set_position(&mut self, pos: usize) {
190         self.position = pos
191     }
192
193     #[inline]
194     pub fn advance(&mut self, bytes: usize) {
195         self.position += bytes;
196     }
197
198     #[inline]
199     pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> {
200         let start = self.position;
201         let end = start + s.len();
202
203         s.copy_from_slice(&self.data[start..end]);
204
205         self.position = end;
206
207         Ok(())
208     }
209 }
210
211 macro_rules! read_uleb128 {
212     ($dec:expr, $t:ty, $fun:ident) => ({
213         let (value, bytes_read) = leb128::$fun(&$dec.data[$dec.position ..]);
214         $dec.position += bytes_read;
215         Ok(value)
216     })
217 }
218
219 macro_rules! read_sleb128 {
220     ($dec:expr, $t:ty) => ({
221         let (value, bytes_read) = read_signed_leb128($dec.data, $dec.position);
222         $dec.position += bytes_read;
223         Ok(value as $t)
224     })
225 }
226
227
228 impl<'a> serialize::Decoder for Decoder<'a> {
229     type Error = String;
230
231     #[inline]
232     fn read_nil(&mut self) -> Result<(), Self::Error> {
233         Ok(())
234     }
235
236     #[inline]
237     fn read_u128(&mut self) -> Result<u128, Self::Error> {
238         read_uleb128!(self, u128, read_u128_leb128)
239     }
240
241     #[inline]
242     fn read_u64(&mut self) -> Result<u64, Self::Error> {
243         read_uleb128!(self, u64, read_u64_leb128)
244     }
245
246     #[inline]
247     fn read_u32(&mut self) -> Result<u32, Self::Error> {
248         read_uleb128!(self, u32, read_u32_leb128)
249     }
250
251     #[inline]
252     fn read_u16(&mut self) -> Result<u16, Self::Error> {
253         read_uleb128!(self, u16, read_u16_leb128)
254     }
255
256     #[inline]
257     fn read_u8(&mut self) -> Result<u8, Self::Error> {
258         let value = self.data[self.position];
259         self.position += 1;
260         Ok(value)
261     }
262
263     #[inline]
264     fn read_usize(&mut self) -> Result<usize, Self::Error> {
265         read_uleb128!(self, usize, read_usize_leb128)
266     }
267
268     #[inline]
269     fn read_i128(&mut self) -> Result<i128, Self::Error> {
270         read_sleb128!(self, i128)
271     }
272
273     #[inline]
274     fn read_i64(&mut self) -> Result<i64, Self::Error> {
275         read_sleb128!(self, i64)
276     }
277
278     #[inline]
279     fn read_i32(&mut self) -> Result<i32, Self::Error> {
280         read_sleb128!(self, i32)
281     }
282
283     #[inline]
284     fn read_i16(&mut self) -> Result<i16, Self::Error> {
285         read_sleb128!(self, i16)
286     }
287
288     #[inline]
289     fn read_i8(&mut self) -> Result<i8, Self::Error> {
290         let as_u8 = self.data[self.position];
291         self.position += 1;
292         unsafe { Ok(::std::mem::transmute(as_u8)) }
293     }
294
295     #[inline]
296     fn read_isize(&mut self) -> Result<isize, Self::Error> {
297         read_sleb128!(self, isize)
298     }
299
300     #[inline]
301     fn read_bool(&mut self) -> Result<bool, Self::Error> {
302         let value = self.read_u8()?;
303         Ok(value != 0)
304     }
305
306     #[inline]
307     fn read_f64(&mut self) -> Result<f64, Self::Error> {
308         let bits = self.read_u64()?;
309         Ok(unsafe { ::std::mem::transmute(bits) })
310     }
311
312     #[inline]
313     fn read_f32(&mut self) -> Result<f32, Self::Error> {
314         let bits = self.read_u32()?;
315         Ok(unsafe { ::std::mem::transmute(bits) })
316     }
317
318     #[inline]
319     fn read_char(&mut self) -> Result<char, Self::Error> {
320         let bits = self.read_u32()?;
321         Ok(::std::char::from_u32(bits).unwrap())
322     }
323
324     #[inline]
325     fn read_str(&mut self) -> Result<Cow<str>, Self::Error> {
326         let len = self.read_usize()?;
327         let s = ::std::str::from_utf8(&self.data[self.position..self.position + len]).unwrap();
328         self.position += len;
329         Ok(Cow::Borrowed(s))
330     }
331
332     #[inline]
333     fn error(&mut self, err: &str) -> Self::Error {
334         err.to_string()
335     }
336 }
337
338
339 #[cfg(test)]
340 mod tests {
341     use serialize::{Encodable, Decodable};
342     use std::fmt::Debug;
343     use super::{Encoder, Decoder};
344
345     #[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
346     struct Struct {
347         a: (),
348         b: u8,
349         c: u16,
350         d: u32,
351         e: u64,
352         f: usize,
353
354         g: i8,
355         h: i16,
356         i: i32,
357         j: i64,
358         k: isize,
359
360         l: char,
361         m: String,
362         n: f32,
363         o: f64,
364         p: bool,
365         q: Option<u32>,
366     }
367
368
369     fn check_round_trip<T: Encodable + Decodable + PartialEq + Debug>(values: Vec<T>) {
370         let mut encoder = Encoder::new(Vec::new());
371
372         for value in &values {
373             Encodable::encode(&value, &mut encoder).unwrap();
374         }
375
376         let data = encoder.into_inner();
377         let mut decoder = Decoder::new(&data[..], 0);
378
379         for value in values {
380             let decoded = Decodable::decode(&mut decoder).unwrap();
381             assert_eq!(value, decoded);
382         }
383     }
384
385     #[test]
386     fn test_unit() {
387         check_round_trip(vec![(), (), (), ()]);
388     }
389
390     #[test]
391     fn test_u8() {
392         let mut vec = vec![];
393         for i in ::std::u8::MIN..::std::u8::MAX {
394             vec.push(i);
395         }
396         check_round_trip(vec);
397     }
398
399     #[test]
400     fn test_u16() {
401         for i in ::std::u16::MIN..::std::u16::MAX {
402             check_round_trip(vec![1, 2, 3, i, i, i]);
403         }
404     }
405
406     #[test]
407     fn test_u32() {
408         check_round_trip(vec![1, 2, 3, ::std::u32::MIN, 0, 1, ::std::u32::MAX, 2, 1]);
409     }
410
411     #[test]
412     fn test_u64() {
413         check_round_trip(vec![1, 2, 3, ::std::u64::MIN, 0, 1, ::std::u64::MAX, 2, 1]);
414     }
415
416     #[test]
417     fn test_usize() {
418         check_round_trip(vec![1, 2, 3, ::std::usize::MIN, 0, 1, ::std::usize::MAX, 2, 1]);
419     }
420
421     #[test]
422     fn test_i8() {
423         let mut vec = vec![];
424         for i in ::std::i8::MIN..::std::i8::MAX {
425             vec.push(i);
426         }
427         check_round_trip(vec);
428     }
429
430     #[test]
431     fn test_i16() {
432         for i in ::std::i16::MIN..::std::i16::MAX {
433             check_round_trip(vec![-1, 2, -3, i, i, i, 2]);
434         }
435     }
436
437     #[test]
438     fn test_i32() {
439         check_round_trip(vec![-1, 2, -3, ::std::i32::MIN, 0, 1, ::std::i32::MAX, 2, 1]);
440     }
441
442     #[test]
443     fn test_i64() {
444         check_round_trip(vec![-1, 2, -3, ::std::i64::MIN, 0, 1, ::std::i64::MAX, 2, 1]);
445     }
446
447     #[test]
448     fn test_isize() {
449         check_round_trip(vec![-1, 2, -3, ::std::isize::MIN, 0, 1, ::std::isize::MAX, 2, 1]);
450     }
451
452     #[test]
453     fn test_bool() {
454         check_round_trip(vec![false, true, true, false, false]);
455     }
456
457     #[test]
458     fn test_f32() {
459         let mut vec = vec![];
460         for i in -100..100 {
461             vec.push((i as f32) / 3.0);
462         }
463         check_round_trip(vec);
464     }
465
466     #[test]
467     fn test_f64() {
468         let mut vec = vec![];
469         for i in -100..100 {
470             vec.push((i as f64) / 3.0);
471         }
472         check_round_trip(vec);
473     }
474
475     #[test]
476     fn test_char() {
477         let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€'];
478         check_round_trip(vec);
479     }
480
481     #[test]
482     fn test_string() {
483         let vec = vec!["abcbuÖeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
484                        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
485                        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpapmaebn".to_string(),
486                        "abcbuÖganeiovÄnameÜavmpßvmeabpnvapeapmaebn".to_string(),
487                        "abcbuÖganeiÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
488                        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpmaebn".to_string(),
489                        "abcbuÖganeiovÄnameÜavmpßvmea€µnvapeapmaebn".to_string()];
490
491         check_round_trip(vec);
492     }
493
494     #[test]
495     fn test_option() {
496         check_round_trip(vec![Some(-1i8)]);
497         check_round_trip(vec![Some(-2i16)]);
498         check_round_trip(vec![Some(-3i32)]);
499         check_round_trip(vec![Some(-4i64)]);
500         check_round_trip(vec![Some(-5isize)]);
501
502         let none_i8: Option<i8> = None;
503         check_round_trip(vec![none_i8]);
504
505         let none_i16: Option<i16> = None;
506         check_round_trip(vec![none_i16]);
507
508         let none_i32: Option<i32> = None;
509         check_round_trip(vec![none_i32]);
510
511         let none_i64: Option<i64> = None;
512         check_round_trip(vec![none_i64]);
513
514         let none_isize: Option<isize> = None;
515         check_round_trip(vec![none_isize]);
516     }
517
518     #[test]
519     fn test_struct() {
520         check_round_trip(vec![Struct {
521                                   a: (),
522                                   b: 10,
523                                   c: 11,
524                                   d: 12,
525                                   e: 13,
526                                   f: 14,
527
528                                   g: 15,
529                                   h: 16,
530                                   i: 17,
531                                   j: 18,
532                                   k: 19,
533
534                                   l: 'x',
535                                   m: "abc".to_string(),
536                                   n: 20.5,
537                                   o: 21.5,
538                                   p: false,
539                                   q: None,
540                               }]);
541
542         check_round_trip(vec![Struct {
543                                   a: (),
544                                   b: 101,
545                                   c: 111,
546                                   d: 121,
547                                   e: 131,
548                                   f: 141,
549
550                                   g: -15,
551                                   h: -16,
552                                   i: -17,
553                                   j: -18,
554                                   k: -19,
555
556                                   l: 'y',
557                                   m: "def".to_string(),
558                                   n: -20.5,
559                                   o: -21.5,
560                                   p: true,
561                                   q: Some(1234567),
562                               }]);
563     }
564
565     #[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
566     enum Enum {
567         Variant1,
568         Variant2(usize, f32),
569         Variant3 {
570             a: i32,
571             b: char,
572             c: bool,
573         },
574     }
575
576     #[test]
577     fn test_enum() {
578         check_round_trip(vec![Enum::Variant1,
579                               Enum::Variant2(1, 2.5),
580                               Enum::Variant3 {
581                                   a: 3,
582                                   b: 'b',
583                                   c: false,
584                               },
585                               Enum::Variant3 {
586                                   a: -4,
587                                   b: 'f',
588                                   c: true,
589                               }]);
590     }
591
592     #[test]
593     fn test_sequence() {
594         let mut vec = vec![];
595         for i in -100i64..100i64 {
596             vec.push(i * 100000);
597         }
598
599         check_round_trip(vec![vec]);
600     }
601
602     #[test]
603     fn test_hash_map() {
604         use std::collections::HashMap;
605         let mut map = HashMap::new();
606         for i in -100i64..100i64 {
607             map.insert(i * 100000, i * 10000);
608         }
609
610         check_round_trip(vec![map]);
611     }
612
613     #[test]
614     fn test_tuples() {
615         check_round_trip(vec![('x', (), false, 0.5f32)]);
616         check_round_trip(vec![(9i8, 10u16, 1.5f64)]);
617         check_round_trip(vec![(-12i16, 11u8, 12usize)]);
618         check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
619         check_round_trip(vec![(String::new(), "some string".to_string())]);
620     }
621 }