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