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