]> git.lizzy.rs Git - rust.git/blob - src/librbml/lib.rs
rollup merge of #20642: michaelwoerister/sane-source-locations-pt1
[rust.git] / src / librbml / lib.rs
1 // Copyright 2012-2014 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 a temporary measure until we migrate
12 //! the rust object metadata to a better serialization format. It is not
13 //! intended to be used by users.
14 //!
15 //! It is loosely based on the Extensible Binary Markup Language (ebml):
16 //!     http://www.matroska.org/technical/specs/rfc/index.html
17
18 #![crate_name = "rbml"]
19 #![unstable]
20 #![staged_api]
21 #![crate_type = "rlib"]
22 #![crate_type = "dylib"]
23 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
24        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
25        html_root_url = "http://doc.rust-lang.org/nightly/",
26        html_playground_url = "http://play.rust-lang.org/")]
27 #![allow(unknown_features)]
28 #![feature(slicing_syntax)]
29 #![allow(unknown_features)] #![feature(int_uint)]
30 #![allow(unstable)]
31
32 extern crate serialize;
33 #[macro_use] extern crate log;
34
35 #[cfg(test)] extern crate test;
36
37 pub use self::EbmlEncoderTag::*;
38 pub use self::Error::*;
39
40 use std::str;
41 use std::fmt;
42
43 pub mod io;
44
45 /// Common data structures
46 #[derive(Clone, Copy)]
47 pub struct Doc<'a> {
48     pub data: &'a [u8],
49     pub start: uint,
50     pub end: uint,
51 }
52
53 impl<'doc> Doc<'doc> {
54     pub fn new(data: &'doc [u8]) -> Doc<'doc> {
55         Doc { data: data, start: 0u, end: data.len() }
56     }
57
58     pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
59         reader::get_doc(*self, tag)
60     }
61
62     pub fn as_str_slice<'a>(&'a self) -> &'a str {
63         str::from_utf8(&self.data[self.start..self.end]).unwrap()
64     }
65
66     pub fn as_str(&self) -> String {
67         self.as_str_slice().to_string()
68     }
69 }
70
71 pub struct TaggedDoc<'a> {
72     tag: uint,
73     pub doc: Doc<'a>,
74 }
75
76 #[derive(Copy, Show)]
77 pub enum EbmlEncoderTag {
78     EsUint,     // 0
79     EsU64,      // 1
80     EsU32,      // 2
81     EsU16,      // 3
82     EsU8,       // 4
83     EsInt,      // 5
84     EsI64,      // 6
85     EsI32,      // 7
86     EsI16,      // 8
87     EsI8,       // 9
88     EsBool,     // 10
89     EsChar,     // 11
90     EsStr,      // 12
91     EsF64,      // 13
92     EsF32,      // 14
93     EsFloat,    // 15
94     EsEnum,     // 16
95     EsEnumVid,  // 17
96     EsEnumBody, // 18
97     EsVec,      // 19
98     EsVecLen,   // 20
99     EsVecElt,   // 21
100     EsMap,      // 22
101     EsMapLen,   // 23
102     EsMapKey,   // 24
103     EsMapVal,   // 25
104
105     EsOpaque,
106
107     EsLabel, // Used only when debugging
108 }
109
110 #[derive(Show)]
111 pub enum Error {
112     IntTooBig(uint),
113     Expected(String),
114     IoError(std::io::IoError),
115     ApplicationError(String)
116 }
117
118 impl fmt::Display for Error {
119     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120         // FIXME: this should be a more useful display form
121         fmt::Debug::fmt(self, f)
122     }
123 }
124 // --------------------------------------
125
126 pub mod reader {
127     use std::char;
128
129     use std::int;
130     use std::io::extensions::u64_from_be_bytes;
131     use std::mem::transmute;
132     use std::num::Int;
133     use std::option::Option;
134     use std::option::Option::{None, Some};
135
136     use serialize;
137
138     use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
139         EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
140         EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
141         EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
142         Error, IntTooBig, Expected };
143
144     pub type DecodeResult<T> = Result<T, Error>;
145     // rbml reading
146
147     macro_rules! try_or {
148         ($e:expr, $r:expr) => (
149             match $e {
150                 Ok(e) => e,
151                 Err(e) => {
152                     debug!("ignored error: {:?}", e);
153                     return $r
154                 }
155             }
156         )
157     }
158
159     #[derive(Copy)]
160     pub struct Res {
161         pub val: uint,
162         pub next: uint
163     }
164
165     #[inline(never)]
166     fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
167         let a = data[start];
168         if a & 0x80u8 != 0u8 {
169             return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
170         }
171         if a & 0x40u8 != 0u8 {
172             return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
173                         (data[start + 1u] as uint),
174                     next: start + 2u});
175         }
176         if a & 0x20u8 != 0u8 {
177             return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
178                         (data[start + 1u] as uint) << 8u |
179                         (data[start + 2u] as uint),
180                     next: start + 3u});
181         }
182         if a & 0x10u8 != 0u8 {
183             return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
184                         (data[start + 1u] as uint) << 16u |
185                         (data[start + 2u] as uint) << 8u |
186                         (data[start + 3u] as uint),
187                     next: start + 4u});
188         }
189         Err(IntTooBig(a as uint))
190     }
191
192     pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
193         if data.len() - start < 4 {
194             return vuint_at_slow(data, start);
195         }
196
197         // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
198         // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
199         // Using the four most significant bits of the u32 we lookup in the table below how the
200         // element ID should be derived from it.
201         //
202         // The table stores tuples (shift, mask) where shift is the number the u32 should be right
203         // shifted with and mask is the value the right shifted value should be masked with.
204         // If for example the most significant bit is set this means it's a class A ID and the u32
205         // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
206         // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
207         //
208         // By storing the number of shifts and masks in a table instead of checking in order if
209         // the most significant bit is set, the second most significant bit is set etc. we can
210         // replace up to three "and+branch" with a single table lookup which gives us a measured
211         // speedup of around 2x on x86_64.
212         static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
213             (0, 0x0), (0, 0x0fffffff),
214             (8, 0x1fffff), (8, 0x1fffff),
215             (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
216             (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
217             (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
218         ];
219
220         unsafe {
221             let ptr = data.as_ptr().offset(start as int) as *const u32;
222             let val = Int::from_be(*ptr);
223
224             let i = (val >> 28u) as uint;
225             let (shift, mask) = SHIFT_MASK_TABLE[i];
226             Ok(Res {
227                 val: ((val >> shift) & mask) as uint,
228                 next: start + (((32 - shift) >> 3) as uint)
229             })
230         }
231     }
232
233     pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
234         let elt_tag = try!(vuint_at(data, start));
235         let elt_size = try!(vuint_at(data, elt_tag.next));
236         let end = elt_size.next + elt_size.val;
237         Ok(TaggedDoc {
238             tag: elt_tag.val,
239             doc: Doc { data: data, start: elt_size.next, end: end }
240         })
241     }
242
243     pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
244         let mut pos = d.start;
245         while pos < d.end {
246             let elt_tag = try_or!(vuint_at(d.data, pos), None);
247             let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
248             pos = elt_size.next + elt_size.val;
249             if elt_tag.val == tg {
250                 return Some(Doc { data: d.data, start: elt_size.next,
251                                   end: pos });
252             }
253         }
254         None
255     }
256
257     pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
258         match maybe_get_doc(d, tg) {
259             Some(d) => d,
260             None => {
261                 error!("failed to find block with tag {:?}", tg);
262                 panic!();
263             }
264         }
265     }
266
267     pub fn docs<F>(d: Doc, mut it: F) -> bool where
268         F: FnMut(uint, Doc) -> bool,
269     {
270         let mut pos = d.start;
271         while pos < d.end {
272             let elt_tag = try_or!(vuint_at(d.data, pos), false);
273             let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
274             pos = elt_size.next + elt_size.val;
275             let doc = Doc { data: d.data, start: elt_size.next, end: pos };
276             if !it(elt_tag.val, doc) {
277                 return false;
278             }
279         }
280         return true;
281     }
282
283     pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
284         F: FnMut(Doc) -> bool,
285     {
286         let mut pos = d.start;
287         while pos < d.end {
288             let elt_tag = try_or!(vuint_at(d.data, pos), false);
289             let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
290             pos = elt_size.next + elt_size.val;
291             if elt_tag.val == tg {
292                 let doc = Doc { data: d.data, start: elt_size.next,
293                                 end: pos };
294                 if !it(doc) {
295                     return false;
296                 }
297             }
298         }
299         return true;
300     }
301
302     pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
303         F: FnOnce(&[u8]) -> T,
304     {
305         f(&d.data[d.start..d.end])
306     }
307
308
309     pub fn doc_as_u8(d: Doc) -> u8 {
310         assert_eq!(d.end, d.start + 1u);
311         d.data[d.start]
312     }
313
314     pub fn doc_as_u16(d: Doc) -> u16 {
315         assert_eq!(d.end, d.start + 2u);
316         u64_from_be_bytes(d.data, d.start, 2u) as u16
317     }
318
319     pub fn doc_as_u32(d: Doc) -> u32 {
320         assert_eq!(d.end, d.start + 4u);
321         u64_from_be_bytes(d.data, d.start, 4u) as u32
322     }
323
324     pub fn doc_as_u64(d: Doc) -> u64 {
325         assert_eq!(d.end, d.start + 8u);
326         u64_from_be_bytes(d.data, d.start, 8u)
327     }
328
329     pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
330     pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
331     pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
332     pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
333
334     pub struct Decoder<'a> {
335         parent: Doc<'a>,
336         pos: uint,
337     }
338
339     impl<'doc> Decoder<'doc> {
340         pub fn new(d: Doc<'doc>) -> Decoder<'doc> {
341             Decoder {
342                 parent: d,
343                 pos: d.start
344             }
345         }
346
347         fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
348             if self.pos < self.parent.end {
349                 let TaggedDoc { tag: r_tag, doc: r_doc } =
350                     try!(doc_at(self.parent.data, self.pos));
351
352                 if r_tag == (EsLabel as uint) {
353                     self.pos = r_doc.end;
354                     let str = r_doc.as_str_slice();
355                     if lbl != str {
356                         return Err(Expected(format!("Expected label {:?} but \
357                                                      found {:?}", lbl, str)));
358                     }
359                 }
360             }
361             Ok(())
362         }
363
364         fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
365             debug!(". next_doc(exp_tag={:?})", exp_tag);
366             if self.pos >= self.parent.end {
367                 return Err(Expected(format!("no more documents in \
368                                              current node!")));
369             }
370             let TaggedDoc { tag: r_tag, doc: r_doc } =
371                 try!(doc_at(self.parent.data, self.pos));
372             debug!("self.parent={:?}-{:?} self.pos={:?} r_tag={:?} r_doc={:?}-{:?}",
373                    self.parent.start,
374                    self.parent.end,
375                    self.pos,
376                    r_tag,
377                    r_doc.start,
378                    r_doc.end);
379             if r_tag != (exp_tag as uint) {
380                 return Err(Expected(format!("expected EBML doc with tag {:?} but \
381                                              found tag {:?}", exp_tag, r_tag)));
382             }
383             if r_doc.end > self.parent.end {
384                 return Err(Expected(format!("invalid EBML, child extends to \
385                                              {:#x}, parent to {:#x}",
386                                             r_doc.end, self.parent.end)));
387             }
388             self.pos = r_doc.end;
389             Ok(r_doc)
390         }
391
392         fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
393             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
394         {
395             let d = try!(self.next_doc(exp_tag));
396             let old_parent = self.parent;
397             let old_pos = self.pos;
398             self.parent = d;
399             self.pos = d.start;
400             let r = try!(f(self));
401             self.parent = old_parent;
402             self.pos = old_pos;
403             Ok(r)
404         }
405
406         fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
407             let r = doc_as_u32(try!(self.next_doc(exp_tag)));
408             debug!("_next_uint exp_tag={:?} result={:?}", exp_tag, r);
409             Ok(r as uint)
410         }
411
412         pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
413             F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
414         {
415             let doc = try!(self.next_doc(EsOpaque));
416
417             let (old_parent, old_pos) = (self.parent, self.pos);
418             self.parent = doc;
419             self.pos = doc.start;
420
421             let result = try!(op(self, doc));
422
423             self.parent = old_parent;
424             self.pos = old_pos;
425             Ok(result)
426         }
427     }
428
429     impl<'doc> serialize::Decoder for Decoder<'doc> {
430         type Error = Error;
431         fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
432
433         fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
434         fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
435         fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
436         fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
437         fn read_uint(&mut self) -> DecodeResult<uint> {
438             let v = doc_as_u64(try!(self.next_doc(EsUint)));
439             if v > (::std::uint::MAX as u64) {
440                 Err(IntTooBig(v as uint))
441             } else {
442                 Ok(v as uint)
443             }
444         }
445
446         fn read_i64(&mut self) -> DecodeResult<i64> {
447             Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
448         }
449         fn read_i32(&mut self) -> DecodeResult<i32> {
450             Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
451         }
452         fn read_i16(&mut self) -> DecodeResult<i16> {
453             Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
454         }
455         fn read_i8 (&mut self) -> DecodeResult<i8> {
456             Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
457         }
458         fn read_int(&mut self) -> DecodeResult<int> {
459             let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
460             if v > (int::MAX as i64) || v < (int::MIN as i64) {
461                 debug!("FIXME \\#6122: Removing this makes this function miscompile");
462                 Err(IntTooBig(v as uint))
463             } else {
464                 Ok(v as int)
465             }
466         }
467
468         fn read_bool(&mut self) -> DecodeResult<bool> {
469             Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
470         }
471
472         fn read_f64(&mut self) -> DecodeResult<f64> {
473             let bits = doc_as_u64(try!(self.next_doc(EsF64)));
474             Ok(unsafe { transmute(bits) })
475         }
476         fn read_f32(&mut self) -> DecodeResult<f32> {
477             let bits = doc_as_u32(try!(self.next_doc(EsF32)));
478             Ok(unsafe { transmute(bits) })
479         }
480         fn read_char(&mut self) -> DecodeResult<char> {
481             Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
482         }
483         fn read_str(&mut self) -> DecodeResult<String> {
484             Ok(try!(self.next_doc(EsStr)).as_str())
485         }
486
487         // Compound types:
488         fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
489             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
490         {
491             debug!("read_enum({})", name);
492             try!(self._check_label(name));
493
494             let doc = try!(self.next_doc(EsEnum));
495
496             let (old_parent, old_pos) = (self.parent, self.pos);
497             self.parent = doc;
498             self.pos = self.parent.start;
499
500             let result = try!(f(self));
501
502             self.parent = old_parent;
503             self.pos = old_pos;
504             Ok(result)
505         }
506
507         fn read_enum_variant<T, F>(&mut self, _: &[&str],
508                                    mut f: F) -> DecodeResult<T>
509             where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
510         {
511             debug!("read_enum_variant()");
512             let idx = try!(self._next_uint(EsEnumVid));
513             debug!("  idx={}", idx);
514
515             let doc = try!(self.next_doc(EsEnumBody));
516
517             let (old_parent, old_pos) = (self.parent, self.pos);
518             self.parent = doc;
519             self.pos = self.parent.start;
520
521             let result = try!(f(self, idx));
522
523             self.parent = old_parent;
524             self.pos = old_pos;
525             Ok(result)
526         }
527
528         fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
529             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
530         {
531             debug!("read_enum_variant_arg(idx={})", idx);
532             f(self)
533         }
534
535         fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
536                                           mut f: F) -> DecodeResult<T>
537             where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
538         {
539             debug!("read_enum_struct_variant()");
540             let idx = try!(self._next_uint(EsEnumVid));
541             debug!("  idx={}", idx);
542
543             let doc = try!(self.next_doc(EsEnumBody));
544
545             let (old_parent, old_pos) = (self.parent, self.pos);
546             self.parent = doc;
547             self.pos = self.parent.start;
548
549             let result = try!(f(self, idx));
550
551             self.parent = old_parent;
552             self.pos = old_pos;
553             Ok(result)
554         }
555
556         fn read_enum_struct_variant_field<T, F>(&mut self,
557                                                 name: &str,
558                                                 idx: uint,
559                                                 f: F)
560                                                 -> DecodeResult<T> where
561             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
562         {
563                 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
564             f(self)
565         }
566
567         fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
568             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
569         {
570             debug!("read_struct(name={})", name);
571             f(self)
572         }
573
574         fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
575             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
576         {
577             debug!("read_struct_field(name={}, idx={})", name, idx);
578             try!(self._check_label(name));
579             f(self)
580         }
581
582         fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
583             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
584         {
585             debug!("read_tuple()");
586             self.read_seq(move |d, len| {
587                 if len == tuple_len {
588                     f(d)
589                 } else {
590                     Err(Expected(format!("Expected tuple of length `{}`, \
591                                           found tuple of length `{}`", tuple_len, len)))
592                 }
593             })
594         }
595
596         fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
597             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
598         {
599             debug!("read_tuple_arg(idx={})", idx);
600             self.read_seq_elt(idx, f)
601         }
602
603         fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
604             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
605         {
606             debug!("read_tuple_struct(name={})", name);
607             self.read_tuple(len, f)
608         }
609
610         fn read_tuple_struct_arg<T, F>(&mut self,
611                                        idx: uint,
612                                        f: F)
613                                        -> DecodeResult<T> where
614             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
615         {
616             debug!("read_tuple_struct_arg(idx={})", idx);
617             self.read_tuple_arg(idx, f)
618         }
619
620         fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
621             F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
622         {
623             debug!("read_option()");
624             self.read_enum("Option", move |this| {
625                 this.read_enum_variant(&["None", "Some"], move |this, idx| {
626                     match idx {
627                         0 => f(this, false),
628                         1 => f(this, true),
629                         _ => {
630                             Err(Expected(format!("Expected None or Some")))
631                         }
632                     }
633                 })
634             })
635         }
636
637         fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
638             F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
639         {
640             debug!("read_seq()");
641             self.push_doc(EsVec, move |d| {
642                 let len = try!(d._next_uint(EsVecLen));
643                 debug!("  len={}", len);
644                 f(d, len)
645             })
646         }
647
648         fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
649             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
650         {
651             debug!("read_seq_elt(idx={})", idx);
652             self.push_doc(EsVecElt, f)
653         }
654
655         fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
656             F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
657         {
658             debug!("read_map()");
659             self.push_doc(EsMap, move |d| {
660                 let len = try!(d._next_uint(EsMapLen));
661                 debug!("  len={}", len);
662                 f(d, len)
663             })
664         }
665
666         fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
667             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
668         {
669             debug!("read_map_elt_key(idx={})", idx);
670             self.push_doc(EsMapKey, f)
671         }
672
673         fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
674             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
675         {
676             debug!("read_map_elt_val(idx={})", idx);
677             self.push_doc(EsMapVal, f)
678         }
679
680         fn error(&mut self, err: &str) -> Error {
681             ApplicationError(err.to_string())
682         }
683     }
684 }
685
686 pub mod writer {
687     use std::clone::Clone;
688     use std::io::extensions::u64_to_be_bytes;
689     use std::io::{Writer, Seek};
690     use std::io;
691     use std::mem;
692
693     use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
694         EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
695         EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
696         EsOpaque, EsLabel, EbmlEncoderTag };
697
698     use serialize;
699
700
701     pub type EncodeResult = io::IoResult<()>;
702
703     // rbml writing
704     pub struct Encoder<'a, W:'a> {
705         pub writer: &'a mut W,
706         size_positions: Vec<uint>,
707     }
708
709     fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
710         match size {
711             1u => w.write(&[0x80u8 | (n as u8)]),
712             2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
713             3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
714                             n as u8]),
715             4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
716                             (n >> 8_u) as u8, n as u8]),
717             _ => Err(io::IoError {
718                 kind: io::OtherIoError,
719                 desc: "int too big",
720                 detail: Some(format!("{}", n))
721             })
722         }
723     }
724
725     fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
726         if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
727         if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
728         if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
729         if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
730         Err(io::IoError {
731             kind: io::OtherIoError,
732             desc: "int too big",
733             detail: Some(format!("{}", n))
734         })
735     }
736
737     // FIXME (#2741): Provide a function to write the standard rbml header.
738     impl<'a, W: Writer + Seek> Encoder<'a, W> {
739         pub fn new(w: &'a mut W) -> Encoder<'a, W> {
740             Encoder {
741                 writer: w,
742                 size_positions: vec!(),
743             }
744         }
745
746         /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
747         pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
748             Encoder {
749                 writer: mem::transmute_copy(&self.writer),
750                 size_positions: self.size_positions.clone(),
751             }
752         }
753
754         pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
755             debug!("Start tag {:?}", tag_id);
756
757             // Write the enum ID:
758             try!(write_vuint(self.writer, tag_id));
759
760             // Write a placeholder four-byte size.
761             self.size_positions.push(try!(self.writer.tell()) as uint);
762             let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
763             self.writer.write(zeroes)
764         }
765
766         pub fn end_tag(&mut self) -> EncodeResult {
767             let last_size_pos = self.size_positions.pop().unwrap();
768             let cur_pos = try!(self.writer.tell());
769             try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
770             let size = cur_pos as uint - last_size_pos - 4;
771             try!(write_sized_vuint(self.writer, size, 4u));
772             let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
773
774             debug!("End tag (size = {:?})", size);
775             Ok(r)
776         }
777
778         pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
779             F: FnOnce() -> EncodeResult,
780         {
781             try!(self.start_tag(tag_id));
782             try!(blk());
783             self.end_tag()
784         }
785
786         pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
787             try!(write_vuint(self.writer, tag_id));
788             try!(write_vuint(self.writer, b.len()));
789             self.writer.write(b)
790         }
791
792         pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
793             u64_to_be_bytes(v, 8u, |v| {
794                 self.wr_tagged_bytes(tag_id, v)
795             })
796         }
797
798         pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32)  -> EncodeResult{
799             u64_to_be_bytes(v as u64, 4u, |v| {
800                 self.wr_tagged_bytes(tag_id, v)
801             })
802         }
803
804         pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
805             u64_to_be_bytes(v as u64, 2u, |v| {
806                 self.wr_tagged_bytes(tag_id, v)
807             })
808         }
809
810         pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
811             self.wr_tagged_bytes(tag_id, &[v])
812         }
813
814         pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
815             u64_to_be_bytes(v as u64, 8u, |v| {
816                 self.wr_tagged_bytes(tag_id, v)
817             })
818         }
819
820         pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
821             u64_to_be_bytes(v as u64, 4u, |v| {
822                 self.wr_tagged_bytes(tag_id, v)
823             })
824         }
825
826         pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
827             u64_to_be_bytes(v as u64, 2u, |v| {
828                 self.wr_tagged_bytes(tag_id, v)
829             })
830         }
831
832         pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
833             self.wr_tagged_bytes(tag_id, &[v as u8])
834         }
835
836         pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
837             self.wr_tagged_bytes(tag_id, v.as_bytes())
838         }
839
840         pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
841             debug!("Write {:?} bytes", b.len());
842             self.writer.write(b)
843         }
844
845         pub fn wr_str(&mut self, s: &str) -> EncodeResult {
846             debug!("Write str: {:?}", s);
847             self.writer.write(s.as_bytes())
848         }
849     }
850
851     // FIXME (#2743): optionally perform "relaxations" on end_tag to more
852     // efficiently encode sizes; this is a fixed point iteration
853
854     // Set to true to generate more debugging in EBML code.
855     // Totally lame approach.
856     static DEBUG: bool = true;
857
858     impl<'a, W: Writer + Seek> Encoder<'a, W> {
859         // used internally to emit things like the vector length and so on
860         fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
861             assert!(v <= 0xFFFF_FFFF_u);
862             self.wr_tagged_u32(t as uint, v as u32)
863         }
864
865         fn _emit_label(&mut self, label: &str) -> EncodeResult {
866             // There are various strings that we have access to, such as
867             // the name of a record field, which do not actually appear in
868             // the encoded EBML (normally).  This is just for
869             // efficiency.  When debugging, though, we can emit such
870             // labels and then they will be checked by decoder to
871             // try and check panics more quickly.
872             if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
873             else { Ok(()) }
874         }
875
876         pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
877             F: FnOnce(&mut Encoder<W>) -> EncodeResult,
878         {
879             try!(self.start_tag(EsOpaque as uint));
880             try!(f(self));
881             self.end_tag()
882         }
883     }
884
885     impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> {
886         type Error = io::IoError;
887
888         fn emit_nil(&mut self) -> EncodeResult {
889             Ok(())
890         }
891
892         fn emit_uint(&mut self, v: uint) -> EncodeResult {
893             self.wr_tagged_u64(EsUint as uint, v as u64)
894         }
895         fn emit_u64(&mut self, v: u64) -> EncodeResult {
896             self.wr_tagged_u64(EsU64 as uint, v)
897         }
898         fn emit_u32(&mut self, v: u32) -> EncodeResult {
899             self.wr_tagged_u32(EsU32 as uint, v)
900         }
901         fn emit_u16(&mut self, v: u16) -> EncodeResult {
902             self.wr_tagged_u16(EsU16 as uint, v)
903         }
904         fn emit_u8(&mut self, v: u8) -> EncodeResult {
905             self.wr_tagged_u8(EsU8 as uint, v)
906         }
907
908         fn emit_int(&mut self, v: int) -> EncodeResult {
909             self.wr_tagged_i64(EsInt as uint, v as i64)
910         }
911         fn emit_i64(&mut self, v: i64) -> EncodeResult {
912             self.wr_tagged_i64(EsI64 as uint, v)
913         }
914         fn emit_i32(&mut self, v: i32) -> EncodeResult {
915             self.wr_tagged_i32(EsI32 as uint, v)
916         }
917         fn emit_i16(&mut self, v: i16) -> EncodeResult {
918             self.wr_tagged_i16(EsI16 as uint, v)
919         }
920         fn emit_i8(&mut self, v: i8) -> EncodeResult {
921             self.wr_tagged_i8(EsI8 as uint, v)
922         }
923
924         fn emit_bool(&mut self, v: bool) -> EncodeResult {
925             self.wr_tagged_u8(EsBool as uint, v as u8)
926         }
927
928         fn emit_f64(&mut self, v: f64) -> EncodeResult {
929             let bits = unsafe { mem::transmute(v) };
930             self.wr_tagged_u64(EsF64 as uint, bits)
931         }
932         fn emit_f32(&mut self, v: f32) -> EncodeResult {
933             let bits = unsafe { mem::transmute(v) };
934             self.wr_tagged_u32(EsF32 as uint, bits)
935         }
936         fn emit_char(&mut self, v: char) -> EncodeResult {
937             self.wr_tagged_u32(EsChar as uint, v as u32)
938         }
939
940         fn emit_str(&mut self, v: &str) -> EncodeResult {
941             self.wr_tagged_str(EsStr as uint, v)
942         }
943
944         fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
945             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
946         {
947             try!(self._emit_label(name));
948             try!(self.start_tag(EsEnum as uint));
949             try!(f(self));
950             self.end_tag()
951         }
952
953         fn emit_enum_variant<F>(&mut self,
954                                 _: &str,
955                                 v_id: uint,
956                                 _: uint,
957                                 f: F) -> EncodeResult where
958             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
959         {
960             try!(self._emit_tagged_uint(EsEnumVid, v_id));
961             try!(self.start_tag(EsEnumBody as uint));
962             try!(f(self));
963             self.end_tag()
964         }
965
966         fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
967             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
968         {
969             f(self)
970         }
971
972         fn emit_enum_struct_variant<F>(&mut self,
973                                        v_name: &str,
974                                        v_id: uint,
975                                        cnt: uint,
976                                        f: F) -> EncodeResult where
977             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
978         {
979             self.emit_enum_variant(v_name, v_id, cnt, f)
980         }
981
982         fn emit_enum_struct_variant_field<F>(&mut self,
983                                              _: &str,
984                                              idx: uint,
985                                              f: F) -> EncodeResult where
986             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
987         {
988             self.emit_enum_variant_arg(idx, f)
989         }
990
991         fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
992             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
993         {
994             f(self)
995         }
996
997         fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
998             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
999         {
1000             try!(self._emit_label(name));
1001             f(self)
1002         }
1003
1004         fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
1005             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1006         {
1007             self.emit_seq(len, f)
1008         }
1009         fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1010             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1011         {
1012             self.emit_seq_elt(idx, f)
1013         }
1014
1015         fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
1016             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1017         {
1018             self.emit_seq(len, f)
1019         }
1020         fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1021             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1022         {
1023             self.emit_seq_elt(idx, f)
1024         }
1025
1026         fn emit_option<F>(&mut self, f: F) -> EncodeResult where
1027             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1028         {
1029             self.emit_enum("Option", f)
1030         }
1031         fn emit_option_none(&mut self) -> EncodeResult {
1032             self.emit_enum_variant("None", 0, 0, |_| Ok(()))
1033         }
1034         fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
1035             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1036         {
1037
1038             self.emit_enum_variant("Some", 1, 1, f)
1039         }
1040
1041         fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
1042             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1043         {
1044
1045             try!(self.start_tag(EsVec as uint));
1046             try!(self._emit_tagged_uint(EsVecLen, len));
1047             try!(f(self));
1048             self.end_tag()
1049         }
1050
1051         fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1052             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1053         {
1054
1055             try!(self.start_tag(EsVecElt as uint));
1056             try!(f(self));
1057             self.end_tag()
1058         }
1059
1060         fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
1061             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1062         {
1063
1064             try!(self.start_tag(EsMap as uint));
1065             try!(self._emit_tagged_uint(EsMapLen, len));
1066             try!(f(self));
1067             self.end_tag()
1068         }
1069
1070         fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1071             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1072         {
1073
1074             try!(self.start_tag(EsMapKey as uint));
1075             try!(f(self));
1076             self.end_tag()
1077         }
1078
1079         fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1080             F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1081         {
1082             try!(self.start_tag(EsMapVal as uint));
1083             try!(f(self));
1084             self.end_tag()
1085         }
1086     }
1087 }
1088
1089 // ___________________________________________________________________________
1090 // Testing
1091
1092 #[cfg(test)]
1093 mod tests {
1094     use super::{Doc, reader, writer};
1095     use super::io::SeekableMemWriter;
1096
1097     use serialize::{Encodable, Decodable};
1098
1099     use std::option::Option;
1100     use std::option::Option::{None, Some};
1101
1102     #[test]
1103     fn test_vuint_at() {
1104         let data = &[
1105             0x80,
1106             0xff,
1107             0x40, 0x00,
1108             0x7f, 0xff,
1109             0x20, 0x00, 0x00,
1110             0x3f, 0xff, 0xff,
1111             0x10, 0x00, 0x00, 0x00,
1112             0x1f, 0xff, 0xff, 0xff
1113         ];
1114
1115         let mut res: reader::Res;
1116
1117         // Class A
1118         res = reader::vuint_at(data, 0).unwrap();
1119         assert_eq!(res.val, 0);
1120         assert_eq!(res.next, 1);
1121         res = reader::vuint_at(data, res.next).unwrap();
1122         assert_eq!(res.val, (1 << 7) - 1);
1123         assert_eq!(res.next, 2);
1124
1125         // Class B
1126         res = reader::vuint_at(data, res.next).unwrap();
1127         assert_eq!(res.val, 0);
1128         assert_eq!(res.next, 4);
1129         res = reader::vuint_at(data, res.next).unwrap();
1130         assert_eq!(res.val, (1 << 14) - 1);
1131         assert_eq!(res.next, 6);
1132
1133         // Class C
1134         res = reader::vuint_at(data, res.next).unwrap();
1135         assert_eq!(res.val, 0);
1136         assert_eq!(res.next, 9);
1137         res = reader::vuint_at(data, res.next).unwrap();
1138         assert_eq!(res.val, (1 << 21) - 1);
1139         assert_eq!(res.next, 12);
1140
1141         // Class D
1142         res = reader::vuint_at(data, res.next).unwrap();
1143         assert_eq!(res.val, 0);
1144         assert_eq!(res.next, 16);
1145         res = reader::vuint_at(data, res.next).unwrap();
1146         assert_eq!(res.val, (1 << 28) - 1);
1147         assert_eq!(res.next, 20);
1148     }
1149
1150     #[test]
1151     fn test_option_int() {
1152         fn test_v(v: Option<int>) {
1153             debug!("v == {:?}", v);
1154             let mut wr = SeekableMemWriter::new();
1155             {
1156                 let mut rbml_w = writer::Encoder::new(&mut wr);
1157                 let _ = v.encode(&mut rbml_w);
1158             }
1159             let rbml_doc = Doc::new(wr.get_ref());
1160             let mut deser = reader::Decoder::new(rbml_doc);
1161             let v1 = Decodable::decode(&mut deser).unwrap();
1162             debug!("v1 == {:?}", v1);
1163             assert_eq!(v, v1);
1164         }
1165
1166         test_v(Some(22));
1167         test_v(None);
1168         test_v(Some(3));
1169     }
1170 }
1171
1172 #[cfg(test)]
1173 mod bench {
1174     #![allow(non_snake_case)]
1175     use test::Bencher;
1176     use super::reader;
1177
1178     #[bench]
1179     pub fn vuint_at_A_aligned(b: &mut Bencher) {
1180         let data = range(0, 4*100).map(|i| {
1181             match i % 2 {
1182               0 => 0x80u8,
1183               _ => i as u8,
1184             }
1185         }).collect::<Vec<_>>();
1186         let mut sum = 0u;
1187         b.iter(|| {
1188             let mut i = 0;
1189             while i < data.len() {
1190                 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1191                 i += 4;
1192             }
1193         });
1194     }
1195
1196     #[bench]
1197     pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1198         let data = range(0, 4*100+1).map(|i| {
1199             match i % 2 {
1200               1 => 0x80u8,
1201               _ => i as u8
1202             }
1203         }).collect::<Vec<_>>();
1204         let mut sum = 0u;
1205         b.iter(|| {
1206             let mut i = 1;
1207             while i < data.len() {
1208                 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1209                 i += 4;
1210             }
1211         });
1212     }
1213
1214     #[bench]
1215     pub fn vuint_at_D_aligned(b: &mut Bencher) {
1216         let data = range(0, 4*100).map(|i| {
1217             match i % 4 {
1218               0 => 0x10u8,
1219               3 => i as u8,
1220               _ => 0u8
1221             }
1222         }).collect::<Vec<_>>();
1223         let mut sum = 0u;
1224         b.iter(|| {
1225             let mut i = 0;
1226             while i < data.len() {
1227                 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1228                 i += 4;
1229             }
1230         });
1231     }
1232
1233     #[bench]
1234     pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1235         let data = range(0, 4*100+1).map(|i| {
1236             match i % 4 {
1237               1 => 0x10u8,
1238               0 => i as u8,
1239               _ => 0u8
1240             }
1241         }).collect::<Vec<_>>();
1242         let mut sum = 0u;
1243         b.iter(|| {
1244             let mut i = 1;
1245             while i < data.len() {
1246                 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1247                 i += 4;
1248             }
1249         });
1250     }
1251 }