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.
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)]
16 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
17 // cursor model. See the specification here:
18 // http://www.matroska.org/technical/specs/rfc/index.html
20 // Common data structures
28 impl<'doc> Doc<'doc> {
29 pub fn new(data: &'doc [u8]) -> Doc<'doc> {
30 Doc { data: data, start: 0u, end: data.len() }
33 pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
34 reader::get_doc(*self, tag)
37 pub fn as_str_slice<'a>(&'a self) -> &'a str {
38 str::from_utf8(self.data.slice(self.start, self.end)).unwrap()
41 pub fn as_str(&self) -> String {
42 self.as_str_slice().to_string()
46 pub struct TaggedDoc<'a> {
52 pub enum EbmlEncoderTag {
82 EsLabel, // Used only when debugging
91 // --------------------------------------
96 use std::mem::transmute;
98 use std::option::{None, Option, Some};
99 use std::io::extensions::u64_from_be_bytes;
103 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
104 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
105 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
106 EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc, Error, IntTooBig,
109 pub type DecodeResult<T> = Result<T, Error>;
113 ($e:expr, $r:expr) => (
117 debug!("ignored error: {}", e);
130 fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
132 if a & 0x80u8 != 0u8 {
133 return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
135 if a & 0x40u8 != 0u8 {
136 return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
137 (data[start + 1u] as uint),
140 if a & 0x20u8 != 0u8 {
141 return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
142 (data[start + 1u] as uint) << 8u |
143 (data[start + 2u] as uint),
146 if a & 0x10u8 != 0u8 {
147 return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
148 (data[start + 1u] as uint) << 16u |
149 (data[start + 2u] as uint) << 8u |
150 (data[start + 3u] as uint),
153 Err(IntTooBig(a as uint))
156 pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
157 if data.len() - start < 4 {
158 return vuint_at_slow(data, start);
161 // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
162 // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
163 // Using the four most significant bits of the u32 we lookup in the table below how the
164 // element ID should be derived from it.
166 // The table stores tuples (shift, mask) where shift is the number the u32 should be right
167 // shifted with and mask is the value the right shifted value should be masked with.
168 // If for example the most significant bit is set this means it's a class A ID and the u32
169 // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
170 // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
172 // By storing the number of shifts and masks in a table instead of checking in order if
173 // the most significant bit is set, the second most significant bit is set etc. we can
174 // replace up to three "and+branch" with a single table lookup which gives us a measured
175 // speedup of around 2x on x86_64.
176 static SHIFT_MASK_TABLE: [(uint, u32), ..16] = [
177 (0, 0x0), (0, 0x0fffffff),
178 (8, 0x1fffff), (8, 0x1fffff),
179 (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
180 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
181 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
185 let ptr = data.as_ptr().offset(start as int) as *const u32;
186 let val = Int::from_be(*ptr);
188 let i = (val >> 28u) as uint;
189 let (shift, mask) = SHIFT_MASK_TABLE[i];
191 val: ((val >> shift) & mask) as uint,
192 next: start + (((32 - shift) >> 3) as uint)
197 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
198 let elt_tag = try!(vuint_at(data, start));
199 let elt_size = try!(vuint_at(data, elt_tag.next));
200 let end = elt_size.next + elt_size.val;
203 doc: Doc { data: data, start: elt_size.next, end: end }
207 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
208 let mut pos = d.start;
210 let elt_tag = try_or!(vuint_at(d.data, pos), None);
211 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
212 pos = elt_size.next + elt_size.val;
213 if elt_tag.val == tg {
214 return Some(Doc { data: d.data, start: elt_size.next,
221 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
222 match maybe_get_doc(d, tg) {
225 error!("failed to find block with tag {}", tg);
231 pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
232 let mut pos = d.start;
234 let elt_tag = try_or!(vuint_at(d.data, pos), false);
235 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
236 pos = elt_size.next + elt_size.val;
237 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
238 if !it(elt_tag.val, doc) {
245 pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
246 let mut pos = d.start;
248 let elt_tag = try_or!(vuint_at(d.data, pos), false);
249 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
250 pos = elt_size.next + elt_size.val;
251 if elt_tag.val == tg {
252 let doc = Doc { data: d.data, start: elt_size.next,
262 pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T {
263 f(d.data.slice(d.start, d.end))
267 pub fn doc_as_u8(d: Doc) -> u8 {
268 assert_eq!(d.end, d.start + 1u);
272 pub fn doc_as_u16(d: Doc) -> u16 {
273 assert_eq!(d.end, d.start + 2u);
274 u64_from_be_bytes(d.data, d.start, 2u) as u16
277 pub fn doc_as_u32(d: Doc) -> u32 {
278 assert_eq!(d.end, d.start + 4u);
279 u64_from_be_bytes(d.data, d.start, 4u) as u32
282 pub fn doc_as_u64(d: Doc) -> u64 {
283 assert_eq!(d.end, d.start + 8u);
284 u64_from_be_bytes(d.data, d.start, 8u)
287 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
288 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
289 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
290 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
292 pub struct Decoder<'a> {
297 impl<'doc> Decoder<'doc> {
298 pub fn new(d: Doc<'doc>) -> Decoder<'doc> {
305 fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
306 if self.pos < self.parent.end {
307 let TaggedDoc { tag: r_tag, doc: r_doc } =
308 try!(doc_at(self.parent.data, self.pos));
310 if r_tag == (EsLabel as uint) {
311 self.pos = r_doc.end;
312 let str = r_doc.as_str_slice();
314 return Err(Expected(format!("Expected label {} but \
315 found {}", lbl, str)));
322 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
323 debug!(". next_doc(exp_tag={})", exp_tag);
324 if self.pos >= self.parent.end {
325 return Err(Expected(format!("no more documents in \
328 let TaggedDoc { tag: r_tag, doc: r_doc } =
329 try!(doc_at(self.parent.data, self.pos));
330 debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
337 if r_tag != (exp_tag as uint) {
338 return Err(Expected(format!("expected EBML doc with tag {} but \
339 found tag {}", exp_tag, r_tag)));
341 if r_doc.end > self.parent.end {
342 return Err(Expected(format!("invalid EBML, child extends to \
343 {:#x}, parent to {:#x}",
344 r_doc.end, self.parent.end)));
346 self.pos = r_doc.end;
350 fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
351 f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
352 let d = try!(self.next_doc(exp_tag));
353 let old_parent = self.parent;
354 let old_pos = self.pos;
357 let r = try!(f(self));
358 self.parent = old_parent;
363 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
364 let r = doc_as_u32(try!(self.next_doc(exp_tag)));
365 debug!("_next_uint exp_tag={} result={}", exp_tag, r);
369 pub fn read_opaque<R>(&mut self,
370 op: |&mut Decoder<'doc>, Doc| -> DecodeResult<R>) -> DecodeResult<R> {
371 let doc = try!(self.next_doc(EsOpaque));
373 let (old_parent, old_pos) = (self.parent, self.pos);
375 self.pos = doc.start;
377 let result = try!(op(self, doc));
379 self.parent = old_parent;
385 impl<'doc> serialize::Decoder<Error> for Decoder<'doc> {
386 fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
388 fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
389 fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
390 fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
391 fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
392 fn read_uint(&mut self) -> DecodeResult<uint> {
393 let v = doc_as_u64(try!(self.next_doc(EsUint)));
394 if v > (::std::uint::MAX as u64) {
395 Err(IntTooBig(v as uint))
401 fn read_i64(&mut self) -> DecodeResult<i64> {
402 Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
404 fn read_i32(&mut self) -> DecodeResult<i32> {
405 Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
407 fn read_i16(&mut self) -> DecodeResult<i16> {
408 Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
410 fn read_i8 (&mut self) -> DecodeResult<i8> {
411 Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
413 fn read_int(&mut self) -> DecodeResult<int> {
414 let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
415 if v > (int::MAX as i64) || v < (int::MIN as i64) {
416 debug!("FIXME \\#6122: Removing this makes this function miscompile");
417 Err(IntTooBig(v as uint))
423 fn read_bool(&mut self) -> DecodeResult<bool> {
424 Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
427 fn read_f64(&mut self) -> DecodeResult<f64> {
428 let bits = doc_as_u64(try!(self.next_doc(EsF64)));
429 Ok(unsafe { transmute(bits) })
431 fn read_f32(&mut self) -> DecodeResult<f32> {
432 let bits = doc_as_u32(try!(self.next_doc(EsF32)));
433 Ok(unsafe { transmute(bits) })
435 fn read_char(&mut self) -> DecodeResult<char> {
436 Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
438 fn read_str(&mut self) -> DecodeResult<String> {
439 Ok(try!(self.next_doc(EsStr)).as_str())
443 fn read_enum<T>(&mut self,
445 f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
446 debug!("read_enum({})", name);
447 try!(self._check_label(name));
449 let doc = try!(self.next_doc(EsEnum));
451 let (old_parent, old_pos) = (self.parent, self.pos);
453 self.pos = self.parent.start;
455 let result = try!(f(self));
457 self.parent = old_parent;
462 fn read_enum_variant<T>(&mut self,
464 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
466 debug!("read_enum_variant()");
467 let idx = try!(self._next_uint(EsEnumVid));
468 debug!(" idx={}", idx);
470 let doc = try!(self.next_doc(EsEnumBody));
472 let (old_parent, old_pos) = (self.parent, self.pos);
474 self.pos = self.parent.start;
476 let result = try!(f(self, idx));
478 self.parent = old_parent;
483 fn read_enum_variant_arg<T>(&mut self,
485 f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
486 debug!("read_enum_variant_arg(idx={})", idx);
490 fn read_enum_struct_variant<T>(&mut self,
492 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
494 debug!("read_enum_struct_variant()");
495 let idx = try!(self._next_uint(EsEnumVid));
496 debug!(" idx={}", idx);
498 let doc = try!(self.next_doc(EsEnumBody));
500 let (old_parent, old_pos) = (self.parent, self.pos);
502 self.pos = self.parent.start;
504 let result = try!(f(self, idx));
506 self.parent = old_parent;
511 fn read_enum_struct_variant_field<T>(&mut self,
514 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
516 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
520 fn read_struct<T>(&mut self,
523 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
525 debug!("read_struct(name={})", name);
529 fn read_struct_field<T>(&mut self,
532 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
534 debug!("read_struct_field(name={}, idx={})", name, idx);
535 try!(self._check_label(name));
539 fn read_tuple<T>(&mut self,
540 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
541 debug!("read_tuple()");
545 fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
547 debug!("read_tuple_arg(idx={})", idx);
548 self.read_seq_elt(idx, f)
551 fn read_tuple_struct<T>(&mut self,
553 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
555 debug!("read_tuple_struct(name={})", name);
559 fn read_tuple_struct_arg<T>(&mut self,
561 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
563 debug!("read_tuple_struct_arg(idx={})", idx);
564 self.read_tuple_arg(idx, f)
567 fn read_option<T>(&mut self,
568 f: |&mut Decoder<'doc>, bool| -> DecodeResult<T>) -> DecodeResult<T> {
569 debug!("read_option()");
570 self.read_enum("Option", |this| {
571 this.read_enum_variant(["None", "Some"], |this, idx| {
576 Err(Expected(format!("Expected None or Some")))
583 fn read_seq<T>(&mut self,
584 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
585 debug!("read_seq()");
586 self.push_doc(EsVec, |d| {
587 let len = try!(d._next_uint(EsVecLen));
588 debug!(" len={}", len);
593 fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
595 debug!("read_seq_elt(idx={})", idx);
596 self.push_doc(EsVecElt, f)
599 fn read_map<T>(&mut self,
600 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
601 debug!("read_map()");
602 self.push_doc(EsMap, |d| {
603 let len = try!(d._next_uint(EsMapLen));
604 debug!(" len={}", len);
609 fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
611 debug!("read_map_elt_key(idx={})", idx);
612 self.push_doc(EsMapKey, f)
615 fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
617 debug!("read_map_elt_val(idx={})", idx);
618 self.push_doc(EsMapVal, f)
624 use std::clone::Clone;
625 use std::io::extensions::u64_to_be_bytes;
626 use std::io::{Writer, Seek};
630 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
631 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
632 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
633 EsOpaque, EsLabel, EbmlEncoderTag };
638 pub type EncodeResult = io::IoResult<()>;
641 pub struct Encoder<'a, W> {
642 pub writer: &'a mut W,
643 size_positions: Vec<uint>,
646 fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
648 1u => w.write(&[0x80u8 | (n as u8)]),
649 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
650 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
652 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
653 (n >> 8_u) as u8, n as u8]),
654 _ => Err(io::IoError {
655 kind: io::OtherIoError,
657 detail: Some(format!("{}", n))
662 fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
663 if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
664 if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
665 if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
666 if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
668 kind: io::OtherIoError,
670 detail: Some(format!("{}", n))
674 // FIXME (#2741): Provide a function to write the standard ebml header.
675 impl<'a, W: Writer + Seek> Encoder<'a, W> {
676 pub fn new(w: &'a mut W) -> Encoder<'a, W> {
679 size_positions: vec!(),
683 /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
684 pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
686 writer: mem::transmute_copy(&self.writer),
687 size_positions: self.size_positions.clone(),
691 pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
692 debug!("Start tag {}", tag_id);
694 // Write the enum ID:
695 try!(write_vuint(self.writer, tag_id));
697 // Write a placeholder four-byte size.
698 self.size_positions.push(try!(self.writer.tell()) as uint);
699 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
700 self.writer.write(zeroes)
703 pub fn end_tag(&mut self) -> EncodeResult {
704 let last_size_pos = self.size_positions.pop().unwrap();
705 let cur_pos = try!(self.writer.tell());
706 try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
707 let size = cur_pos as uint - last_size_pos - 4;
708 try!(write_sized_vuint(self.writer, size, 4u));
709 let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
711 debug!("End tag (size = {})", size);
715 pub fn wr_tag(&mut self, tag_id: uint, blk: || -> EncodeResult) -> EncodeResult {
716 try!(self.start_tag(tag_id));
721 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
722 try!(write_vuint(self.writer, tag_id));
723 try!(write_vuint(self.writer, b.len()));
727 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
728 u64_to_be_bytes(v, 8u, |v| {
729 self.wr_tagged_bytes(tag_id, v)
733 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
734 u64_to_be_bytes(v as u64, 4u, |v| {
735 self.wr_tagged_bytes(tag_id, v)
739 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
740 u64_to_be_bytes(v as u64, 2u, |v| {
741 self.wr_tagged_bytes(tag_id, v)
745 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
746 self.wr_tagged_bytes(tag_id, &[v])
749 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
750 u64_to_be_bytes(v as u64, 8u, |v| {
751 self.wr_tagged_bytes(tag_id, v)
755 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
756 u64_to_be_bytes(v as u64, 4u, |v| {
757 self.wr_tagged_bytes(tag_id, v)
761 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
762 u64_to_be_bytes(v as u64, 2u, |v| {
763 self.wr_tagged_bytes(tag_id, v)
767 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
768 self.wr_tagged_bytes(tag_id, &[v as u8])
771 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
772 self.wr_tagged_bytes(tag_id, v.as_bytes())
775 pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
776 debug!("Write {} bytes", b.len());
780 pub fn wr_str(&mut self, s: &str) -> EncodeResult {
781 debug!("Write str: {}", s);
782 self.writer.write(s.as_bytes())
786 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
787 // efficiently encode sizes; this is a fixed point iteration
789 // Set to true to generate more debugging in EBML code.
790 // Totally lame approach.
791 static DEBUG: bool = true;
793 impl<'a, W: Writer + Seek> Encoder<'a, W> {
794 // used internally to emit things like the vector length and so on
795 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
796 assert!(v <= 0xFFFF_FFFF_u);
797 self.wr_tagged_u32(t as uint, v as u32)
800 fn _emit_label(&mut self, label: &str) -> EncodeResult {
801 // There are various strings that we have access to, such as
802 // the name of a record field, which do not actually appear in
803 // the encoded EBML (normally). This is just for
804 // efficiency. When debugging, though, we can emit such
805 // labels and then they will be checked by decoder to
806 // try and check failures more quickly.
807 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
811 pub fn emit_opaque(&mut self, f: |&mut Encoder<W>| -> EncodeResult) -> EncodeResult {
812 try!(self.start_tag(EsOpaque as uint));
818 impl<'a, W: Writer + Seek> serialize::Encoder<io::IoError> for Encoder<'a, W> {
819 fn emit_nil(&mut self) -> EncodeResult {
823 fn emit_uint(&mut self, v: uint) -> EncodeResult {
824 self.wr_tagged_u64(EsUint as uint, v as u64)
826 fn emit_u64(&mut self, v: u64) -> EncodeResult {
827 self.wr_tagged_u64(EsU64 as uint, v)
829 fn emit_u32(&mut self, v: u32) -> EncodeResult {
830 self.wr_tagged_u32(EsU32 as uint, v)
832 fn emit_u16(&mut self, v: u16) -> EncodeResult {
833 self.wr_tagged_u16(EsU16 as uint, v)
835 fn emit_u8(&mut self, v: u8) -> EncodeResult {
836 self.wr_tagged_u8(EsU8 as uint, v)
839 fn emit_int(&mut self, v: int) -> EncodeResult {
840 self.wr_tagged_i64(EsInt as uint, v as i64)
842 fn emit_i64(&mut self, v: i64) -> EncodeResult {
843 self.wr_tagged_i64(EsI64 as uint, v)
845 fn emit_i32(&mut self, v: i32) -> EncodeResult {
846 self.wr_tagged_i32(EsI32 as uint, v)
848 fn emit_i16(&mut self, v: i16) -> EncodeResult {
849 self.wr_tagged_i16(EsI16 as uint, v)
851 fn emit_i8(&mut self, v: i8) -> EncodeResult {
852 self.wr_tagged_i8(EsI8 as uint, v)
855 fn emit_bool(&mut self, v: bool) -> EncodeResult {
856 self.wr_tagged_u8(EsBool as uint, v as u8)
859 fn emit_f64(&mut self, v: f64) -> EncodeResult {
860 let bits = unsafe { mem::transmute(v) };
861 self.wr_tagged_u64(EsF64 as uint, bits)
863 fn emit_f32(&mut self, v: f32) -> EncodeResult {
864 let bits = unsafe { mem::transmute(v) };
865 self.wr_tagged_u32(EsF32 as uint, bits)
867 fn emit_char(&mut self, v: char) -> EncodeResult {
868 self.wr_tagged_u32(EsChar as uint, v as u32)
871 fn emit_str(&mut self, v: &str) -> EncodeResult {
872 self.wr_tagged_str(EsStr as uint, v)
875 fn emit_enum(&mut self,
877 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
878 try!(self._emit_label(name));
879 try!(self.start_tag(EsEnum as uint));
884 fn emit_enum_variant(&mut self,
888 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
889 try!(self._emit_tagged_uint(EsEnumVid, v_id));
890 try!(self.start_tag(EsEnumBody as uint));
895 fn emit_enum_variant_arg(&mut self,
897 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
901 fn emit_enum_struct_variant(&mut self,
905 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
906 self.emit_enum_variant(v_name, v_id, cnt, f)
909 fn emit_enum_struct_variant_field(&mut self,
912 f: |&mut Encoder<'a, W>| -> EncodeResult)
914 self.emit_enum_variant_arg(idx, f)
917 fn emit_struct(&mut self,
920 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
924 fn emit_struct_field(&mut self,
927 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
928 try!(self._emit_label(name));
932 fn emit_tuple(&mut self,
934 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
935 self.emit_seq(len, f)
937 fn emit_tuple_arg(&mut self,
939 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
940 self.emit_seq_elt(idx, f)
943 fn emit_tuple_struct(&mut self,
946 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
947 self.emit_seq(len, f)
949 fn emit_tuple_struct_arg(&mut self,
951 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
952 self.emit_seq_elt(idx, f)
955 fn emit_option(&mut self,
956 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
957 self.emit_enum("Option", f)
959 fn emit_option_none(&mut self) -> EncodeResult {
960 self.emit_enum_variant("None", 0, 0, |_| Ok(()))
962 fn emit_option_some(&mut self,
963 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
965 self.emit_enum_variant("Some", 1, 1, f)
968 fn emit_seq(&mut self,
970 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
972 try!(self.start_tag(EsVec as uint));
973 try!(self._emit_tagged_uint(EsVecLen, len));
978 fn emit_seq_elt(&mut self,
980 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
982 try!(self.start_tag(EsVecElt as uint));
987 fn emit_map(&mut self,
989 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
991 try!(self.start_tag(EsMap as uint));
992 try!(self._emit_tagged_uint(EsMapLen, len));
997 fn emit_map_elt_key(&mut self,
999 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
1001 try!(self.start_tag(EsMapKey as uint));
1006 fn emit_map_elt_val(&mut self,
1008 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
1009 try!(self.start_tag(EsMapVal as uint));
1016 // ___________________________________________________________________________
1024 use {Encodable, Decodable};
1026 use std::io::MemWriter;
1027 use std::option::{None, Option, Some};
1030 fn test_vuint_at() {
1038 0x10, 0x00, 0x00, 0x00,
1039 0x1f, 0xff, 0xff, 0xff
1042 let mut res: reader::Res;
1045 res = reader::vuint_at(data, 0).unwrap();
1046 assert_eq!(res.val, 0);
1047 assert_eq!(res.next, 1);
1048 res = reader::vuint_at(data, res.next).unwrap();
1049 assert_eq!(res.val, (1 << 7) - 1);
1050 assert_eq!(res.next, 2);
1053 res = reader::vuint_at(data, res.next).unwrap();
1054 assert_eq!(res.val, 0);
1055 assert_eq!(res.next, 4);
1056 res = reader::vuint_at(data, res.next).unwrap();
1057 assert_eq!(res.val, (1 << 14) - 1);
1058 assert_eq!(res.next, 6);
1061 res = reader::vuint_at(data, res.next).unwrap();
1062 assert_eq!(res.val, 0);
1063 assert_eq!(res.next, 9);
1064 res = reader::vuint_at(data, res.next).unwrap();
1065 assert_eq!(res.val, (1 << 21) - 1);
1066 assert_eq!(res.next, 12);
1069 res = reader::vuint_at(data, res.next).unwrap();
1070 assert_eq!(res.val, 0);
1071 assert_eq!(res.next, 16);
1072 res = reader::vuint_at(data, res.next).unwrap();
1073 assert_eq!(res.val, (1 << 28) - 1);
1074 assert_eq!(res.next, 20);
1078 fn test_option_int() {
1079 fn test_v(v: Option<int>) {
1080 debug!("v == {}", v);
1081 let mut wr = MemWriter::new();
1083 let mut ebml_w = writer::Encoder::new(&mut wr);
1084 let _ = v.encode(&mut ebml_w);
1086 let ebml_doc = Doc::new(wr.get_ref());
1087 let mut deser = reader::Decoder::new(ebml_doc);
1088 let v1 = Decodable::decode(&mut deser).unwrap();
1089 debug!("v1 == {}", v1);
1101 #![allow(non_snake_case_functions)]
1103 use self::test::Bencher;
1107 pub fn vuint_at_A_aligned(b: &mut Bencher) {
1108 let data = Vec::from_fn(4*100, |i| {
1117 while i < data.len() {
1118 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1125 pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1126 let data = Vec::from_fn(4*100+1, |i| {
1135 while i < data.len() {
1136 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1143 pub fn vuint_at_D_aligned(b: &mut Bencher) {
1144 let data = Vec::from_fn(4*100, |i| {
1154 while i < data.len() {
1155 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1162 pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1163 let data = Vec::from_fn(4*100+1, |i| {
1173 while i < data.len() {
1174 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;