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);
133 // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
134 // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
135 // Using the four most significant bits of the u32 we lookup in the table below how the
136 // element ID should be derived from it.
138 // The table stores tuples (shift, mask) where shift is the number the u32 should be right
139 // shifted with and mask is the value the right shifted value should be masked with.
140 // If for example the most significant bit is set this means it's a class A ID and the u32
141 // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
142 // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
144 // By storing the number of shifts and masks in a table instead of checking in order if
145 // the most significant bit is set, the second most significant bit is set etc. we can
146 // replace up to three "and+branch" with a single table lookup which gives us a measured
147 // speedup of around 2x on x86_64.
148 static SHIFT_MASK_TABLE: [(u32, u32), ..16] = [
149 (0, 0x0), (0, 0x0fffffff),
150 (8, 0x1fffff), (8, 0x1fffff),
151 (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
152 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
153 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
157 let (ptr, _): (*u8, uint) = transmute(data);
158 let ptr = offset(ptr, start as int);
159 let ptr: *i32 = transmute(ptr);
160 let val = from_be32(*ptr) as u32;
162 let i = (val >> 28u) as uint;
163 let (shift, mask) = SHIFT_MASK_TABLE[i];
165 val: ((val >> shift) & mask) as uint,
166 next: start + (((32 - shift) >> 3) as uint)
171 pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> {
172 Doc { data: data, start: 0u, end: data.len() }
175 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> TaggedDoc<'a> {
176 let elt_tag = vuint_at(data, start);
177 let elt_size = vuint_at(data, elt_tag.next);
178 let end = elt_size.next + elt_size.val;
181 doc: Doc { data: data, start: elt_size.next, end: end }
185 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
186 let mut pos = d.start;
188 let elt_tag = vuint_at(d.data, pos);
189 let elt_size = vuint_at(d.data, elt_tag.next);
190 pos = elt_size.next + elt_size.val;
191 if elt_tag.val == tg {
192 return Some(Doc { data: d.data, start: elt_size.next,
199 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
200 match maybe_get_doc(d, tg) {
203 error!("failed to find block with tag {}", tg);
209 pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
210 let mut pos = d.start;
212 let elt_tag = vuint_at(d.data, pos);
213 let elt_size = vuint_at(d.data, elt_tag.next);
214 pos = elt_size.next + elt_size.val;
215 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
216 if !it(elt_tag.val, doc) {
223 pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
224 let mut pos = d.start;
226 let elt_tag = vuint_at(d.data, pos);
227 let elt_size = vuint_at(d.data, elt_tag.next);
228 pos = elt_size.next + elt_size.val;
229 if elt_tag.val == tg {
230 let doc = Doc { data: d.data, start: elt_size.next,
240 pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T {
241 f(d.data.slice(d.start, d.end))
245 pub fn doc_as_u8(d: Doc) -> u8 {
246 assert_eq!(d.end, d.start + 1u);
250 pub fn doc_as_u16(d: Doc) -> u16 {
251 assert_eq!(d.end, d.start + 2u);
252 u64_from_be_bytes(d.data, d.start, 2u) as u16
255 pub fn doc_as_u32(d: Doc) -> u32 {
256 assert_eq!(d.end, d.start + 4u);
257 u64_from_be_bytes(d.data, d.start, 4u) as u32
260 pub fn doc_as_u64(d: Doc) -> u64 {
261 assert_eq!(d.end, d.start + 8u);
262 u64_from_be_bytes(d.data, d.start, 8u)
265 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
266 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
267 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
268 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
270 pub struct Decoder<'a> {
271 priv parent: Doc<'a>,
275 pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> {
282 impl<'doc> Decoder<'doc> {
283 fn _check_label(&mut self, lbl: &str) {
284 if self.pos < self.parent.end {
285 let TaggedDoc { tag: r_tag, doc: r_doc } =
286 doc_at(self.parent.data, self.pos);
288 if r_tag == (EsLabel as uint) {
289 self.pos = r_doc.end;
290 let str = r_doc.as_str_slice();
292 fail!("Expected label {} but found {}", lbl, str);
298 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc<'doc> {
299 debug!(". next_doc(exp_tag={:?})", exp_tag);
300 if self.pos >= self.parent.end {
301 fail!("no more documents in current node!");
303 let TaggedDoc { tag: r_tag, doc: r_doc } =
304 doc_at(self.parent.data, self.pos);
305 debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
312 if r_tag != (exp_tag as uint) {
313 fail!("expected EBML doc with tag {:?} but found tag {:?}",
316 if r_doc.end > self.parent.end {
317 fail!("invalid EBML, child extends to {:#x}, parent to {:#x}",
318 r_doc.end, self.parent.end);
320 self.pos = r_doc.end;
324 fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
325 f: |&mut Decoder<'doc>| -> T) -> T {
326 let d = self.next_doc(exp_tag);
327 let old_parent = self.parent;
328 let old_pos = self.pos;
332 self.parent = old_parent;
337 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint {
338 let r = doc_as_u32(self.next_doc(exp_tag));
339 debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
343 pub fn read_opaque<R>(&mut self, op: |&mut Decoder<'doc>, Doc| -> R) -> R {
344 let doc = self.next_doc(EsOpaque);
346 let (old_parent, old_pos) = (self.parent, self.pos);
348 self.pos = doc.start;
350 let result = op(self, doc);
352 self.parent = old_parent;
358 impl<'doc> serialize::Decoder for Decoder<'doc> {
359 fn read_nil(&mut self) -> () { () }
361 fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
362 fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
363 fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
364 fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) }
365 fn read_uint(&mut self) -> uint {
366 let v = doc_as_u64(self.next_doc(EsUint));
367 if v > (::std::uint::max_value as u64) {
368 fail!("uint {} too large for this architecture", v);
373 fn read_i64(&mut self) -> i64 {
374 doc_as_u64(self.next_doc(EsI64)) as i64
376 fn read_i32(&mut self) -> i32 {
377 doc_as_u32(self.next_doc(EsI32)) as i32
379 fn read_i16(&mut self) -> i16 {
380 doc_as_u16(self.next_doc(EsI16)) as i16
382 fn read_i8 (&mut self) -> i8 {
383 doc_as_u8(self.next_doc(EsI8 )) as i8
385 fn read_int(&mut self) -> int {
386 let v = doc_as_u64(self.next_doc(EsInt)) as i64;
387 if v > (int::max_value as i64) || v < (int::min_value as i64) {
388 debug!("FIXME \\#6122: Removing this makes this function miscompile");
389 fail!("int {} out of range for this architecture", v);
394 fn read_bool(&mut self) -> bool {
395 doc_as_u8(self.next_doc(EsBool)) != 0
398 fn read_f64(&mut self) -> f64 {
399 let bits = doc_as_u64(self.next_doc(EsF64));
400 unsafe { transmute(bits) }
402 fn read_f32(&mut self) -> f32 {
403 let bits = doc_as_u32(self.next_doc(EsF32));
404 unsafe { transmute(bits) }
406 fn read_char(&mut self) -> char {
407 char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap()
409 fn read_str(&mut self) -> ~str {
410 self.next_doc(EsStr).as_str()
414 fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder<'doc>| -> T) -> T {
415 debug!("read_enum({})", name);
416 self._check_label(name);
418 let doc = self.next_doc(EsEnum);
420 let (old_parent, old_pos) = (self.parent, self.pos);
422 self.pos = self.parent.start;
424 let result = f(self);
426 self.parent = old_parent;
431 fn read_enum_variant<T>(&mut self,
433 f: |&mut Decoder<'doc>, uint| -> T)
435 debug!("read_enum_variant()");
436 let idx = self._next_uint(EsEnumVid);
437 debug!(" idx={}", idx);
439 let doc = self.next_doc(EsEnumBody);
441 let (old_parent, old_pos) = (self.parent, self.pos);
443 self.pos = self.parent.start;
445 let result = f(self, idx);
447 self.parent = old_parent;
452 fn read_enum_variant_arg<T>(&mut self,
454 f: |&mut Decoder<'doc>| -> T) -> T {
455 debug!("read_enum_variant_arg(idx={})", idx);
459 fn read_enum_struct_variant<T>(&mut self,
461 f: |&mut Decoder<'doc>, uint| -> T)
463 debug!("read_enum_struct_variant()");
464 let idx = self._next_uint(EsEnumVid);
465 debug!(" idx={}", idx);
467 let doc = self.next_doc(EsEnumBody);
469 let (old_parent, old_pos) = (self.parent, self.pos);
471 self.pos = self.parent.start;
473 let result = f(self, idx);
475 self.parent = old_parent;
480 fn read_enum_struct_variant_field<T>(&mut self,
483 f: |&mut Decoder<'doc>| -> T)
485 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
489 fn read_struct<T>(&mut self,
492 f: |&mut Decoder<'doc>| -> T)
494 debug!("read_struct(name={})", name);
498 fn read_struct_field<T>(&mut self,
501 f: |&mut Decoder<'doc>| -> T)
503 debug!("read_struct_field(name={}, idx={})", name, idx);
504 self._check_label(name);
508 fn read_tuple<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
509 debug!("read_tuple()");
513 fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
515 debug!("read_tuple_arg(idx={})", idx);
516 self.read_seq_elt(idx, f)
519 fn read_tuple_struct<T>(&mut self,
521 f: |&mut Decoder<'doc>, uint| -> T)
523 debug!("read_tuple_struct(name={})", name);
527 fn read_tuple_struct_arg<T>(&mut self,
529 f: |&mut Decoder<'doc>| -> T)
531 debug!("read_tuple_struct_arg(idx={})", idx);
532 self.read_tuple_arg(idx, f)
535 fn read_option<T>(&mut self, f: |&mut Decoder<'doc>, bool| -> T) -> T {
536 debug!("read_option()");
537 self.read_enum("Option", |this| {
538 this.read_enum_variant(["None", "Some"], |this, idx| {
548 fn read_seq<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
549 debug!("read_seq()");
550 self.push_doc(EsVec, |d| {
551 let len = d._next_uint(EsVecLen);
552 debug!(" len={}", len);
557 fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
559 debug!("read_seq_elt(idx={})", idx);
560 self.push_doc(EsVecElt, f)
563 fn read_map<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
564 debug!("read_map()");
565 self.push_doc(EsMap, |d| {
566 let len = d._next_uint(EsMapLen);
567 debug!(" len={}", len);
572 fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
574 debug!("read_map_elt_key(idx={})", idx);
575 self.push_doc(EsMapKey, f)
578 fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
580 debug!("read_map_elt_val(idx={})", idx);
581 self.push_doc(EsMapVal, f)
590 use std::clone::Clone;
592 use std::io::{Writer, Seek};
593 use std::io::mem::MemWriter;
594 use std::io::extensions::u64_to_be_bytes;
597 pub struct Encoder<'a> {
598 // FIXME(#5665): this should take a trait object
599 writer: &'a mut MemWriter,
600 priv size_positions: ~[uint],
603 fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
605 1u => w.write(&[0x80u8 | (n as u8)]),
606 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
607 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
609 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
610 (n >> 8_u) as u8, n as u8]),
611 _ => fail!("vint to write too big: {}", n)
615 fn write_vuint(w: &mut MemWriter, n: uint) {
616 if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
617 if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
618 if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
619 if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
620 fail!("vint to write too big: {}", n);
623 pub fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> {
624 let size_positions: ~[uint] = ~[];
627 size_positions: size_positions
631 // FIXME (#2741): Provide a function to write the standard ebml header.
632 impl<'a> Encoder<'a> {
633 /// XXX(pcwalton): Workaround for badness in trans. DO NOT USE ME.
634 pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
636 writer: cast::transmute_copy(&self.writer),
637 size_positions: self.size_positions.clone(),
641 pub fn start_tag(&mut self, tag_id: uint) {
642 debug!("Start tag {}", tag_id);
644 // Write the enum ID:
645 write_vuint(self.writer, tag_id);
647 // Write a placeholder four-byte size.
648 self.size_positions.push(self.writer.tell() as uint);
649 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
650 self.writer.write(zeroes);
653 pub fn end_tag(&mut self) {
654 let last_size_pos = self.size_positions.pop();
655 let cur_pos = self.writer.tell();
656 self.writer.seek(last_size_pos as i64, io::SeekSet);
657 let size = (cur_pos as uint - last_size_pos - 4);
658 write_sized_vuint(self.writer, size, 4u);
659 self.writer.seek(cur_pos as i64, io::SeekSet);
661 debug!("End tag (size = {})", size);
664 pub fn wr_tag(&mut self, tag_id: uint, blk: ||) {
665 self.start_tag(tag_id);
670 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
671 write_vuint(self.writer, tag_id);
672 write_vuint(self.writer, b.len());
673 self.writer.write(b);
676 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
677 u64_to_be_bytes(v, 8u, |v| {
678 self.wr_tagged_bytes(tag_id, v);
682 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) {
683 u64_to_be_bytes(v as u64, 4u, |v| {
684 self.wr_tagged_bytes(tag_id, v);
688 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) {
689 u64_to_be_bytes(v as u64, 2u, |v| {
690 self.wr_tagged_bytes(tag_id, v);
694 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) {
695 self.wr_tagged_bytes(tag_id, &[v]);
698 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) {
699 u64_to_be_bytes(v as u64, 8u, |v| {
700 self.wr_tagged_bytes(tag_id, v);
704 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) {
705 u64_to_be_bytes(v as u64, 4u, |v| {
706 self.wr_tagged_bytes(tag_id, v);
710 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) {
711 u64_to_be_bytes(v as u64, 2u, |v| {
712 self.wr_tagged_bytes(tag_id, v);
716 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) {
717 self.wr_tagged_bytes(tag_id, &[v as u8]);
720 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) {
721 self.wr_tagged_bytes(tag_id, v.as_bytes());
724 pub fn wr_bytes(&mut self, b: &[u8]) {
725 debug!("Write {} bytes", b.len());
726 self.writer.write(b);
729 pub fn wr_str(&mut self, s: &str) {
730 debug!("Write str: {}", s);
731 self.writer.write(s.as_bytes());
735 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
736 // efficiently encode sizes; this is a fixed point iteration
738 // Set to true to generate more debugging in EBML code.
739 // Totally lame approach.
740 static DEBUG: bool = true;
742 impl<'a> Encoder<'a> {
743 // used internally to emit things like the vector length and so on
744 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) {
745 assert!(v <= 0xFFFF_FFFF_u);
746 self.wr_tagged_u32(t as uint, v as u32);
749 fn _emit_label(&mut self, label: &str) {
750 // There are various strings that we have access to, such as
751 // the name of a record field, which do not actually appear in
752 // the encoded EBML (normally). This is just for
753 // efficiency. When debugging, though, we can emit such
754 // labels and then they will be checked by decoder to
755 // try and check failures more quickly.
756 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
759 pub fn emit_opaque(&mut self, f: |&mut Encoder|) {
760 self.start_tag(EsOpaque as uint);
766 impl<'a> ::serialize::Encoder for Encoder<'a> {
767 fn emit_nil(&mut self) {}
769 fn emit_uint(&mut self, v: uint) {
770 self.wr_tagged_u64(EsUint as uint, v as u64);
772 fn emit_u64(&mut self, v: u64) {
773 self.wr_tagged_u64(EsU64 as uint, v);
775 fn emit_u32(&mut self, v: u32) {
776 self.wr_tagged_u32(EsU32 as uint, v);
778 fn emit_u16(&mut self, v: u16) {
779 self.wr_tagged_u16(EsU16 as uint, v);
781 fn emit_u8(&mut self, v: u8) {
782 self.wr_tagged_u8(EsU8 as uint, v);
785 fn emit_int(&mut self, v: int) {
786 self.wr_tagged_i64(EsInt as uint, v as i64);
788 fn emit_i64(&mut self, v: i64) {
789 self.wr_tagged_i64(EsI64 as uint, v);
791 fn emit_i32(&mut self, v: i32) {
792 self.wr_tagged_i32(EsI32 as uint, v);
794 fn emit_i16(&mut self, v: i16) {
795 self.wr_tagged_i16(EsI16 as uint, v);
797 fn emit_i8(&mut self, v: i8) {
798 self.wr_tagged_i8(EsI8 as uint, v);
801 fn emit_bool(&mut self, v: bool) {
802 self.wr_tagged_u8(EsBool as uint, v as u8)
805 fn emit_f64(&mut self, v: f64) {
806 let bits = unsafe { cast::transmute(v) };
807 self.wr_tagged_u64(EsF64 as uint, bits);
809 fn emit_f32(&mut self, v: f32) {
810 let bits = unsafe { cast::transmute(v) };
811 self.wr_tagged_u32(EsF32 as uint, bits);
813 fn emit_char(&mut self, v: char) {
814 self.wr_tagged_u32(EsChar as uint, v as u32);
817 fn emit_str(&mut self, v: &str) {
818 self.wr_tagged_str(EsStr as uint, v)
821 fn emit_enum(&mut self, name: &str, f: |&mut Encoder<'a>|) {
822 self._emit_label(name);
823 self.start_tag(EsEnum as uint);
828 fn emit_enum_variant(&mut self,
832 f: |&mut Encoder<'a>|) {
833 self._emit_tagged_uint(EsEnumVid, v_id);
834 self.start_tag(EsEnumBody as uint);
839 fn emit_enum_variant_arg(&mut self, _: uint, f: |&mut Encoder<'a>|) {
843 fn emit_enum_struct_variant(&mut self,
847 f: |&mut Encoder<'a>|) {
848 self.emit_enum_variant(v_name, v_id, cnt, f)
851 fn emit_enum_struct_variant_field(&mut self,
854 f: |&mut Encoder<'a>|) {
855 self.emit_enum_variant_arg(idx, f)
858 fn emit_struct(&mut self,
861 f: |&mut Encoder<'a>|) {
865 fn emit_struct_field(&mut self,
868 f: |&mut Encoder<'a>|) {
869 self._emit_label(name);
873 fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) {
874 self.emit_seq(len, f)
876 fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
877 self.emit_seq_elt(idx, f)
880 fn emit_tuple_struct(&mut self,
883 f: |&mut Encoder<'a>|) {
884 self.emit_seq(len, f)
886 fn emit_tuple_struct_arg(&mut self,
888 f: |&mut Encoder<'a>|) {
889 self.emit_seq_elt(idx, f)
892 fn emit_option(&mut self, f: |&mut Encoder<'a>|) {
893 self.emit_enum("Option", f);
895 fn emit_option_none(&mut self) {
896 self.emit_enum_variant("None", 0, 0, |_| ())
898 fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) {
899 self.emit_enum_variant("Some", 1, 1, f)
902 fn emit_seq(&mut self, len: uint, f: |&mut Encoder<'a>|) {
903 self.start_tag(EsVec as uint);
904 self._emit_tagged_uint(EsVecLen, len);
909 fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
910 self.start_tag(EsVecElt as uint);
915 fn emit_map(&mut self, len: uint, f: |&mut Encoder<'a>|) {
916 self.start_tag(EsMap as uint);
917 self._emit_tagged_uint(EsMapLen, len);
922 fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
923 self.start_tag(EsMapKey as uint);
928 fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
929 self.start_tag(EsMapVal as uint);
936 // ___________________________________________________________________________
943 use serialize::Encodable;
946 use std::io::mem::MemWriter;
947 use std::option::{None, Option, Some};
958 0x10, 0x00, 0x00, 0x00,
959 0x1f, 0xff, 0xff, 0xff
962 let mut res: reader::Res;
965 res = reader::vuint_at(data, 0);
966 assert_eq!(res.val, 0);
967 assert_eq!(res.next, 1);
968 res = reader::vuint_at(data, res.next);
969 assert_eq!(res.val, (1 << 7) - 1);
970 assert_eq!(res.next, 2);
973 res = reader::vuint_at(data, res.next);
974 assert_eq!(res.val, 0);
975 assert_eq!(res.next, 4);
976 res = reader::vuint_at(data, res.next);
977 assert_eq!(res.val, (1 << 14) - 1);
978 assert_eq!(res.next, 6);
981 res = reader::vuint_at(data, res.next);
982 assert_eq!(res.val, 0);
983 assert_eq!(res.next, 9);
984 res = reader::vuint_at(data, res.next);
985 assert_eq!(res.val, (1 << 21) - 1);
986 assert_eq!(res.next, 12);
989 res = reader::vuint_at(data, res.next);
990 assert_eq!(res.val, 0);
991 assert_eq!(res.next, 16);
992 res = reader::vuint_at(data, res.next);
993 assert_eq!(res.val, (1 << 28) - 1);
994 assert_eq!(res.next, 20);
998 fn test_option_int() {
999 fn test_v(v: Option<int>) {
1000 debug!("v == {:?}", v);
1001 let mut wr = MemWriter::new();
1003 let mut ebml_w = writer::Encoder(&mut wr);
1004 v.encode(&mut ebml_w);
1006 let ebml_doc = reader::Doc(wr.get_ref());
1007 let mut deser = reader::Decoder(ebml_doc);
1008 let v1 = serialize::Decodable::decode(&mut deser);
1009 debug!("v1 == {:?}", v1);
1022 use test::BenchHarness;
1025 pub fn vuint_at_A_aligned(bh: &mut BenchHarness) {
1027 let data = vec::from_fn(4*100, |i| {
1036 while (i < data.len()) {
1037 sum += reader::vuint_at(data, i).val;
1044 pub fn vuint_at_A_unaligned(bh: &mut BenchHarness) {
1046 let data = vec::from_fn(4*100+1, |i| {
1055 while (i < data.len()) {
1056 sum += reader::vuint_at(data, i).val;
1063 pub fn vuint_at_D_aligned(bh: &mut BenchHarness) {
1065 let data = vec::from_fn(4*100, |i| {
1075 while (i < data.len()) {
1076 sum += reader::vuint_at(data, i).val;
1083 pub fn vuint_at_D_unaligned(bh: &mut BenchHarness) {
1085 let data = vec::from_fn(4*100+1, |i| {
1095 while (i < data.len()) {
1096 sum += reader::vuint_at(data, i).val;