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