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 //! 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.
15 //! It is loosely based on the Extensible Binary Markup Language (ebml):
16 //! http://www.matroska.org/technical/specs/rfc/index.html
18 #![crate_name = "rbml"]
21 #![crate_type = "rlib"]
22 #![crate_type = "dylib"]
23 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
24 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
25 html_root_url = "http://doc.rust-lang.org/nightly/",
26 html_playground_url = "http://play.rust-lang.org/")]
27 #![allow(unknown_features)]
28 #![feature(slicing_syntax)]
29 #![allow(unknown_features)] #![feature(int_uint)]
32 extern crate serialize;
33 #[macro_use] extern crate log;
35 #[cfg(test)] extern crate test;
37 pub use self::EbmlEncoderTag::*;
38 pub use self::Error::*;
45 /// Common data structures
46 #[derive(Clone, Copy)]
53 impl<'doc> Doc<'doc> {
54 pub fn new(data: &'doc [u8]) -> Doc<'doc> {
55 Doc { data: data, start: 0u, end: data.len() }
58 pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
59 reader::get_doc(*self, tag)
62 pub fn as_str_slice<'a>(&'a self) -> &'a str {
63 str::from_utf8(&self.data[self.start..self.end]).unwrap()
66 pub fn as_str(&self) -> String {
67 self.as_str_slice().to_string()
71 pub struct TaggedDoc<'a> {
77 pub enum EbmlEncoderTag {
107 EsLabel, // Used only when debugging
114 IoError(std::io::IoError),
115 ApplicationError(String)
118 impl fmt::Display for Error {
119 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120 // FIXME: this should be a more useful display form
121 fmt::Debug::fmt(self, f)
124 // --------------------------------------
130 use std::io::extensions::u64_from_be_bytes;
131 use std::mem::transmute;
133 use std::option::Option;
134 use std::option::Option::{None, Some};
138 use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
139 EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
140 EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
141 EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
142 Error, IntTooBig, Expected };
144 pub type DecodeResult<T> = Result<T, Error>;
147 macro_rules! try_or {
148 ($e:expr, $r:expr) => (
152 debug!("ignored error: {:?}", e);
166 fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
168 if a & 0x80u8 != 0u8 {
169 return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
171 if a & 0x40u8 != 0u8 {
172 return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
173 (data[start + 1u] as uint),
176 if a & 0x20u8 != 0u8 {
177 return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
178 (data[start + 1u] as uint) << 8u |
179 (data[start + 2u] as uint),
182 if a & 0x10u8 != 0u8 {
183 return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
184 (data[start + 1u] as uint) << 16u |
185 (data[start + 2u] as uint) << 8u |
186 (data[start + 3u] as uint),
189 Err(IntTooBig(a as uint))
192 pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
193 if data.len() - start < 4 {
194 return vuint_at_slow(data, start);
197 // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
198 // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
199 // Using the four most significant bits of the u32 we lookup in the table below how the
200 // element ID should be derived from it.
202 // The table stores tuples (shift, mask) where shift is the number the u32 should be right
203 // shifted with and mask is the value the right shifted value should be masked with.
204 // If for example the most significant bit is set this means it's a class A ID and the u32
205 // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
206 // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
208 // By storing the number of shifts and masks in a table instead of checking in order if
209 // the most significant bit is set, the second most significant bit is set etc. we can
210 // replace up to three "and+branch" with a single table lookup which gives us a measured
211 // speedup of around 2x on x86_64.
212 static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
213 (0, 0x0), (0, 0x0fffffff),
214 (8, 0x1fffff), (8, 0x1fffff),
215 (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
216 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
217 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
221 let ptr = data.as_ptr().offset(start as int) as *const u32;
222 let val = Int::from_be(*ptr);
224 let i = (val >> 28u) as uint;
225 let (shift, mask) = SHIFT_MASK_TABLE[i];
227 val: ((val >> shift) & mask) as uint,
228 next: start + (((32 - shift) >> 3) as uint)
233 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
234 let elt_tag = try!(vuint_at(data, start));
235 let elt_size = try!(vuint_at(data, elt_tag.next));
236 let end = elt_size.next + elt_size.val;
239 doc: Doc { data: data, start: elt_size.next, end: end }
243 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
244 let mut pos = d.start;
246 let elt_tag = try_or!(vuint_at(d.data, pos), None);
247 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
248 pos = elt_size.next + elt_size.val;
249 if elt_tag.val == tg {
250 return Some(Doc { data: d.data, start: elt_size.next,
257 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
258 match maybe_get_doc(d, tg) {
261 error!("failed to find block with tag {:?}", tg);
267 pub fn docs<F>(d: Doc, mut it: F) -> bool where
268 F: FnMut(uint, Doc) -> bool,
270 let mut pos = d.start;
272 let elt_tag = try_or!(vuint_at(d.data, pos), false);
273 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
274 pos = elt_size.next + elt_size.val;
275 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
276 if !it(elt_tag.val, doc) {
283 pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
284 F: FnMut(Doc) -> bool,
286 let mut pos = d.start;
288 let elt_tag = try_or!(vuint_at(d.data, pos), false);
289 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
290 pos = elt_size.next + elt_size.val;
291 if elt_tag.val == tg {
292 let doc = Doc { data: d.data, start: elt_size.next,
302 pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
303 F: FnOnce(&[u8]) -> T,
305 f(&d.data[d.start..d.end])
309 pub fn doc_as_u8(d: Doc) -> u8 {
310 assert_eq!(d.end, d.start + 1u);
314 pub fn doc_as_u16(d: Doc) -> u16 {
315 assert_eq!(d.end, d.start + 2u);
316 u64_from_be_bytes(d.data, d.start, 2u) as u16
319 pub fn doc_as_u32(d: Doc) -> u32 {
320 assert_eq!(d.end, d.start + 4u);
321 u64_from_be_bytes(d.data, d.start, 4u) as u32
324 pub fn doc_as_u64(d: Doc) -> u64 {
325 assert_eq!(d.end, d.start + 8u);
326 u64_from_be_bytes(d.data, d.start, 8u)
329 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
330 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
331 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
332 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
334 pub struct Decoder<'a> {
339 impl<'doc> Decoder<'doc> {
340 pub fn new(d: Doc<'doc>) -> Decoder<'doc> {
347 fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
348 if self.pos < self.parent.end {
349 let TaggedDoc { tag: r_tag, doc: r_doc } =
350 try!(doc_at(self.parent.data, self.pos));
352 if r_tag == (EsLabel as uint) {
353 self.pos = r_doc.end;
354 let str = r_doc.as_str_slice();
356 return Err(Expected(format!("Expected label {:?} but \
357 found {:?}", lbl, str)));
364 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
365 debug!(". next_doc(exp_tag={:?})", exp_tag);
366 if self.pos >= self.parent.end {
367 return Err(Expected(format!("no more documents in \
370 let TaggedDoc { tag: r_tag, doc: r_doc } =
371 try!(doc_at(self.parent.data, self.pos));
372 debug!("self.parent={:?}-{:?} self.pos={:?} r_tag={:?} r_doc={:?}-{:?}",
379 if r_tag != (exp_tag as uint) {
380 return Err(Expected(format!("expected EBML doc with tag {:?} but \
381 found tag {:?}", exp_tag, r_tag)));
383 if r_doc.end > self.parent.end {
384 return Err(Expected(format!("invalid EBML, child extends to \
385 {:#x}, parent to {:#x}",
386 r_doc.end, self.parent.end)));
388 self.pos = r_doc.end;
392 fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
393 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
395 let d = try!(self.next_doc(exp_tag));
396 let old_parent = self.parent;
397 let old_pos = self.pos;
400 let r = try!(f(self));
401 self.parent = old_parent;
406 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
407 let r = doc_as_u32(try!(self.next_doc(exp_tag)));
408 debug!("_next_uint exp_tag={:?} result={:?}", exp_tag, r);
412 pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
413 F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
415 let doc = try!(self.next_doc(EsOpaque));
417 let (old_parent, old_pos) = (self.parent, self.pos);
419 self.pos = doc.start;
421 let result = try!(op(self, doc));
423 self.parent = old_parent;
429 impl<'doc> serialize::Decoder for Decoder<'doc> {
431 fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
433 fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
434 fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
435 fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
436 fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
437 fn read_uint(&mut self) -> DecodeResult<uint> {
438 let v = doc_as_u64(try!(self.next_doc(EsUint)));
439 if v > (::std::uint::MAX as u64) {
440 Err(IntTooBig(v as uint))
446 fn read_i64(&mut self) -> DecodeResult<i64> {
447 Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
449 fn read_i32(&mut self) -> DecodeResult<i32> {
450 Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
452 fn read_i16(&mut self) -> DecodeResult<i16> {
453 Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
455 fn read_i8 (&mut self) -> DecodeResult<i8> {
456 Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
458 fn read_int(&mut self) -> DecodeResult<int> {
459 let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
460 if v > (int::MAX as i64) || v < (int::MIN as i64) {
461 debug!("FIXME \\#6122: Removing this makes this function miscompile");
462 Err(IntTooBig(v as uint))
468 fn read_bool(&mut self) -> DecodeResult<bool> {
469 Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
472 fn read_f64(&mut self) -> DecodeResult<f64> {
473 let bits = doc_as_u64(try!(self.next_doc(EsF64)));
474 Ok(unsafe { transmute(bits) })
476 fn read_f32(&mut self) -> DecodeResult<f32> {
477 let bits = doc_as_u32(try!(self.next_doc(EsF32)));
478 Ok(unsafe { transmute(bits) })
480 fn read_char(&mut self) -> DecodeResult<char> {
481 Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
483 fn read_str(&mut self) -> DecodeResult<String> {
484 Ok(try!(self.next_doc(EsStr)).as_str())
488 fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
489 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
491 debug!("read_enum({})", name);
492 try!(self._check_label(name));
494 let doc = try!(self.next_doc(EsEnum));
496 let (old_parent, old_pos) = (self.parent, self.pos);
498 self.pos = self.parent.start;
500 let result = try!(f(self));
502 self.parent = old_parent;
507 fn read_enum_variant<T, F>(&mut self, _: &[&str],
508 mut f: F) -> DecodeResult<T>
509 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
511 debug!("read_enum_variant()");
512 let idx = try!(self._next_uint(EsEnumVid));
513 debug!(" idx={}", idx);
515 let doc = try!(self.next_doc(EsEnumBody));
517 let (old_parent, old_pos) = (self.parent, self.pos);
519 self.pos = self.parent.start;
521 let result = try!(f(self, idx));
523 self.parent = old_parent;
528 fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
529 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
531 debug!("read_enum_variant_arg(idx={})", idx);
535 fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
536 mut f: F) -> DecodeResult<T>
537 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
539 debug!("read_enum_struct_variant()");
540 let idx = try!(self._next_uint(EsEnumVid));
541 debug!(" idx={}", idx);
543 let doc = try!(self.next_doc(EsEnumBody));
545 let (old_parent, old_pos) = (self.parent, self.pos);
547 self.pos = self.parent.start;
549 let result = try!(f(self, idx));
551 self.parent = old_parent;
556 fn read_enum_struct_variant_field<T, F>(&mut self,
560 -> DecodeResult<T> where
561 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
563 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
567 fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
568 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
570 debug!("read_struct(name={})", name);
574 fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
575 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
577 debug!("read_struct_field(name={}, idx={})", name, idx);
578 try!(self._check_label(name));
582 fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
583 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
585 debug!("read_tuple()");
586 self.read_seq(move |d, len| {
587 if len == tuple_len {
590 Err(Expected(format!("Expected tuple of length `{}`, \
591 found tuple of length `{}`", tuple_len, len)))
596 fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
597 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
599 debug!("read_tuple_arg(idx={})", idx);
600 self.read_seq_elt(idx, f)
603 fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
604 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
606 debug!("read_tuple_struct(name={})", name);
607 self.read_tuple(len, f)
610 fn read_tuple_struct_arg<T, F>(&mut self,
613 -> DecodeResult<T> where
614 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
616 debug!("read_tuple_struct_arg(idx={})", idx);
617 self.read_tuple_arg(idx, f)
620 fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
621 F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
623 debug!("read_option()");
624 self.read_enum("Option", move |this| {
625 this.read_enum_variant(&["None", "Some"], move |this, idx| {
630 Err(Expected(format!("Expected None or Some")))
637 fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
638 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
640 debug!("read_seq()");
641 self.push_doc(EsVec, move |d| {
642 let len = try!(d._next_uint(EsVecLen));
643 debug!(" len={}", len);
648 fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
649 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
651 debug!("read_seq_elt(idx={})", idx);
652 self.push_doc(EsVecElt, f)
655 fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
656 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
658 debug!("read_map()");
659 self.push_doc(EsMap, move |d| {
660 let len = try!(d._next_uint(EsMapLen));
661 debug!(" len={}", len);
666 fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
667 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
669 debug!("read_map_elt_key(idx={})", idx);
670 self.push_doc(EsMapKey, f)
673 fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
674 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
676 debug!("read_map_elt_val(idx={})", idx);
677 self.push_doc(EsMapVal, f)
680 fn error(&mut self, err: &str) -> Error {
681 ApplicationError(err.to_string())
687 use std::clone::Clone;
688 use std::io::extensions::u64_to_be_bytes;
689 use std::io::{Writer, Seek};
693 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
694 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
695 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
696 EsOpaque, EsLabel, EbmlEncoderTag };
701 pub type EncodeResult = io::IoResult<()>;
704 pub struct Encoder<'a, W:'a> {
705 pub writer: &'a mut W,
706 size_positions: Vec<uint>,
709 fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
711 1u => w.write(&[0x80u8 | (n as u8)]),
712 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
713 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
715 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
716 (n >> 8_u) as u8, n as u8]),
717 _ => Err(io::IoError {
718 kind: io::OtherIoError,
720 detail: Some(format!("{}", n))
725 fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
726 if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
727 if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
728 if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
729 if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
731 kind: io::OtherIoError,
733 detail: Some(format!("{}", n))
737 // FIXME (#2741): Provide a function to write the standard rbml header.
738 impl<'a, W: Writer + Seek> Encoder<'a, W> {
739 pub fn new(w: &'a mut W) -> Encoder<'a, W> {
742 size_positions: vec!(),
746 /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
747 pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
749 writer: mem::transmute_copy(&self.writer),
750 size_positions: self.size_positions.clone(),
754 pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
755 debug!("Start tag {:?}", tag_id);
757 // Write the enum ID:
758 try!(write_vuint(self.writer, tag_id));
760 // Write a placeholder four-byte size.
761 self.size_positions.push(try!(self.writer.tell()) as uint);
762 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
763 self.writer.write(zeroes)
766 pub fn end_tag(&mut self) -> EncodeResult {
767 let last_size_pos = self.size_positions.pop().unwrap();
768 let cur_pos = try!(self.writer.tell());
769 try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
770 let size = cur_pos as uint - last_size_pos - 4;
771 try!(write_sized_vuint(self.writer, size, 4u));
772 let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
774 debug!("End tag (size = {:?})", size);
778 pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
779 F: FnOnce() -> EncodeResult,
781 try!(self.start_tag(tag_id));
786 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
787 try!(write_vuint(self.writer, tag_id));
788 try!(write_vuint(self.writer, b.len()));
792 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
793 u64_to_be_bytes(v, 8u, |v| {
794 self.wr_tagged_bytes(tag_id, v)
798 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
799 u64_to_be_bytes(v as u64, 4u, |v| {
800 self.wr_tagged_bytes(tag_id, v)
804 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
805 u64_to_be_bytes(v as u64, 2u, |v| {
806 self.wr_tagged_bytes(tag_id, v)
810 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
811 self.wr_tagged_bytes(tag_id, &[v])
814 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
815 u64_to_be_bytes(v as u64, 8u, |v| {
816 self.wr_tagged_bytes(tag_id, v)
820 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
821 u64_to_be_bytes(v as u64, 4u, |v| {
822 self.wr_tagged_bytes(tag_id, v)
826 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
827 u64_to_be_bytes(v as u64, 2u, |v| {
828 self.wr_tagged_bytes(tag_id, v)
832 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
833 self.wr_tagged_bytes(tag_id, &[v as u8])
836 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
837 self.wr_tagged_bytes(tag_id, v.as_bytes())
840 pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
841 debug!("Write {:?} bytes", b.len());
845 pub fn wr_str(&mut self, s: &str) -> EncodeResult {
846 debug!("Write str: {:?}", s);
847 self.writer.write(s.as_bytes())
851 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
852 // efficiently encode sizes; this is a fixed point iteration
854 // Set to true to generate more debugging in EBML code.
855 // Totally lame approach.
856 static DEBUG: bool = true;
858 impl<'a, W: Writer + Seek> Encoder<'a, W> {
859 // used internally to emit things like the vector length and so on
860 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
861 assert!(v <= 0xFFFF_FFFF_u);
862 self.wr_tagged_u32(t as uint, v as u32)
865 fn _emit_label(&mut self, label: &str) -> EncodeResult {
866 // There are various strings that we have access to, such as
867 // the name of a record field, which do not actually appear in
868 // the encoded EBML (normally). This is just for
869 // efficiency. When debugging, though, we can emit such
870 // labels and then they will be checked by decoder to
871 // try and check panics more quickly.
872 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
876 pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
877 F: FnOnce(&mut Encoder<W>) -> EncodeResult,
879 try!(self.start_tag(EsOpaque as uint));
885 impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> {
886 type Error = io::IoError;
888 fn emit_nil(&mut self) -> EncodeResult {
892 fn emit_uint(&mut self, v: uint) -> EncodeResult {
893 self.wr_tagged_u64(EsUint as uint, v as u64)
895 fn emit_u64(&mut self, v: u64) -> EncodeResult {
896 self.wr_tagged_u64(EsU64 as uint, v)
898 fn emit_u32(&mut self, v: u32) -> EncodeResult {
899 self.wr_tagged_u32(EsU32 as uint, v)
901 fn emit_u16(&mut self, v: u16) -> EncodeResult {
902 self.wr_tagged_u16(EsU16 as uint, v)
904 fn emit_u8(&mut self, v: u8) -> EncodeResult {
905 self.wr_tagged_u8(EsU8 as uint, v)
908 fn emit_int(&mut self, v: int) -> EncodeResult {
909 self.wr_tagged_i64(EsInt as uint, v as i64)
911 fn emit_i64(&mut self, v: i64) -> EncodeResult {
912 self.wr_tagged_i64(EsI64 as uint, v)
914 fn emit_i32(&mut self, v: i32) -> EncodeResult {
915 self.wr_tagged_i32(EsI32 as uint, v)
917 fn emit_i16(&mut self, v: i16) -> EncodeResult {
918 self.wr_tagged_i16(EsI16 as uint, v)
920 fn emit_i8(&mut self, v: i8) -> EncodeResult {
921 self.wr_tagged_i8(EsI8 as uint, v)
924 fn emit_bool(&mut self, v: bool) -> EncodeResult {
925 self.wr_tagged_u8(EsBool as uint, v as u8)
928 fn emit_f64(&mut self, v: f64) -> EncodeResult {
929 let bits = unsafe { mem::transmute(v) };
930 self.wr_tagged_u64(EsF64 as uint, bits)
932 fn emit_f32(&mut self, v: f32) -> EncodeResult {
933 let bits = unsafe { mem::transmute(v) };
934 self.wr_tagged_u32(EsF32 as uint, bits)
936 fn emit_char(&mut self, v: char) -> EncodeResult {
937 self.wr_tagged_u32(EsChar as uint, v as u32)
940 fn emit_str(&mut self, v: &str) -> EncodeResult {
941 self.wr_tagged_str(EsStr as uint, v)
944 fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
945 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
947 try!(self._emit_label(name));
948 try!(self.start_tag(EsEnum as uint));
953 fn emit_enum_variant<F>(&mut self,
957 f: F) -> EncodeResult where
958 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
960 try!(self._emit_tagged_uint(EsEnumVid, v_id));
961 try!(self.start_tag(EsEnumBody as uint));
966 fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
967 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
972 fn emit_enum_struct_variant<F>(&mut self,
976 f: F) -> EncodeResult where
977 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
979 self.emit_enum_variant(v_name, v_id, cnt, f)
982 fn emit_enum_struct_variant_field<F>(&mut self,
985 f: F) -> EncodeResult where
986 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
988 self.emit_enum_variant_arg(idx, f)
991 fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
992 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
997 fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
998 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1000 try!(self._emit_label(name));
1004 fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
1005 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1007 self.emit_seq(len, f)
1009 fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1010 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1012 self.emit_seq_elt(idx, f)
1015 fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
1016 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1018 self.emit_seq(len, f)
1020 fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1021 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1023 self.emit_seq_elt(idx, f)
1026 fn emit_option<F>(&mut self, f: F) -> EncodeResult where
1027 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1029 self.emit_enum("Option", f)
1031 fn emit_option_none(&mut self) -> EncodeResult {
1032 self.emit_enum_variant("None", 0, 0, |_| Ok(()))
1034 fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
1035 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1038 self.emit_enum_variant("Some", 1, 1, f)
1041 fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
1042 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1045 try!(self.start_tag(EsVec as uint));
1046 try!(self._emit_tagged_uint(EsVecLen, len));
1051 fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1052 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1055 try!(self.start_tag(EsVecElt as uint));
1060 fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
1061 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1064 try!(self.start_tag(EsMap as uint));
1065 try!(self._emit_tagged_uint(EsMapLen, len));
1070 fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1071 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1074 try!(self.start_tag(EsMapKey as uint));
1079 fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1080 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1082 try!(self.start_tag(EsMapVal as uint));
1089 // ___________________________________________________________________________
1094 use super::{Doc, reader, writer};
1095 use super::io::SeekableMemWriter;
1097 use serialize::{Encodable, Decodable};
1099 use std::option::Option;
1100 use std::option::Option::{None, Some};
1103 fn test_vuint_at() {
1111 0x10, 0x00, 0x00, 0x00,
1112 0x1f, 0xff, 0xff, 0xff
1115 let mut res: reader::Res;
1118 res = reader::vuint_at(data, 0).unwrap();
1119 assert_eq!(res.val, 0);
1120 assert_eq!(res.next, 1);
1121 res = reader::vuint_at(data, res.next).unwrap();
1122 assert_eq!(res.val, (1 << 7) - 1);
1123 assert_eq!(res.next, 2);
1126 res = reader::vuint_at(data, res.next).unwrap();
1127 assert_eq!(res.val, 0);
1128 assert_eq!(res.next, 4);
1129 res = reader::vuint_at(data, res.next).unwrap();
1130 assert_eq!(res.val, (1 << 14) - 1);
1131 assert_eq!(res.next, 6);
1134 res = reader::vuint_at(data, res.next).unwrap();
1135 assert_eq!(res.val, 0);
1136 assert_eq!(res.next, 9);
1137 res = reader::vuint_at(data, res.next).unwrap();
1138 assert_eq!(res.val, (1 << 21) - 1);
1139 assert_eq!(res.next, 12);
1142 res = reader::vuint_at(data, res.next).unwrap();
1143 assert_eq!(res.val, 0);
1144 assert_eq!(res.next, 16);
1145 res = reader::vuint_at(data, res.next).unwrap();
1146 assert_eq!(res.val, (1 << 28) - 1);
1147 assert_eq!(res.next, 20);
1151 fn test_option_int() {
1152 fn test_v(v: Option<int>) {
1153 debug!("v == {:?}", v);
1154 let mut wr = SeekableMemWriter::new();
1156 let mut rbml_w = writer::Encoder::new(&mut wr);
1157 let _ = v.encode(&mut rbml_w);
1159 let rbml_doc = Doc::new(wr.get_ref());
1160 let mut deser = reader::Decoder::new(rbml_doc);
1161 let v1 = Decodable::decode(&mut deser).unwrap();
1162 debug!("v1 == {:?}", v1);
1174 #![allow(non_snake_case)]
1179 pub fn vuint_at_A_aligned(b: &mut Bencher) {
1180 let data = range(0, 4*100).map(|i| {
1185 }).collect::<Vec<_>>();
1189 while i < data.len() {
1190 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1197 pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1198 let data = range(0, 4*100+1).map(|i| {
1203 }).collect::<Vec<_>>();
1207 while i < data.len() {
1208 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1215 pub fn vuint_at_D_aligned(b: &mut Bencher) {
1216 let data = range(0, 4*100).map(|i| {
1222 }).collect::<Vec<_>>();
1226 while i < data.len() {
1227 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1234 pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1235 let data = range(0, 4*100+1).map(|i| {
1241 }).collect::<Vec<_>>();
1245 while i < data.len() {
1246 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;