]> git.lizzy.rs Git - rust.git/blob - src/librbml/lib.rs
41ae0f2d5e203ca1c89dce2f0eda33e35f3a9353
[rust.git] / src / librbml / lib.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 //! Really Bad Markup Language (rbml) is an internal serialization format of rustc.
12 //! This is not intended to be used by users.
13 //!
14 //! Originally based on the Extensible Binary Markup Language
15 //! (ebml; http://www.matroska.org/technical/specs/rfc/index.html),
16 //! it is now a separate format tuned for the rust object metadata.
17 //!
18 //! # Encoding
19 //!
20 //! RBML document consists of the tag, length and data.
21 //! The encoded data can contain multiple RBML documents concatenated.
22 //!
23 //! **Tags** are a hint for the following data.
24 //! Tags are a number from 0x000 to 0xfff, where 0xf0 through 0xff is reserved.
25 //! Tags less than 0xf0 are encoded in one literal byte.
26 //! Tags greater than 0xff are encoded in two big-endian bytes,
27 //! where the tag number is ORed with 0xf000. (E.g. tag 0x123 = `f1 23`)
28 //!
29 //! **Lengths** encode the length of the following data.
30 //! It is a variable-length unsigned isize, and one of the following forms:
31 //!
32 //! - `80` through `fe` for lengths up to 0x7e;
33 //! - `40 ff` through `7f ff` for lengths up to 0x3fff;
34 //! - `20 40 00` through `3f ff ff` for lengths up to 0x1fffff;
35 //! - `10 20 00 00` through `1f ff ff ff` for lengths up to 0xfffffff.
36 //!
37 //! The "overlong" form is allowed so that the length can be encoded
38 //! without the prior knowledge of the encoded data.
39 //! For example, the length 0 can be represented either by `80`, `40 00`,
40 //! `20 00 00` or `10 00 00 00`.
41 //! The encoder tries to minimize the length if possible.
42 //! Also, some predefined tags listed below are so commonly used that
43 //! their lengths are omitted ("implicit length").
44 //!
45 //! **Data** can be either binary bytes or zero or more nested RBML documents.
46 //! Nested documents cannot overflow, and should be entirely contained
47 //! within a parent document.
48 //!
49 //! # Predefined Tags
50 //!
51 //! Most RBML tags are defined by the application.
52 //! (For the rust object metadata, see also `rustc::metadata::common`.)
53 //! RBML itself does define a set of predefined tags however,
54 //! intended for the auto-serialization implementation.
55 //!
56 //! Predefined tags with an implicit length:
57 //!
58 //! - `U8`  (`00`): 1-byte unsigned integer.
59 //! - `U16` (`01`): 2-byte big endian unsigned integer.
60 //! - `U32` (`02`): 4-byte big endian unsigned integer.
61 //! - `U64` (`03`): 8-byte big endian unsigned integer.
62 //!   Any of `U*` tags can be used to encode primitive unsigned integer types,
63 //!   as long as it is no greater than the actual size.
64 //!   For example, `u8` can only be represented via the `U8` tag.
65 //!
66 //! - `I8`  (`04`): 1-byte signed integer.
67 //! - `I16` (`05`): 2-byte big endian signed integer.
68 //! - `I32` (`06`): 4-byte big endian signed integer.
69 //! - `I64` (`07`): 8-byte big endian signed integer.
70 //!   Similar to `U*` tags. Always uses two's complement encoding.
71 //!
72 //! - `Bool` (`08`): 1-byte boolean value, `00` for false and `01` for true.
73 //!
74 //! - `Char` (`09`): 4-byte big endian Unicode scalar value.
75 //!   Surrogate pairs or out-of-bound values are invalid.
76 //!
77 //! - `F32` (`0a`): 4-byte big endian unsigned integer representing
78 //!   IEEE 754 binary32 floating-point format.
79 //! - `F64` (`0b`): 8-byte big endian unsigned integer representing
80 //!   IEEE 754 binary64 floating-point format.
81 //!
82 //! - `Sub8`  (`0c`): 1-byte unsigned integer for supplementary information.
83 //! - `Sub32` (`0d`): 4-byte unsigned integer for supplementary information.
84 //!   Those two tags normally occur as the first subdocument of certain tags,
85 //!   namely `Enum`, `Vec` and `Map`, to provide a variant or size information.
86 //!   They can be used interchangeably.
87 //!
88 //! Predefined tags with an explicit length:
89 //!
90 //! - `Str` (`10`): A UTF-8-encoded string.
91 //!
92 //! - `Enum` (`11`): An enum.
93 //!   The first subdocument should be `Sub*` tags with a variant ID.
94 //!   Subsequent subdocuments, if any, encode variant arguments.
95 //!
96 //! - `Vec` (`12`): A vector (sequence).
97 //! - `VecElt` (`13`): A vector element.
98 //!   The first subdocument should be `Sub*` tags with the number of elements.
99 //!   Subsequent subdocuments should be `VecElt` tag per each element.
100 //!
101 //! - `Map` (`14`): A map (associated array).
102 //! - `MapKey` (`15`): A key part of the map entry.
103 //! - `MapVal` (`16`): A value part of the map entry.
104 //!   The first subdocument should be `Sub*` tags with the number of entries.
105 //!   Subsequent subdocuments should be an alternating sequence of
106 //!   `MapKey` and `MapVal` tags per each entry.
107 //!
108 //! - `Opaque` (`17`): An opaque, custom-format tag.
109 //!   Used to wrap ordinary custom tags or data in the auto-serialized context.
110 //!   Rustc typically uses this to encode type informations.
111 //!
112 //! First 0x20 tags are reserved by RBML; custom tags start at 0x20.
113
114 // Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
115 #![cfg_attr(stage0, feature(custom_attribute))]
116 #![crate_name = "rbml"]
117 #![unstable(feature = "rustc_private")]
118 #![staged_api]
119 #![crate_type = "rlib"]
120 #![crate_type = "dylib"]
121 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
122        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
123        html_root_url = "http://doc.rust-lang.org/nightly/",
124        html_playground_url = "http://play.rust-lang.org/")]
125
126 #![feature(core)]
127 #![feature(rustc_private)]
128 #![feature(staged_api)]
129
130 #![cfg_attr(test, feature(test))]
131
132 extern crate serialize;
133 #[macro_use] extern crate log;
134
135 #[cfg(test)] extern crate test;
136
137 pub use self::EbmlEncoderTag::*;
138 pub use self::Error::*;
139
140 use std::str;
141 use std::fmt;
142
143 /// Common data structures
144 #[derive(Clone, Copy)]
145 pub struct Doc<'a> {
146     pub data: &'a [u8],
147     pub start: usize,
148     pub end: usize,
149 }
150
151 impl<'doc> Doc<'doc> {
152     pub fn new(data: &'doc [u8]) -> Doc<'doc> {
153         Doc { data: data, start: 0, end: data.len() }
154     }
155
156     pub fn get<'a>(&'a self, tag: usize) -> Doc<'a> {
157         reader::get_doc(*self, tag)
158     }
159
160     pub fn is_empty(&self) -> bool {
161         self.start == self.end
162     }
163
164     pub fn as_str_slice<'a>(&'a self) -> &'a str {
165         str::from_utf8(&self.data[self.start..self.end]).unwrap()
166     }
167
168     pub fn as_str(&self) -> String {
169         self.as_str_slice().to_string()
170     }
171 }
172
173 pub struct TaggedDoc<'a> {
174     tag: usize,
175     pub doc: Doc<'a>,
176 }
177
178 #[derive(Copy, Clone, Debug)]
179 pub enum EbmlEncoderTag {
180     // tags 00..1f are reserved for auto-serialization.
181     // first NUM_IMPLICIT_TAGS tags are implicitly sized and lengths are not encoded.
182
183     EsU8       = 0x00, // + 1 byte
184     EsU16      = 0x01, // + 2 bytes
185     EsU32      = 0x02, // + 4 bytes
186     EsU64      = 0x03, // + 8 bytes
187     EsI8       = 0x04, // + 1 byte
188     EsI16      = 0x05, // + 2 bytes
189     EsI32      = 0x06, // + 4 bytes
190     EsI64      = 0x07, // + 8 bytes
191     EsBool     = 0x08, // + 1 byte
192     EsChar     = 0x09, // + 4 bytes
193     EsF32      = 0x0a, // + 4 bytes
194     EsF64      = 0x0b, // + 8 bytes
195     EsSub8     = 0x0c, // + 1 byte
196     EsSub32    = 0x0d, // + 4 bytes
197     // 0x0e and 0x0f are reserved
198
199     EsStr      = 0x10,
200     EsEnum     = 0x11, // encodes the variant id as the first EsSub*
201     EsVec      = 0x12, // encodes the # of elements as the first EsSub*
202     EsVecElt   = 0x13,
203     EsMap      = 0x14, // encodes the # of pairs as the first EsSub*
204     EsMapKey   = 0x15,
205     EsMapVal   = 0x16,
206     EsOpaque   = 0x17,
207 }
208
209 const NUM_TAGS: usize = 0x1000;
210 const NUM_IMPLICIT_TAGS: usize = 0x0e;
211
212 static TAG_IMPLICIT_LEN: [i8; NUM_IMPLICIT_TAGS] = [
213     1, 2, 4, 8, // EsU*
214     1, 2, 4, 8, // ESI*
215     1, // EsBool
216     4, // EsChar
217     4, 8, // EsF*
218     1, 4, // EsSub*
219 ];
220
221 #[derive(Debug)]
222 pub enum Error {
223     IntTooBig(usize),
224     InvalidTag(usize),
225     Expected(String),
226     IoError(std::io::Error),
227     ApplicationError(String)
228 }
229
230 impl fmt::Display for Error {
231     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
232         // FIXME: this should be a more useful display form
233         fmt::Debug::fmt(self, f)
234     }
235 }
236 // --------------------------------------
237
238 pub mod reader {
239     use std::char;
240
241     use std::isize;
242     use std::mem::transmute;
243     use std::slice::bytes;
244
245     use serialize;
246
247     use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsSub8, EsSub32,
248         EsVecElt, EsMapKey, EsU64, EsU32, EsU16, EsU8, EsI64,
249         EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
250         EsOpaque, EbmlEncoderTag, Doc, TaggedDoc,
251         Error, IntTooBig, InvalidTag, Expected, NUM_IMPLICIT_TAGS, TAG_IMPLICIT_LEN };
252
253     pub type DecodeResult<T> = Result<T, Error>;
254     // rbml reading
255
256     macro_rules! try_or {
257         ($e:expr, $r:expr) => (
258             match $e {
259                 Ok(e) => e,
260                 Err(e) => {
261                     debug!("ignored error: {:?}", e);
262                     return $r
263                 }
264             }
265         )
266     }
267
268     #[derive(Copy, Clone)]
269     pub struct Res {
270         pub val: usize,
271         pub next: usize
272     }
273
274     pub fn tag_at(data: &[u8], start: usize) -> DecodeResult<Res> {
275         let v = data[start] as usize;
276         if v < 0xf0 {
277             Ok(Res { val: v, next: start + 1 })
278         } else if v > 0xf0 {
279             Ok(Res { val: ((v & 0xf) << 8) | data[start + 1] as usize, next: start + 2 })
280         } else {
281             // every tag starting with byte 0xf0 is an overlong form, which is prohibited.
282             Err(InvalidTag(v))
283         }
284     }
285
286     #[inline(never)]
287     fn vuint_at_slow(data: &[u8], start: usize) -> DecodeResult<Res> {
288         let a = data[start];
289         if a & 0x80 != 0 {
290             return Ok(Res {val: (a & 0x7f) as usize, next: start + 1});
291         }
292         if a & 0x40 != 0 {
293             return Ok(Res {val: ((a & 0x3f) as usize) << 8 |
294                         (data[start + 1] as usize),
295                     next: start + 2});
296         }
297         if a & 0x20 != 0 {
298             return Ok(Res {val: ((a & 0x1f) as usize) << 16 |
299                         (data[start + 1] as usize) << 8 |
300                         (data[start + 2] as usize),
301                     next: start + 3});
302         }
303         if a & 0x10 != 0 {
304             return Ok(Res {val: ((a & 0x0f) as usize) << 24 |
305                         (data[start + 1] as usize) << 16 |
306                         (data[start + 2] as usize) << 8 |
307                         (data[start + 3] as usize),
308                     next: start + 4});
309         }
310         Err(IntTooBig(a as usize))
311     }
312
313     pub fn vuint_at(data: &[u8], start: usize) -> DecodeResult<Res> {
314         if data.len() - start < 4 {
315             return vuint_at_slow(data, start);
316         }
317
318         // Lookup table for parsing EBML Element IDs as per
319         // http://ebml.sourceforge.net/specs/ The Element IDs are parsed by
320         // reading a big endian u32 positioned at data[start].  Using the four
321         // most significant bits of the u32 we lookup in the table below how
322         // the element ID should be derived from it.
323         //
324         // The table stores tuples (shift, mask) where shift is the number the
325         // u32 should be right shifted with and mask is the value the right
326         // shifted value should be masked with.  If for example the most
327         // significant bit is set this means it's a class A ID and the u32
328         // should be right shifted with 24 and masked with 0x7f. Therefore we
329         // store (24, 0x7f) at index 0x8 - 0xF (four bit numbers where the most
330         // significant bit is set).
331         //
332         // By storing the number of shifts and masks in a table instead of
333         // checking in order if the most significant bit is set, the second
334         // most significant bit is set etc. we can replace up to three
335         // "and+branch" with a single table lookup which gives us a measured
336         // speedup of around 2x on x86_64.
337         static SHIFT_MASK_TABLE: [(usize, u32); 16] = [
338             (0, 0x0), (0, 0x0fffffff),
339             (8, 0x1fffff), (8, 0x1fffff),
340             (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
341             (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
342             (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
343         ];
344
345         unsafe {
346             let ptr = data.as_ptr().offset(start as isize) as *const u32;
347             let val = u32::from_be(*ptr);
348
349             let i = (val >> 28) as usize;
350             let (shift, mask) = SHIFT_MASK_TABLE[i];
351             Ok(Res {
352                 val: ((val >> shift) & mask) as usize,
353                 next: start + ((32 - shift) >> 3),
354             })
355         }
356     }
357
358     pub fn tag_len_at(data: &[u8], tag: Res) -> DecodeResult<Res> {
359         if tag.val < NUM_IMPLICIT_TAGS && TAG_IMPLICIT_LEN[tag.val] >= 0 {
360             Ok(Res { val: TAG_IMPLICIT_LEN[tag.val] as usize, next: tag.next })
361         } else {
362             vuint_at(data, tag.next)
363         }
364     }
365
366     pub fn doc_at<'a>(data: &'a [u8], start: usize) -> DecodeResult<TaggedDoc<'a>> {
367         let elt_tag = try!(tag_at(data, start));
368         let elt_size = try!(tag_len_at(data, elt_tag));
369         let end = elt_size.next + elt_size.val;
370         Ok(TaggedDoc {
371             tag: elt_tag.val,
372             doc: Doc { data: data, start: elt_size.next, end: end }
373         })
374     }
375
376     pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: usize) -> Option<Doc<'a>> {
377         let mut pos = d.start;
378         while pos < d.end {
379             let elt_tag = try_or!(tag_at(d.data, pos), None);
380             let elt_size = try_or!(tag_len_at(d.data, elt_tag), None);
381             pos = elt_size.next + elt_size.val;
382             if elt_tag.val == tg {
383                 return Some(Doc { data: d.data, start: elt_size.next,
384                                   end: pos });
385             }
386         }
387         None
388     }
389
390     pub fn get_doc<'a>(d: Doc<'a>, tg: usize) -> Doc<'a> {
391         match maybe_get_doc(d, tg) {
392             Some(d) => d,
393             None => {
394                 error!("failed to find block with tag {:?}", tg);
395                 panic!();
396             }
397         }
398     }
399
400     pub fn docs<'a>(d: Doc<'a>) -> DocsIterator<'a> {
401         DocsIterator {
402             d: d
403         }
404     }
405
406     pub struct DocsIterator<'a> {
407         d: Doc<'a>,
408     }
409
410     impl<'a> Iterator for DocsIterator<'a> {
411         type Item = (usize, Doc<'a>);
412
413         fn next(&mut self) -> Option<(usize, Doc<'a>)> {
414             if self.d.start >= self.d.end {
415                 return None;
416             }
417
418             let elt_tag = try_or!(tag_at(self.d.data, self.d.start), {
419                 self.d.start = self.d.end;
420                 None
421             });
422             let elt_size = try_or!(tag_len_at(self.d.data, elt_tag), {
423                 self.d.start = self.d.end;
424                 None
425             });
426
427             let end = elt_size.next + elt_size.val;
428             let doc = Doc {
429                 data: self.d.data,
430                 start: elt_size.next,
431                 end: end,
432             };
433
434             self.d.start = end;
435             return Some((elt_tag.val, doc));
436         }
437     }
438
439     pub fn tagged_docs<'a>(d: Doc<'a>, tag: usize) -> TaggedDocsIterator<'a> {
440         TaggedDocsIterator {
441             iter: docs(d),
442             tag: tag,
443         }
444     }
445
446     pub struct TaggedDocsIterator<'a> {
447         iter: DocsIterator<'a>,
448         tag: usize,
449     }
450
451     impl<'a> Iterator for TaggedDocsIterator<'a> {
452         type Item = Doc<'a>;
453
454         fn next(&mut self) -> Option<Doc<'a>> {
455             while let Some((tag, doc)) = self.iter.next() {
456                 if tag == self.tag {
457                     return Some(doc);
458                 }
459             }
460             None
461         }
462     }
463
464     pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
465         F: FnOnce(&[u8]) -> T,
466     {
467         f(&d.data[d.start..d.end])
468     }
469
470
471     pub fn doc_as_u8(d: Doc) -> u8 {
472         assert_eq!(d.end, d.start + 1);
473         d.data[d.start]
474     }
475
476     pub fn doc_as_u16(d: Doc) -> u16 {
477         assert_eq!(d.end, d.start + 2);
478         let mut b = [0; 2];
479         bytes::copy_memory(&d.data[d.start..d.end], &mut b);
480         unsafe { (*(b.as_ptr() as *const u16)).to_be() }
481     }
482
483     pub fn doc_as_u32(d: Doc) -> u32 {
484         assert_eq!(d.end, d.start + 4);
485         let mut b = [0; 4];
486         bytes::copy_memory(&d.data[d.start..d.end], &mut b);
487         unsafe { (*(b.as_ptr() as *const u32)).to_be() }
488     }
489
490     pub fn doc_as_u64(d: Doc) -> u64 {
491         assert_eq!(d.end, d.start + 8);
492         let mut b = [0; 8];
493         bytes::copy_memory(&d.data[d.start..d.end], &mut b);
494         unsafe { (*(b.as_ptr() as *const u64)).to_be() }
495     }
496
497     pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
498     pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
499     pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
500     pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
501
502     pub struct Decoder<'a> {
503         parent: Doc<'a>,
504         pos: usize,
505     }
506
507     impl<'doc> Decoder<'doc> {
508         pub fn new(d: Doc<'doc>) -> Decoder<'doc> {
509             Decoder {
510                 parent: d,
511                 pos: d.start
512             }
513         }
514
515         fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
516             debug!(". next_doc(exp_tag={:?})", exp_tag);
517             if self.pos >= self.parent.end {
518                 return Err(Expected(format!("no more documents in \
519                                              current node!")));
520             }
521             let TaggedDoc { tag: r_tag, doc: r_doc } =
522                 try!(doc_at(self.parent.data, self.pos));
523             debug!("self.parent={:?}-{:?} self.pos={:?} r_tag={:?} r_doc={:?}-{:?}",
524                    self.parent.start,
525                    self.parent.end,
526                    self.pos,
527                    r_tag,
528                    r_doc.start,
529                    r_doc.end);
530             if r_tag != (exp_tag as usize) {
531                 return Err(Expected(format!("expected EBML doc with tag {:?} but \
532                                              found tag {:?}", exp_tag, r_tag)));
533             }
534             if r_doc.end > self.parent.end {
535                 return Err(Expected(format!("invalid EBML, child extends to \
536                                              {:#x}, parent to {:#x}",
537                                             r_doc.end, self.parent.end)));
538             }
539             self.pos = r_doc.end;
540             Ok(r_doc)
541         }
542
543         fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
544             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
545         {
546             let d = try!(self.next_doc(exp_tag));
547             let old_parent = self.parent;
548             let old_pos = self.pos;
549             self.parent = d;
550             self.pos = d.start;
551             let r = try!(f(self));
552             self.parent = old_parent;
553             self.pos = old_pos;
554             Ok(r)
555         }
556
557         fn _next_sub(&mut self) -> DecodeResult<usize> {
558             // empty vector/map optimization
559             if self.parent.is_empty() {
560                 return Ok(0);
561             }
562
563             let TaggedDoc { tag: r_tag, doc: r_doc } =
564                 try!(doc_at(self.parent.data, self.pos));
565             let r = if r_tag == (EsSub8 as usize) {
566                 doc_as_u8(r_doc) as usize
567             } else if r_tag == (EsSub32 as usize) {
568                 doc_as_u32(r_doc) as usize
569             } else {
570                 return Err(Expected(format!("expected EBML doc with tag {:?} or {:?} but \
571                                              found tag {:?}", EsSub8, EsSub32, r_tag)));
572             };
573             if r_doc.end > self.parent.end {
574                 return Err(Expected(format!("invalid EBML, child extends to \
575                                              {:#x}, parent to {:#x}",
576                                             r_doc.end, self.parent.end)));
577             }
578             self.pos = r_doc.end;
579             debug!("_next_sub result={:?}", r);
580             Ok(r)
581         }
582
583         // variable-length unsigned integer with different tags.
584         // `first_tag` should be a tag for u8 or i8.
585         // `last_tag` should be the largest allowed integer tag with the matching signedness.
586         // all tags between them should be valid, in the order of u8, u16, u32 and u64.
587         fn _next_int(&mut self,
588                      first_tag: EbmlEncoderTag,
589                      last_tag: EbmlEncoderTag) -> DecodeResult<u64> {
590             if self.pos >= self.parent.end {
591                 return Err(Expected(format!("no more documents in \
592                                              current node!")));
593             }
594
595             let TaggedDoc { tag: r_tag, doc: r_doc } =
596                 try!(doc_at(self.parent.data, self.pos));
597             let r = if first_tag as usize <= r_tag && r_tag <= last_tag as usize {
598                 match r_tag - first_tag as usize {
599                     0 => doc_as_u8(r_doc) as u64,
600                     1 => doc_as_u16(r_doc) as u64,
601                     2 => doc_as_u32(r_doc) as u64,
602                     3 => doc_as_u64(r_doc),
603                     _ => unreachable!(),
604                 }
605             } else {
606                 return Err(Expected(format!("expected EBML doc with tag {:?} through {:?} but \
607                                              found tag {:?}", first_tag, last_tag, r_tag)));
608             };
609             if r_doc.end > self.parent.end {
610                 return Err(Expected(format!("invalid EBML, child extends to \
611                                              {:#x}, parent to {:#x}",
612                                             r_doc.end, self.parent.end)));
613             }
614             self.pos = r_doc.end;
615             debug!("_next_int({:?}, {:?}) result={:?}", first_tag, last_tag, r);
616             Ok(r)
617         }
618
619         pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
620             F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
621         {
622             let doc = try!(self.next_doc(EsOpaque));
623
624             let (old_parent, old_pos) = (self.parent, self.pos);
625             self.parent = doc;
626             self.pos = doc.start;
627
628             let result = try!(op(self, doc));
629
630             self.parent = old_parent;
631             self.pos = old_pos;
632             Ok(result)
633         }
634     }
635
636     impl<'doc> serialize::Decoder for Decoder<'doc> {
637         type Error = Error;
638         fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
639
640         fn read_u64(&mut self) -> DecodeResult<u64> { self._next_int(EsU8, EsU64) }
641         fn read_u32(&mut self) -> DecodeResult<u32> { Ok(try!(self._next_int(EsU8, EsU32)) as u32) }
642         fn read_u16(&mut self) -> DecodeResult<u16> { Ok(try!(self._next_int(EsU8, EsU16)) as u16) }
643         fn read_u8(&mut self) -> DecodeResult<u8> { Ok(doc_as_u8(try!(self.next_doc(EsU8)))) }
644         fn read_uint(&mut self) -> DecodeResult<usize> {
645             let v = try!(self._next_int(EsU8, EsU64));
646             if v > (::std::usize::MAX as u64) {
647                 Err(IntTooBig(v as usize))
648             } else {
649                 Ok(v as usize)
650             }
651         }
652
653         fn read_i64(&mut self) -> DecodeResult<i64> { Ok(try!(self._next_int(EsI8, EsI64)) as i64) }
654         fn read_i32(&mut self) -> DecodeResult<i32> { Ok(try!(self._next_int(EsI8, EsI32)) as i32) }
655         fn read_i16(&mut self) -> DecodeResult<i16> { Ok(try!(self._next_int(EsI8, EsI16)) as i16) }
656         fn read_i8(&mut self) -> DecodeResult<i8> { Ok(doc_as_u8(try!(self.next_doc(EsI8))) as i8) }
657         fn read_int(&mut self) -> DecodeResult<isize> {
658             let v = try!(self._next_int(EsI8, EsI64)) as i64;
659             if v > (isize::MAX as i64) || v < (isize::MIN as i64) {
660                 debug!("FIXME \\#6122: Removing this makes this function miscompile");
661                 Err(IntTooBig(v as usize))
662             } else {
663                 Ok(v as isize)
664             }
665         }
666
667         fn read_bool(&mut self) -> DecodeResult<bool> {
668             Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
669         }
670
671         fn read_f64(&mut self) -> DecodeResult<f64> {
672             let bits = doc_as_u64(try!(self.next_doc(EsF64)));
673             Ok(unsafe { transmute(bits) })
674         }
675         fn read_f32(&mut self) -> DecodeResult<f32> {
676             let bits = doc_as_u32(try!(self.next_doc(EsF32)));
677             Ok(unsafe { transmute(bits) })
678         }
679         fn read_char(&mut self) -> DecodeResult<char> {
680             Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
681         }
682         fn read_str(&mut self) -> DecodeResult<String> {
683             Ok(try!(self.next_doc(EsStr)).as_str())
684         }
685
686         // Compound types:
687         fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
688             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
689         {
690             debug!("read_enum({})", name);
691
692             let doc = try!(self.next_doc(EsEnum));
693
694             let (old_parent, old_pos) = (self.parent, self.pos);
695             self.parent = doc;
696             self.pos = self.parent.start;
697
698             let result = try!(f(self));
699
700             self.parent = old_parent;
701             self.pos = old_pos;
702             Ok(result)
703         }
704
705         fn read_enum_variant<T, F>(&mut self, _: &[&str],
706                                    mut f: F) -> DecodeResult<T>
707             where F: FnMut(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
708         {
709             debug!("read_enum_variant()");
710             let idx = try!(self._next_sub());
711             debug!("  idx={}", idx);
712
713             f(self, idx)
714         }
715
716         fn read_enum_variant_arg<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
717             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
718         {
719             debug!("read_enum_variant_arg(idx={})", idx);
720             f(self)
721         }
722
723         fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
724                                           mut f: F) -> DecodeResult<T>
725             where F: FnMut(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
726         {
727             debug!("read_enum_struct_variant()");
728             let idx = try!(self._next_sub());
729             debug!("  idx={}", idx);
730
731             f(self, idx)
732         }
733
734         fn read_enum_struct_variant_field<T, F>(&mut self,
735                                                 name: &str,
736                                                 idx: usize,
737                                                 f: F)
738                                                 -> DecodeResult<T> where
739             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
740         {
741                 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
742             f(self)
743         }
744
745         fn read_struct<T, F>(&mut self, name: &str, _: usize, f: F) -> DecodeResult<T> where
746             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
747         {
748             debug!("read_struct(name={})", name);
749             f(self)
750         }
751
752         fn read_struct_field<T, F>(&mut self, name: &str, idx: usize, f: F) -> DecodeResult<T> where
753             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
754         {
755             debug!("read_struct_field(name={}, idx={})", name, idx);
756             f(self)
757         }
758
759         fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> DecodeResult<T> where
760             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
761         {
762             debug!("read_tuple()");
763             self.read_seq(move |d, len| {
764                 if len == tuple_len {
765                     f(d)
766                 } else {
767                     Err(Expected(format!("Expected tuple of length `{}`, \
768                                           found tuple of length `{}`", tuple_len, len)))
769                 }
770             })
771         }
772
773         fn read_tuple_arg<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
774             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
775         {
776             debug!("read_tuple_arg(idx={})", idx);
777             self.read_seq_elt(idx, f)
778         }
779
780         fn read_tuple_struct<T, F>(&mut self, name: &str, len: usize, f: F) -> DecodeResult<T> where
781             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
782         {
783             debug!("read_tuple_struct(name={})", name);
784             self.read_tuple(len, f)
785         }
786
787         fn read_tuple_struct_arg<T, F>(&mut self,
788                                        idx: usize,
789                                        f: F)
790                                        -> DecodeResult<T> where
791             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
792         {
793             debug!("read_tuple_struct_arg(idx={})", idx);
794             self.read_tuple_arg(idx, f)
795         }
796
797         fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
798             F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
799         {
800             debug!("read_option()");
801             self.read_enum("Option", move |this| {
802                 this.read_enum_variant(&["None", "Some"], move |this, idx| {
803                     match idx {
804                         0 => f(this, false),
805                         1 => f(this, true),
806                         _ => {
807                             Err(Expected(format!("Expected None or Some")))
808                         }
809                     }
810                 })
811             })
812         }
813
814         fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
815             F: FnOnce(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
816         {
817             debug!("read_seq()");
818             self.push_doc(EsVec, move |d| {
819                 let len = try!(d._next_sub());
820                 debug!("  len={}", len);
821                 f(d, len)
822             })
823         }
824
825         fn read_seq_elt<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
826             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
827         {
828             debug!("read_seq_elt(idx={})", idx);
829             self.push_doc(EsVecElt, f)
830         }
831
832         fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
833             F: FnOnce(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
834         {
835             debug!("read_map()");
836             self.push_doc(EsMap, move |d| {
837                 let len = try!(d._next_sub());
838                 debug!("  len={}", len);
839                 f(d, len)
840             })
841         }
842
843         fn read_map_elt_key<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
844             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
845         {
846             debug!("read_map_elt_key(idx={})", idx);
847             self.push_doc(EsMapKey, f)
848         }
849
850         fn read_map_elt_val<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
851             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
852         {
853             debug!("read_map_elt_val(idx={})", idx);
854             self.push_doc(EsMapVal, f)
855         }
856
857         fn error(&mut self, err: &str) -> Error {
858             ApplicationError(err.to_string())
859         }
860     }
861 }
862
863 pub mod writer {
864     use std::mem;
865     use std::io::prelude::*;
866     use std::io::{self, SeekFrom, Cursor};
867     use std::slice::bytes;
868
869     use super::{ EsVec, EsMap, EsEnum, EsSub8, EsSub32, EsVecElt, EsMapKey,
870         EsU64, EsU32, EsU16, EsU8, EsI64, EsI32, EsI16, EsI8,
871         EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
872         EsOpaque, NUM_IMPLICIT_TAGS, NUM_TAGS };
873
874     use serialize;
875
876
877     pub type EncodeResult = io::Result<()>;
878
879     // rbml writing
880     pub struct Encoder<'a> {
881         pub writer: &'a mut Cursor<Vec<u8>>,
882         size_positions: Vec<u64>,
883         relax_limit: u64, // do not move encoded bytes before this position
884     }
885
886     fn write_tag<W: Write>(w: &mut W, n: usize) -> EncodeResult {
887         if n < 0xf0 {
888             w.write_all(&[n as u8])
889         } else if 0x100 <= n && n < NUM_TAGS {
890             w.write_all(&[0xf0 | (n >> 8) as u8, n as u8])
891         } else {
892             Err(io::Error::new(io::ErrorKind::Other,
893                                &format!("invalid tag: {}", n)[..]))
894         }
895     }
896
897     fn write_sized_vuint<W: Write>(w: &mut W, n: usize, size: usize) -> EncodeResult {
898         match size {
899             1 => w.write_all(&[0x80 | (n as u8)]),
900             2 => w.write_all(&[0x40 | ((n >> 8) as u8), n as u8]),
901             3 => w.write_all(&[0x20 | ((n >> 16) as u8), (n >> 8) as u8,
902                             n as u8]),
903             4 => w.write_all(&[0x10 | ((n >> 24) as u8), (n >> 16) as u8,
904                             (n >> 8) as u8, n as u8]),
905             _ => Err(io::Error::new(io::ErrorKind::Other,
906                                     &format!("isize too big: {}", n)[..]))
907         }
908     }
909
910     fn write_vuint<W: Write>(w: &mut W, n: usize) -> EncodeResult {
911         if n < 0x7f { return write_sized_vuint(w, n, 1); }
912         if n < 0x4000 { return write_sized_vuint(w, n, 2); }
913         if n < 0x200000 { return write_sized_vuint(w, n, 3); }
914         if n < 0x10000000 { return write_sized_vuint(w, n, 4); }
915         Err(io::Error::new(io::ErrorKind::Other,
916                            &format!("isize too big: {}", n)[..]))
917     }
918
919     impl<'a> Encoder<'a> {
920         pub fn new(w: &'a mut Cursor<Vec<u8>>) -> Encoder<'a> {
921             Encoder {
922                 writer: w,
923                 size_positions: vec!(),
924                 relax_limit: 0,
925             }
926         }
927
928         /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
929         pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
930             Encoder {
931                 writer: mem::transmute_copy(&self.writer),
932                 size_positions: self.size_positions.clone(),
933                 relax_limit: self.relax_limit,
934             }
935         }
936
937         pub fn start_tag(&mut self, tag_id: usize) -> EncodeResult {
938             debug!("Start tag {:?}", tag_id);
939             assert!(tag_id >= NUM_IMPLICIT_TAGS);
940
941             // Write the enum ID:
942             try!(write_tag(self.writer, tag_id));
943
944             // Write a placeholder four-byte size.
945             let cur_pos = try!(self.writer.seek(SeekFrom::Current(0)));
946             self.size_positions.push(cur_pos);
947             let zeroes: &[u8] = &[0, 0, 0, 0];
948             self.writer.write_all(zeroes)
949         }
950
951         pub fn end_tag(&mut self) -> EncodeResult {
952             let last_size_pos = self.size_positions.pop().unwrap();
953             let cur_pos = try!(self.writer.seek(SeekFrom::Current(0)));
954             try!(self.writer.seek(SeekFrom::Start(last_size_pos)));
955             let size = (cur_pos - last_size_pos - 4) as usize;
956
957             // relax the size encoding for small tags (bigger tags are costly to move).
958             // we should never try to move the stable positions, however.
959             const RELAX_MAX_SIZE: usize = 0x100;
960             if size <= RELAX_MAX_SIZE && last_size_pos >= self.relax_limit {
961                 // we can't alter the buffer in place, so have a temporary buffer
962                 let mut buf = [0u8; RELAX_MAX_SIZE];
963                 {
964                     let last_size_pos = last_size_pos as usize;
965                     let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as usize];
966                     bytes::copy_memory(data, &mut buf);
967                 }
968
969                 // overwrite the size and data and continue
970                 try!(write_vuint(self.writer, size));
971                 try!(self.writer.write_all(&buf[..size]));
972             } else {
973                 // overwrite the size with an overlong encoding and skip past the data
974                 try!(write_sized_vuint(self.writer, size, 4));
975                 try!(self.writer.seek(SeekFrom::Start(cur_pos)));
976             }
977
978             debug!("End tag (size = {:?})", size);
979             Ok(())
980         }
981
982         pub fn wr_tag<F>(&mut self, tag_id: usize, blk: F) -> EncodeResult where
983             F: FnOnce() -> EncodeResult,
984         {
985             try!(self.start_tag(tag_id));
986             try!(blk());
987             self.end_tag()
988         }
989
990         pub fn wr_tagged_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult {
991             assert!(tag_id >= NUM_IMPLICIT_TAGS);
992             try!(write_tag(self.writer, tag_id));
993             try!(write_vuint(self.writer, b.len()));
994             self.writer.write_all(b)
995         }
996
997         pub fn wr_tagged_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult {
998             let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
999             self.wr_tagged_bytes(tag_id, &bytes)
1000         }
1001
1002         pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32)  -> EncodeResult{
1003             let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
1004             self.wr_tagged_bytes(tag_id, &bytes)
1005         }
1006
1007         pub fn wr_tagged_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult {
1008             let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
1009             self.wr_tagged_bytes(tag_id, &bytes)
1010         }
1011
1012         pub fn wr_tagged_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult {
1013             self.wr_tagged_bytes(tag_id, &[v])
1014         }
1015
1016         pub fn wr_tagged_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult {
1017             self.wr_tagged_u64(tag_id, v as u64)
1018         }
1019
1020         pub fn wr_tagged_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult {
1021             self.wr_tagged_u32(tag_id, v as u32)
1022         }
1023
1024         pub fn wr_tagged_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult {
1025             self.wr_tagged_u16(tag_id, v as u16)
1026         }
1027
1028         pub fn wr_tagged_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult {
1029             self.wr_tagged_bytes(tag_id, &[v as u8])
1030         }
1031
1032         pub fn wr_tagged_str(&mut self, tag_id: usize, v: &str) -> EncodeResult {
1033             self.wr_tagged_bytes(tag_id, v.as_bytes())
1034         }
1035
1036         // for auto-serialization
1037         fn wr_tagged_raw_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult {
1038             try!(write_tag(self.writer, tag_id));
1039             self.writer.write_all(b)
1040         }
1041
1042         fn wr_tagged_raw_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult {
1043             let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
1044             self.wr_tagged_raw_bytes(tag_id, &bytes)
1045         }
1046
1047         fn wr_tagged_raw_u32(&mut self, tag_id: usize, v: u32)  -> EncodeResult{
1048             let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
1049             self.wr_tagged_raw_bytes(tag_id, &bytes)
1050         }
1051
1052         fn wr_tagged_raw_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult {
1053             let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
1054             self.wr_tagged_raw_bytes(tag_id, &bytes)
1055         }
1056
1057         fn wr_tagged_raw_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult {
1058             self.wr_tagged_raw_bytes(tag_id, &[v])
1059         }
1060
1061         fn wr_tagged_raw_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult {
1062             self.wr_tagged_raw_u64(tag_id, v as u64)
1063         }
1064
1065         fn wr_tagged_raw_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult {
1066             self.wr_tagged_raw_u32(tag_id, v as u32)
1067         }
1068
1069         fn wr_tagged_raw_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult {
1070             self.wr_tagged_raw_u16(tag_id, v as u16)
1071         }
1072
1073         fn wr_tagged_raw_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult {
1074             self.wr_tagged_raw_bytes(tag_id, &[v as u8])
1075         }
1076
1077         pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
1078             debug!("Write {:?} bytes", b.len());
1079             self.writer.write_all(b)
1080         }
1081
1082         pub fn wr_str(&mut self, s: &str) -> EncodeResult {
1083             debug!("Write str: {:?}", s);
1084             self.writer.write_all(s.as_bytes())
1085         }
1086
1087         /// Returns the current position while marking it stable, i.e.
1088         /// generated bytes so far wouldn't be affected by relaxation.
1089         pub fn mark_stable_position(&mut self) -> u64 {
1090             let pos = self.writer.seek(SeekFrom::Current(0)).unwrap();
1091             if self.relax_limit < pos {
1092                 self.relax_limit = pos;
1093             }
1094             pos
1095         }
1096     }
1097
1098     impl<'a> Encoder<'a> {
1099         // used internally to emit things like the vector length and so on
1100         fn _emit_tagged_sub(&mut self, v: usize) -> EncodeResult {
1101             if v as u8 as usize == v {
1102                 self.wr_tagged_raw_u8(EsSub8 as usize, v as u8)
1103             } else if v as u32 as usize == v {
1104                 self.wr_tagged_raw_u32(EsSub32 as usize, v as u32)
1105             } else {
1106                 Err(io::Error::new(io::ErrorKind::Other,
1107                                    &format!("length or variant id too big: {}",
1108                                             v)[..]))
1109             }
1110         }
1111
1112         pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
1113             F: FnOnce(&mut Encoder) -> EncodeResult,
1114         {
1115             try!(self.start_tag(EsOpaque as usize));
1116             try!(f(self));
1117             self.end_tag()
1118         }
1119     }
1120
1121     impl<'a> serialize::Encoder for Encoder<'a> {
1122         type Error = io::Error;
1123
1124         fn emit_nil(&mut self) -> EncodeResult {
1125             Ok(())
1126         }
1127
1128         fn emit_uint(&mut self, v: usize) -> EncodeResult {
1129             self.emit_u64(v as u64)
1130         }
1131         fn emit_u64(&mut self, v: u64) -> EncodeResult {
1132             if v as u32 as u64 == v {
1133                 self.emit_u32(v as u32)
1134             } else {
1135                 self.wr_tagged_raw_u64(EsU64 as usize, v)
1136             }
1137         }
1138         fn emit_u32(&mut self, v: u32) -> EncodeResult {
1139             if v as u16 as u32 == v {
1140                 self.emit_u16(v as u16)
1141             } else {
1142                 self.wr_tagged_raw_u32(EsU32 as usize, v)
1143             }
1144         }
1145         fn emit_u16(&mut self, v: u16) -> EncodeResult {
1146             if v as u8 as u16 == v {
1147                 self.emit_u8(v as u8)
1148             } else {
1149                 self.wr_tagged_raw_u16(EsU16 as usize, v)
1150             }
1151         }
1152         fn emit_u8(&mut self, v: u8) -> EncodeResult {
1153             self.wr_tagged_raw_u8(EsU8 as usize, v)
1154         }
1155
1156         fn emit_int(&mut self, v: isize) -> EncodeResult {
1157             self.emit_i64(v as i64)
1158         }
1159         fn emit_i64(&mut self, v: i64) -> EncodeResult {
1160             if v as i32 as i64 == v {
1161                 self.emit_i32(v as i32)
1162             } else {
1163                 self.wr_tagged_raw_i64(EsI64 as usize, v)
1164             }
1165         }
1166         fn emit_i32(&mut self, v: i32) -> EncodeResult {
1167             if v as i16 as i32 == v {
1168                 self.emit_i16(v as i16)
1169             } else {
1170                 self.wr_tagged_raw_i32(EsI32 as usize, v)
1171             }
1172         }
1173         fn emit_i16(&mut self, v: i16) -> EncodeResult {
1174             if v as i8 as i16 == v {
1175                 self.emit_i8(v as i8)
1176             } else {
1177                 self.wr_tagged_raw_i16(EsI16 as usize, v)
1178             }
1179         }
1180         fn emit_i8(&mut self, v: i8) -> EncodeResult {
1181             self.wr_tagged_raw_i8(EsI8 as usize, v)
1182         }
1183
1184         fn emit_bool(&mut self, v: bool) -> EncodeResult {
1185             self.wr_tagged_raw_u8(EsBool as usize, v as u8)
1186         }
1187
1188         fn emit_f64(&mut self, v: f64) -> EncodeResult {
1189             let bits = unsafe { mem::transmute(v) };
1190             self.wr_tagged_raw_u64(EsF64 as usize, bits)
1191         }
1192         fn emit_f32(&mut self, v: f32) -> EncodeResult {
1193             let bits = unsafe { mem::transmute(v) };
1194             self.wr_tagged_raw_u32(EsF32 as usize, bits)
1195         }
1196         fn emit_char(&mut self, v: char) -> EncodeResult {
1197             self.wr_tagged_raw_u32(EsChar as usize, v as u32)
1198         }
1199
1200         fn emit_str(&mut self, v: &str) -> EncodeResult {
1201             self.wr_tagged_str(EsStr as usize, v)
1202         }
1203
1204         fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
1205             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1206         {
1207             try!(self.start_tag(EsEnum as usize));
1208             try!(f(self));
1209             self.end_tag()
1210         }
1211
1212         fn emit_enum_variant<F>(&mut self,
1213                                 _: &str,
1214                                 v_id: usize,
1215                                 _: usize,
1216                                 f: F) -> EncodeResult where
1217             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1218         {
1219             try!(self._emit_tagged_sub(v_id));
1220             f(self)
1221         }
1222
1223         fn emit_enum_variant_arg<F>(&mut self, _: usize, f: F) -> EncodeResult where
1224             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1225         {
1226             f(self)
1227         }
1228
1229         fn emit_enum_struct_variant<F>(&mut self,
1230                                        v_name: &str,
1231                                        v_id: usize,
1232                                        cnt: usize,
1233                                        f: F) -> EncodeResult where
1234             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1235         {
1236             self.emit_enum_variant(v_name, v_id, cnt, f)
1237         }
1238
1239         fn emit_enum_struct_variant_field<F>(&mut self,
1240                                              _: &str,
1241                                              idx: usize,
1242                                              f: F) -> EncodeResult where
1243             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1244         {
1245             self.emit_enum_variant_arg(idx, f)
1246         }
1247
1248         fn emit_struct<F>(&mut self, _: &str, _len: usize, f: F) -> EncodeResult where
1249             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1250         {
1251             f(self)
1252         }
1253
1254         fn emit_struct_field<F>(&mut self, _name: &str, _: usize, f: F) -> EncodeResult where
1255             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1256         {
1257             f(self)
1258         }
1259
1260         fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult where
1261             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1262         {
1263             self.emit_seq(len, f)
1264         }
1265         fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
1266             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1267         {
1268             self.emit_seq_elt(idx, f)
1269         }
1270
1271         fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult where
1272             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1273         {
1274             self.emit_seq(len, f)
1275         }
1276         fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
1277             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1278         {
1279             self.emit_seq_elt(idx, f)
1280         }
1281
1282         fn emit_option<F>(&mut self, f: F) -> EncodeResult where
1283             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1284         {
1285             self.emit_enum("Option", f)
1286         }
1287         fn emit_option_none(&mut self) -> EncodeResult {
1288             self.emit_enum_variant("None", 0, 0, |_| Ok(()))
1289         }
1290         fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
1291             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1292         {
1293
1294             self.emit_enum_variant("Some", 1, 1, f)
1295         }
1296
1297         fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodeResult where
1298             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1299         {
1300             if len == 0 {
1301                 // empty vector optimization
1302                 return self.wr_tagged_bytes(EsVec as usize, &[]);
1303             }
1304
1305             try!(self.start_tag(EsVec as usize));
1306             try!(self._emit_tagged_sub(len));
1307             try!(f(self));
1308             self.end_tag()
1309         }
1310
1311         fn emit_seq_elt<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
1312             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1313         {
1314
1315             try!(self.start_tag(EsVecElt as usize));
1316             try!(f(self));
1317             self.end_tag()
1318         }
1319
1320         fn emit_map<F>(&mut self, len: usize, f: F) -> EncodeResult where
1321             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1322         {
1323             if len == 0 {
1324                 // empty map optimization
1325                 return self.wr_tagged_bytes(EsMap as usize, &[]);
1326             }
1327
1328             try!(self.start_tag(EsMap as usize));
1329             try!(self._emit_tagged_sub(len));
1330             try!(f(self));
1331             self.end_tag()
1332         }
1333
1334         fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
1335             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1336         {
1337
1338             try!(self.start_tag(EsMapKey as usize));
1339             try!(f(self));
1340             self.end_tag()
1341         }
1342
1343         fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
1344             F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
1345         {
1346             try!(self.start_tag(EsMapVal as usize));
1347             try!(f(self));
1348             self.end_tag()
1349         }
1350     }
1351 }
1352
1353 // ___________________________________________________________________________
1354 // Testing
1355
1356 #[cfg(test)]
1357 mod tests {
1358     use super::{Doc, reader, writer};
1359
1360     use serialize::{Encodable, Decodable};
1361
1362     use std::io::Cursor;
1363
1364     #[test]
1365     fn test_vuint_at() {
1366         let data = &[
1367             0x80,
1368             0xff,
1369             0x40, 0x00,
1370             0x7f, 0xff,
1371             0x20, 0x00, 0x00,
1372             0x3f, 0xff, 0xff,
1373             0x10, 0x00, 0x00, 0x00,
1374             0x1f, 0xff, 0xff, 0xff
1375         ];
1376
1377         let mut res: reader::Res;
1378
1379         // Class A
1380         res = reader::vuint_at(data, 0).unwrap();
1381         assert_eq!(res.val, 0);
1382         assert_eq!(res.next, 1);
1383         res = reader::vuint_at(data, res.next).unwrap();
1384         assert_eq!(res.val, (1 << 7) - 1);
1385         assert_eq!(res.next, 2);
1386
1387         // Class B
1388         res = reader::vuint_at(data, res.next).unwrap();
1389         assert_eq!(res.val, 0);
1390         assert_eq!(res.next, 4);
1391         res = reader::vuint_at(data, res.next).unwrap();
1392         assert_eq!(res.val, (1 << 14) - 1);
1393         assert_eq!(res.next, 6);
1394
1395         // Class C
1396         res = reader::vuint_at(data, res.next).unwrap();
1397         assert_eq!(res.val, 0);
1398         assert_eq!(res.next, 9);
1399         res = reader::vuint_at(data, res.next).unwrap();
1400         assert_eq!(res.val, (1 << 21) - 1);
1401         assert_eq!(res.next, 12);
1402
1403         // Class D
1404         res = reader::vuint_at(data, res.next).unwrap();
1405         assert_eq!(res.val, 0);
1406         assert_eq!(res.next, 16);
1407         res = reader::vuint_at(data, res.next).unwrap();
1408         assert_eq!(res.val, (1 << 28) - 1);
1409         assert_eq!(res.next, 20);
1410     }
1411
1412     #[test]
1413     fn test_option_int() {
1414         fn test_v(v: Option<isize>) {
1415             debug!("v == {:?}", v);
1416             let mut wr = Cursor::new(Vec::new());
1417             {
1418                 let mut rbml_w = writer::Encoder::new(&mut wr);
1419                 let _ = v.encode(&mut rbml_w);
1420             }
1421             let rbml_doc = Doc::new(wr.get_ref());
1422             let mut deser = reader::Decoder::new(rbml_doc);
1423             let v1 = Decodable::decode(&mut deser).unwrap();
1424             debug!("v1 == {:?}", v1);
1425             assert_eq!(v, v1);
1426         }
1427
1428         test_v(Some(22));
1429         test_v(None);
1430         test_v(Some(3));
1431     }
1432 }
1433
1434 #[cfg(test)]
1435 mod bench {
1436     #![allow(non_snake_case)]
1437     use test::Bencher;
1438     use super::reader;
1439
1440     #[bench]
1441     pub fn vuint_at_A_aligned(b: &mut Bencher) {
1442         let data = (0..4*100).map(|i| {
1443             match i % 2 {
1444               0 => 0x80,
1445               _ => i as u8,
1446             }
1447         }).collect::<Vec<_>>();
1448         let mut sum = 0;
1449         b.iter(|| {
1450             let mut i = 0;
1451             while i < data.len() {
1452                 sum += reader::vuint_at(&data, i).unwrap().val;
1453                 i += 4;
1454             }
1455         });
1456     }
1457
1458     #[bench]
1459     pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1460         let data = (0..4*100+1).map(|i| {
1461             match i % 2 {
1462               1 => 0x80,
1463               _ => i as u8
1464             }
1465         }).collect::<Vec<_>>();
1466         let mut sum = 0;
1467         b.iter(|| {
1468             let mut i = 1;
1469             while i < data.len() {
1470                 sum += reader::vuint_at(&data, i).unwrap().val;
1471                 i += 4;
1472             }
1473         });
1474     }
1475
1476     #[bench]
1477     pub fn vuint_at_D_aligned(b: &mut Bencher) {
1478         let data = (0..4*100).map(|i| {
1479             match i % 4 {
1480               0 => 0x10,
1481               3 => i as u8,
1482               _ => 0
1483             }
1484         }).collect::<Vec<_>>();
1485         let mut sum = 0;
1486         b.iter(|| {
1487             let mut i = 0;
1488             while i < data.len() {
1489                 sum += reader::vuint_at(&data, i).unwrap().val;
1490                 i += 4;
1491             }
1492         });
1493     }
1494
1495     #[bench]
1496     pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1497         let data = (0..4*100+1).map(|i| {
1498             match i % 4 {
1499               1 => 0x10,
1500               0 => i as u8,
1501               _ => 0
1502             }
1503         }).collect::<Vec<_>>();
1504         let mut sum = 0;
1505         b.iter(|| {
1506             let mut i = 1;
1507             while i < data.len() {
1508                 sum += reader::vuint_at(&data, i).unwrap().val;
1509                 i += 4;
1510             }
1511         });
1512     }
1513 }