1 // Copyright 2012-2013 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.
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.
11 #[allow(missing_doc)];
15 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
16 // cursor model. See the specification here:
17 // http://www.matroska.org/technical/specs/rfc/index.html
19 // Common data structures
27 impl<'doc> Doc<'doc> {
28 pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
29 reader::get_doc(*self, tag)
32 pub fn as_str_slice<'a>(&'a self) -> &'a str {
33 str::from_utf8(self.data.slice(self.start, self.end))
36 pub fn as_str(&self) -> ~str {
37 self.as_str_slice().to_owned()
41 pub struct TaggedDoc<'a> {
46 pub enum EbmlEncoderTag {
76 EsLabel, // Used only when debugging
78 // --------------------------------------
86 use std::cast::transmute;
88 use std::option::{None, Option, Some};
89 use std::io::extensions::u64_from_be_bytes;
99 fn vuint_at_slow(data: &[u8], start: uint) -> Res {
101 if a & 0x80u8 != 0u8 {
102 return Res {val: (a & 0x7fu8) as uint, next: start + 1u};
104 if a & 0x40u8 != 0u8 {
105 return Res {val: ((a & 0x3fu8) as uint) << 8u |
106 (data[start + 1u] as uint),
109 if a & 0x20u8 != 0u8 {
110 return Res {val: ((a & 0x1fu8) as uint) << 16u |
111 (data[start + 1u] as uint) << 8u |
112 (data[start + 2u] as uint),
115 if a & 0x10u8 != 0u8 {
116 return Res {val: ((a & 0x0fu8) as uint) << 24u |
117 (data[start + 1u] as uint) << 16u |
118 (data[start + 2u] as uint) << 8u |
119 (data[start + 3u] as uint),
122 fail!("vint too big");
125 pub fn vuint_at(data: &[u8], start: uint) -> Res {
126 use std::ptr::offset;
127 use std::unstable::intrinsics::from_be32;
129 if data.len() - start < 4 {
130 return vuint_at_slow(data, start);
134 let (ptr, _): (*u8, uint) = transmute(data);
135 let ptr = offset(ptr, start as int);
136 let ptr: *i32 = transmute(ptr);
137 let val = from_be32(*ptr);
138 let val: u32 = transmute(val);
139 if (val & 0x80000000) != 0 {
141 val: ((val >> 24) & 0x7f) as uint,
144 } else if (val & 0x40000000) != 0 {
146 val: ((val >> 16) & 0x3fff) as uint,
149 } else if (val & 0x20000000) != 0 {
151 val: ((val >> 8) & 0x1fffff) as uint,
156 val: (val & 0x0fffffff) as uint,
163 pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> {
164 Doc { data: data, start: 0u, end: data.len() }
167 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> TaggedDoc<'a> {
168 let elt_tag = vuint_at(data, start);
169 let elt_size = vuint_at(data, elt_tag.next);
170 let end = elt_size.next + elt_size.val;
173 doc: Doc { data: data, start: elt_size.next, end: end }
177 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
178 let mut pos = d.start;
180 let elt_tag = vuint_at(d.data, pos);
181 let elt_size = vuint_at(d.data, elt_tag.next);
182 pos = elt_size.next + elt_size.val;
183 if elt_tag.val == tg {
184 return Some(Doc { data: d.data, start: elt_size.next,
191 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
192 match maybe_get_doc(d, tg) {
195 error!("failed to find block with tag {}", tg);
201 pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
202 let mut pos = d.start;
204 let elt_tag = vuint_at(d.data, pos);
205 let elt_size = vuint_at(d.data, elt_tag.next);
206 pos = elt_size.next + elt_size.val;
207 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
208 if !it(elt_tag.val, doc) {
215 pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
216 let mut pos = d.start;
218 let elt_tag = vuint_at(d.data, pos);
219 let elt_size = vuint_at(d.data, elt_tag.next);
220 pos = elt_size.next + elt_size.val;
221 if elt_tag.val == tg {
222 let doc = Doc { data: d.data, start: elt_size.next,
232 pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T {
233 f(d.data.slice(d.start, d.end))
237 pub fn doc_as_u8(d: Doc) -> u8 {
238 assert_eq!(d.end, d.start + 1u);
242 pub fn doc_as_u16(d: Doc) -> u16 {
243 assert_eq!(d.end, d.start + 2u);
244 u64_from_be_bytes(d.data, d.start, 2u) as u16
247 pub fn doc_as_u32(d: Doc) -> u32 {
248 assert_eq!(d.end, d.start + 4u);
249 u64_from_be_bytes(d.data, d.start, 4u) as u32
252 pub fn doc_as_u64(d: Doc) -> u64 {
253 assert_eq!(d.end, d.start + 8u);
254 u64_from_be_bytes(d.data, d.start, 8u)
257 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
258 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
259 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
260 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
262 pub struct Decoder<'a> {
263 priv parent: Doc<'a>,
267 pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> {
274 impl<'doc> Decoder<'doc> {
275 fn _check_label(&mut self, lbl: &str) {
276 if self.pos < self.parent.end {
277 let TaggedDoc { tag: r_tag, doc: r_doc } =
278 doc_at(self.parent.data, self.pos);
280 if r_tag == (EsLabel as uint) {
281 self.pos = r_doc.end;
282 let str = r_doc.as_str_slice();
284 fail!("Expected label {} but found {}", lbl, str);
290 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc<'doc> {
291 debug!(". next_doc(exp_tag={:?})", exp_tag);
292 if self.pos >= self.parent.end {
293 fail!("no more documents in current node!");
295 let TaggedDoc { tag: r_tag, doc: r_doc } =
296 doc_at(self.parent.data, self.pos);
297 debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
304 if r_tag != (exp_tag as uint) {
305 fail!("expected EBML doc with tag {:?} but found tag {:?}",
308 if r_doc.end > self.parent.end {
309 fail!("invalid EBML, child extends to {:#x}, parent to {:#x}",
310 r_doc.end, self.parent.end);
312 self.pos = r_doc.end;
316 fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
317 f: |&mut Decoder<'doc>| -> T) -> T {
318 let d = self.next_doc(exp_tag);
319 let old_parent = self.parent;
320 let old_pos = self.pos;
324 self.parent = old_parent;
329 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint {
330 let r = doc_as_u32(self.next_doc(exp_tag));
331 debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
335 pub fn read_opaque<R>(&mut self, op: |&mut Decoder<'doc>, Doc| -> R) -> R {
336 let doc = self.next_doc(EsOpaque);
338 let (old_parent, old_pos) = (self.parent, self.pos);
340 self.pos = doc.start;
342 let result = op(self, doc);
344 self.parent = old_parent;
350 impl<'doc> serialize::Decoder for Decoder<'doc> {
351 fn read_nil(&mut self) -> () { () }
353 fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
354 fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
355 fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
356 fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) }
357 fn read_uint(&mut self) -> uint {
358 let v = doc_as_u64(self.next_doc(EsUint));
359 if v > (::std::uint::max_value as u64) {
360 fail!("uint {} too large for this architecture", v);
365 fn read_i64(&mut self) -> i64 {
366 doc_as_u64(self.next_doc(EsI64)) as i64
368 fn read_i32(&mut self) -> i32 {
369 doc_as_u32(self.next_doc(EsI32)) as i32
371 fn read_i16(&mut self) -> i16 {
372 doc_as_u16(self.next_doc(EsI16)) as i16
374 fn read_i8 (&mut self) -> i8 {
375 doc_as_u8(self.next_doc(EsI8 )) as i8
377 fn read_int(&mut self) -> int {
378 let v = doc_as_u64(self.next_doc(EsInt)) as i64;
379 if v > (int::max_value as i64) || v < (int::min_value as i64) {
380 debug!("FIXME \\#6122: Removing this makes this function miscompile");
381 fail!("int {} out of range for this architecture", v);
386 fn read_bool(&mut self) -> bool {
387 doc_as_u8(self.next_doc(EsBool)) != 0
390 fn read_f64(&mut self) -> f64 {
391 let bits = doc_as_u64(self.next_doc(EsF64));
392 unsafe { transmute(bits) }
394 fn read_f32(&mut self) -> f32 {
395 let bits = doc_as_u32(self.next_doc(EsF32));
396 unsafe { transmute(bits) }
398 fn read_char(&mut self) -> char {
399 char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap()
401 fn read_str(&mut self) -> ~str {
402 self.next_doc(EsStr).as_str()
406 fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder<'doc>| -> T) -> T {
407 debug!("read_enum({})", name);
408 self._check_label(name);
410 let doc = self.next_doc(EsEnum);
412 let (old_parent, old_pos) = (self.parent, self.pos);
414 self.pos = self.parent.start;
416 let result = f(self);
418 self.parent = old_parent;
423 fn read_enum_variant<T>(&mut self,
425 f: |&mut Decoder<'doc>, uint| -> T)
427 debug!("read_enum_variant()");
428 let idx = self._next_uint(EsEnumVid);
429 debug!(" idx={}", idx);
431 let doc = self.next_doc(EsEnumBody);
433 let (old_parent, old_pos) = (self.parent, self.pos);
435 self.pos = self.parent.start;
437 let result = f(self, idx);
439 self.parent = old_parent;
444 fn read_enum_variant_arg<T>(&mut self,
446 f: |&mut Decoder<'doc>| -> T) -> T {
447 debug!("read_enum_variant_arg(idx={})", idx);
451 fn read_enum_struct_variant<T>(&mut self,
453 f: |&mut Decoder<'doc>, uint| -> T)
455 debug!("read_enum_struct_variant()");
456 let idx = self._next_uint(EsEnumVid);
457 debug!(" idx={}", idx);
459 let doc = self.next_doc(EsEnumBody);
461 let (old_parent, old_pos) = (self.parent, self.pos);
463 self.pos = self.parent.start;
465 let result = f(self, idx);
467 self.parent = old_parent;
472 fn read_enum_struct_variant_field<T>(&mut self,
475 f: |&mut Decoder<'doc>| -> T)
477 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
481 fn read_struct<T>(&mut self,
484 f: |&mut Decoder<'doc>| -> T)
486 debug!("read_struct(name={})", name);
490 fn read_struct_field<T>(&mut self,
493 f: |&mut Decoder<'doc>| -> T)
495 debug!("read_struct_field(name={}, idx={})", name, idx);
496 self._check_label(name);
500 fn read_tuple<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
501 debug!("read_tuple()");
505 fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
507 debug!("read_tuple_arg(idx={})", idx);
508 self.read_seq_elt(idx, f)
511 fn read_tuple_struct<T>(&mut self,
513 f: |&mut Decoder<'doc>, uint| -> T)
515 debug!("read_tuple_struct(name={})", name);
519 fn read_tuple_struct_arg<T>(&mut self,
521 f: |&mut Decoder<'doc>| -> T)
523 debug!("read_tuple_struct_arg(idx={})", idx);
524 self.read_tuple_arg(idx, f)
527 fn read_option<T>(&mut self, f: |&mut Decoder<'doc>, bool| -> T) -> T {
528 debug!("read_option()");
529 self.read_enum("Option", |this| {
530 this.read_enum_variant(["None", "Some"], |this, idx| {
540 fn read_seq<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
541 debug!("read_seq()");
542 self.push_doc(EsVec, |d| {
543 let len = d._next_uint(EsVecLen);
544 debug!(" len={}", len);
549 fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
551 debug!("read_seq_elt(idx={})", idx);
552 self.push_doc(EsVecElt, f)
555 fn read_map<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
556 debug!("read_map()");
557 self.push_doc(EsMap, |d| {
558 let len = d._next_uint(EsMapLen);
559 debug!(" len={}", len);
564 fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
566 debug!("read_map_elt_key(idx={})", idx);
567 self.push_doc(EsMapKey, f)
570 fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
572 debug!("read_map_elt_val(idx={})", idx);
573 self.push_doc(EsMapVal, f)
582 use std::clone::Clone;
584 use std::io::{Writer, Seek};
585 use std::io::MemWriter;
586 use std::io::extensions::u64_to_be_bytes;
589 pub struct Encoder<'a> {
590 // FIXME(#5665): this should take a trait object
591 writer: &'a mut MemWriter,
592 priv size_positions: ~[uint],
595 fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
597 1u => w.write(&[0x80u8 | (n as u8)]),
598 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
599 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
601 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
602 (n >> 8_u) as u8, n as u8]),
603 _ => fail!("vint to write too big: {}", n)
607 fn write_vuint(w: &mut MemWriter, n: uint) {
608 if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
609 if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
610 if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
611 if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
612 fail!("vint to write too big: {}", n);
615 pub fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> {
616 let size_positions: ~[uint] = ~[];
619 size_positions: size_positions
623 // FIXME (#2741): Provide a function to write the standard ebml header.
624 impl<'a> Encoder<'a> {
625 /// XXX(pcwalton): Workaround for badness in trans. DO NOT USE ME.
626 pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
628 writer: cast::transmute_copy(&self.writer),
629 size_positions: self.size_positions.clone(),
633 pub fn start_tag(&mut self, tag_id: uint) {
634 debug!("Start tag {}", tag_id);
636 // Write the enum ID:
637 write_vuint(self.writer, tag_id);
639 // Write a placeholder four-byte size.
640 self.size_positions.push(self.writer.tell() as uint);
641 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
642 self.writer.write(zeroes);
645 pub fn end_tag(&mut self) {
646 let last_size_pos = self.size_positions.pop();
647 let cur_pos = self.writer.tell();
648 self.writer.seek(last_size_pos as i64, io::SeekSet);
649 let size = (cur_pos as uint - last_size_pos - 4);
650 write_sized_vuint(self.writer, size, 4u);
651 self.writer.seek(cur_pos as i64, io::SeekSet);
653 debug!("End tag (size = {})", size);
656 pub fn wr_tag(&mut self, tag_id: uint, blk: ||) {
657 self.start_tag(tag_id);
662 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
663 write_vuint(self.writer, tag_id);
664 write_vuint(self.writer, b.len());
665 self.writer.write(b);
668 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
669 u64_to_be_bytes(v, 8u, |v| {
670 self.wr_tagged_bytes(tag_id, v);
674 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) {
675 u64_to_be_bytes(v as u64, 4u, |v| {
676 self.wr_tagged_bytes(tag_id, v);
680 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) {
681 u64_to_be_bytes(v as u64, 2u, |v| {
682 self.wr_tagged_bytes(tag_id, v);
686 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) {
687 self.wr_tagged_bytes(tag_id, &[v]);
690 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) {
691 u64_to_be_bytes(v as u64, 8u, |v| {
692 self.wr_tagged_bytes(tag_id, v);
696 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) {
697 u64_to_be_bytes(v as u64, 4u, |v| {
698 self.wr_tagged_bytes(tag_id, v);
702 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) {
703 u64_to_be_bytes(v as u64, 2u, |v| {
704 self.wr_tagged_bytes(tag_id, v);
708 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) {
709 self.wr_tagged_bytes(tag_id, &[v as u8]);
712 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) {
713 self.wr_tagged_bytes(tag_id, v.as_bytes());
716 pub fn wr_bytes(&mut self, b: &[u8]) {
717 debug!("Write {} bytes", b.len());
718 self.writer.write(b);
721 pub fn wr_str(&mut self, s: &str) {
722 debug!("Write str: {}", s);
723 self.writer.write(s.as_bytes());
727 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
728 // efficiently encode sizes; this is a fixed point iteration
730 // Set to true to generate more debugging in EBML code.
731 // Totally lame approach.
732 static DEBUG: bool = true;
734 impl<'a> Encoder<'a> {
735 // used internally to emit things like the vector length and so on
736 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) {
737 assert!(v <= 0xFFFF_FFFF_u);
738 self.wr_tagged_u32(t as uint, v as u32);
741 fn _emit_label(&mut self, label: &str) {
742 // There are various strings that we have access to, such as
743 // the name of a record field, which do not actually appear in
744 // the encoded EBML (normally). This is just for
745 // efficiency. When debugging, though, we can emit such
746 // labels and then they will be checked by decoder to
747 // try and check failures more quickly.
748 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
751 pub fn emit_opaque(&mut self, f: |&mut Encoder|) {
752 self.start_tag(EsOpaque as uint);
758 impl<'a> ::serialize::Encoder for Encoder<'a> {
759 fn emit_nil(&mut self) {}
761 fn emit_uint(&mut self, v: uint) {
762 self.wr_tagged_u64(EsUint as uint, v as u64);
764 fn emit_u64(&mut self, v: u64) {
765 self.wr_tagged_u64(EsU64 as uint, v);
767 fn emit_u32(&mut self, v: u32) {
768 self.wr_tagged_u32(EsU32 as uint, v);
770 fn emit_u16(&mut self, v: u16) {
771 self.wr_tagged_u16(EsU16 as uint, v);
773 fn emit_u8(&mut self, v: u8) {
774 self.wr_tagged_u8(EsU8 as uint, v);
777 fn emit_int(&mut self, v: int) {
778 self.wr_tagged_i64(EsInt as uint, v as i64);
780 fn emit_i64(&mut self, v: i64) {
781 self.wr_tagged_i64(EsI64 as uint, v);
783 fn emit_i32(&mut self, v: i32) {
784 self.wr_tagged_i32(EsI32 as uint, v);
786 fn emit_i16(&mut self, v: i16) {
787 self.wr_tagged_i16(EsI16 as uint, v);
789 fn emit_i8(&mut self, v: i8) {
790 self.wr_tagged_i8(EsI8 as uint, v);
793 fn emit_bool(&mut self, v: bool) {
794 self.wr_tagged_u8(EsBool as uint, v as u8)
797 fn emit_f64(&mut self, v: f64) {
798 let bits = unsafe { cast::transmute(v) };
799 self.wr_tagged_u64(EsF64 as uint, bits);
801 fn emit_f32(&mut self, v: f32) {
802 let bits = unsafe { cast::transmute(v) };
803 self.wr_tagged_u32(EsF32 as uint, bits);
805 fn emit_char(&mut self, v: char) {
806 self.wr_tagged_u32(EsChar as uint, v as u32);
809 fn emit_str(&mut self, v: &str) {
810 self.wr_tagged_str(EsStr as uint, v)
813 fn emit_enum(&mut self, name: &str, f: |&mut Encoder<'a>|) {
814 self._emit_label(name);
815 self.start_tag(EsEnum as uint);
820 fn emit_enum_variant(&mut self,
824 f: |&mut Encoder<'a>|) {
825 self._emit_tagged_uint(EsEnumVid, v_id);
826 self.start_tag(EsEnumBody as uint);
831 fn emit_enum_variant_arg(&mut self, _: uint, f: |&mut Encoder<'a>|) {
835 fn emit_enum_struct_variant(&mut self,
839 f: |&mut Encoder<'a>|) {
840 self.emit_enum_variant(v_name, v_id, cnt, f)
843 fn emit_enum_struct_variant_field(&mut self,
846 f: |&mut Encoder<'a>|) {
847 self.emit_enum_variant_arg(idx, f)
850 fn emit_struct(&mut self,
853 f: |&mut Encoder<'a>|) {
857 fn emit_struct_field(&mut self,
860 f: |&mut Encoder<'a>|) {
861 self._emit_label(name);
865 fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) {
866 self.emit_seq(len, f)
868 fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
869 self.emit_seq_elt(idx, f)
872 fn emit_tuple_struct(&mut self,
875 f: |&mut Encoder<'a>|) {
876 self.emit_seq(len, f)
878 fn emit_tuple_struct_arg(&mut self,
880 f: |&mut Encoder<'a>|) {
881 self.emit_seq_elt(idx, f)
884 fn emit_option(&mut self, f: |&mut Encoder<'a>|) {
885 self.emit_enum("Option", f);
887 fn emit_option_none(&mut self) {
888 self.emit_enum_variant("None", 0, 0, |_| ())
890 fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) {
891 self.emit_enum_variant("Some", 1, 1, f)
894 fn emit_seq(&mut self, len: uint, f: |&mut Encoder<'a>|) {
895 self.start_tag(EsVec as uint);
896 self._emit_tagged_uint(EsVecLen, len);
901 fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
902 self.start_tag(EsVecElt as uint);
907 fn emit_map(&mut self, len: uint, f: |&mut Encoder<'a>|) {
908 self.start_tag(EsMap as uint);
909 self._emit_tagged_uint(EsMapLen, len);
914 fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
915 self.start_tag(EsMapKey as uint);
920 fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
921 self.start_tag(EsMapVal as uint);
928 // ___________________________________________________________________________
935 use serialize::Encodable;
938 use std::io::MemWriter;
939 use std::option::{None, Option, Some};
942 fn test_option_int() {
943 fn test_v(v: Option<int>) {
944 debug!("v == {:?}", v);
945 let mut wr = MemWriter::new();
947 let mut ebml_w = writer::Encoder(&mut wr);
948 v.encode(&mut ebml_w);
950 let ebml_doc = reader::Doc(wr.get_ref());
951 let mut deser = reader::Decoder(ebml_doc);
952 let v1 = serialize::Decodable::decode(&mut deser);
953 debug!("v1 == {:?}", v1);
966 use test::BenchHarness;
969 pub fn vuint_at_A_aligned(bh: &mut BenchHarness) {
971 let data = vec::from_fn(4*100, |i| {
980 while (i < data.len()) {
981 sum += reader::vuint_at(data, i).val;
988 pub fn vuint_at_A_unaligned(bh: &mut BenchHarness) {
990 let data = vec::from_fn(4*100+1, |i| {
999 while (i < data.len()) {
1000 sum += reader::vuint_at(data, i).val;
1007 pub fn vuint_at_D_aligned(bh: &mut BenchHarness) {
1009 let data = vec::from_fn(4*100, |i| {
1019 while (i < data.len()) {
1020 sum += reader::vuint_at(data, i).val;
1027 pub fn vuint_at_D_unaligned(bh: &mut BenchHarness) {
1029 let data = vec::from_fn(4*100+1, |i| {
1039 while (i < data.len()) {
1040 sum += reader::vuint_at(data, i).val;