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