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::*;
44 /// Common data structures
45 #[derive(Clone, Copy)]
52 impl<'doc> Doc<'doc> {
53 pub fn new(data: &'doc [u8]) -> Doc<'doc> {
54 Doc { data: data, start: 0u, end: data.len() }
57 pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
58 reader::get_doc(*self, tag)
61 pub fn as_str_slice<'a>(&'a self) -> &'a str {
62 str::from_utf8(&self.data[self.start..self.end]).unwrap()
65 pub fn as_str(&self) -> String {
66 self.as_str_slice().to_string()
70 pub struct TaggedDoc<'a> {
76 pub enum EbmlEncoderTag {
106 EsLabel, // Used only when debugging
113 IoError(std::io::IoError),
114 ApplicationError(String)
116 // --------------------------------------
122 use std::io::extensions::u64_from_be_bytes;
123 use std::mem::transmute;
125 use std::option::Option;
126 use std::option::Option::{None, Some};
130 use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
131 EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
132 EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
133 EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
134 Error, IntTooBig, Expected };
136 pub type DecodeResult<T> = Result<T, Error>;
139 macro_rules! try_or {
140 ($e:expr, $r:expr) => (
144 debug!("ignored error: {:?}", e);
158 fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
160 if a & 0x80u8 != 0u8 {
161 return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
163 if a & 0x40u8 != 0u8 {
164 return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
165 (data[start + 1u] as uint),
168 if a & 0x20u8 != 0u8 {
169 return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
170 (data[start + 1u] as uint) << 8u |
171 (data[start + 2u] as uint),
174 if a & 0x10u8 != 0u8 {
175 return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
176 (data[start + 1u] as uint) << 16u |
177 (data[start + 2u] as uint) << 8u |
178 (data[start + 3u] as uint),
181 Err(IntTooBig(a as uint))
184 pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
185 if data.len() - start < 4 {
186 return vuint_at_slow(data, start);
189 // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
190 // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
191 // Using the four most significant bits of the u32 we lookup in the table below how the
192 // element ID should be derived from it.
194 // The table stores tuples (shift, mask) where shift is the number the u32 should be right
195 // shifted with and mask is the value the right shifted value should be masked with.
196 // If for example the most significant bit is set this means it's a class A ID and the u32
197 // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
198 // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
200 // By storing the number of shifts and masks in a table instead of checking in order if
201 // the most significant bit is set, the second most significant bit is set etc. we can
202 // replace up to three "and+branch" with a single table lookup which gives us a measured
203 // speedup of around 2x on x86_64.
204 static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
205 (0, 0x0), (0, 0x0fffffff),
206 (8, 0x1fffff), (8, 0x1fffff),
207 (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
208 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
209 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
213 let ptr = data.as_ptr().offset(start as int) as *const u32;
214 let val = Int::from_be(*ptr);
216 let i = (val >> 28u) as uint;
217 let (shift, mask) = SHIFT_MASK_TABLE[i];
219 val: ((val >> shift) & mask) as uint,
220 next: start + (((32 - shift) >> 3) as uint)
225 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
226 let elt_tag = try!(vuint_at(data, start));
227 let elt_size = try!(vuint_at(data, elt_tag.next));
228 let end = elt_size.next + elt_size.val;
231 doc: Doc { data: data, start: elt_size.next, end: end }
235 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
236 let mut pos = d.start;
238 let elt_tag = try_or!(vuint_at(d.data, pos), None);
239 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
240 pos = elt_size.next + elt_size.val;
241 if elt_tag.val == tg {
242 return Some(Doc { data: d.data, start: elt_size.next,
249 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
250 match maybe_get_doc(d, tg) {
253 error!("failed to find block with tag {:?}", tg);
259 pub fn docs<F>(d: Doc, mut it: F) -> bool where
260 F: FnMut(uint, Doc) -> bool,
262 let mut pos = d.start;
264 let elt_tag = try_or!(vuint_at(d.data, pos), false);
265 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
266 pos = elt_size.next + elt_size.val;
267 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
268 if !it(elt_tag.val, doc) {
275 pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
276 F: FnMut(Doc) -> bool,
278 let mut pos = d.start;
280 let elt_tag = try_or!(vuint_at(d.data, pos), false);
281 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
282 pos = elt_size.next + elt_size.val;
283 if elt_tag.val == tg {
284 let doc = Doc { data: d.data, start: elt_size.next,
294 pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
295 F: FnOnce(&[u8]) -> T,
297 f(&d.data[d.start..d.end])
301 pub fn doc_as_u8(d: Doc) -> u8 {
302 assert_eq!(d.end, d.start + 1u);
306 pub fn doc_as_u16(d: Doc) -> u16 {
307 assert_eq!(d.end, d.start + 2u);
308 u64_from_be_bytes(d.data, d.start, 2u) as u16
311 pub fn doc_as_u32(d: Doc) -> u32 {
312 assert_eq!(d.end, d.start + 4u);
313 u64_from_be_bytes(d.data, d.start, 4u) as u32
316 pub fn doc_as_u64(d: Doc) -> u64 {
317 assert_eq!(d.end, d.start + 8u);
318 u64_from_be_bytes(d.data, d.start, 8u)
321 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
322 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
323 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
324 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
326 pub struct Decoder<'a> {
331 impl<'doc> Decoder<'doc> {
332 pub fn new(d: Doc<'doc>) -> Decoder<'doc> {
339 fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
340 if self.pos < self.parent.end {
341 let TaggedDoc { tag: r_tag, doc: r_doc } =
342 try!(doc_at(self.parent.data, self.pos));
344 if r_tag == (EsLabel as uint) {
345 self.pos = r_doc.end;
346 let str = r_doc.as_str_slice();
348 return Err(Expected(format!("Expected label {:?} but \
349 found {:?}", lbl, str)));
356 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
357 debug!(". next_doc(exp_tag={:?})", exp_tag);
358 if self.pos >= self.parent.end {
359 return Err(Expected(format!("no more documents in \
362 let TaggedDoc { tag: r_tag, doc: r_doc } =
363 try!(doc_at(self.parent.data, self.pos));
364 debug!("self.parent={:?}-{:?} self.pos={:?} r_tag={:?} r_doc={:?}-{:?}",
371 if r_tag != (exp_tag as uint) {
372 return Err(Expected(format!("expected EBML doc with tag {:?} but \
373 found tag {:?}", exp_tag, r_tag)));
375 if r_doc.end > self.parent.end {
376 return Err(Expected(format!("invalid EBML, child extends to \
377 {:#x}, parent to {:#x}",
378 r_doc.end, self.parent.end)));
380 self.pos = r_doc.end;
384 fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
385 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
387 let d = try!(self.next_doc(exp_tag));
388 let old_parent = self.parent;
389 let old_pos = self.pos;
392 let r = try!(f(self));
393 self.parent = old_parent;
398 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
399 let r = doc_as_u32(try!(self.next_doc(exp_tag)));
400 debug!("_next_uint exp_tag={:?} result={:?}", exp_tag, r);
404 pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
405 F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
407 let doc = try!(self.next_doc(EsOpaque));
409 let (old_parent, old_pos) = (self.parent, self.pos);
411 self.pos = doc.start;
413 let result = try!(op(self, doc));
415 self.parent = old_parent;
421 impl<'doc> serialize::Decoder for Decoder<'doc> {
423 fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
425 fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
426 fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
427 fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
428 fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
429 fn read_uint(&mut self) -> DecodeResult<uint> {
430 let v = doc_as_u64(try!(self.next_doc(EsUint)));
431 if v > (::std::uint::MAX as u64) {
432 Err(IntTooBig(v as uint))
438 fn read_i64(&mut self) -> DecodeResult<i64> {
439 Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
441 fn read_i32(&mut self) -> DecodeResult<i32> {
442 Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
444 fn read_i16(&mut self) -> DecodeResult<i16> {
445 Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
447 fn read_i8 (&mut self) -> DecodeResult<i8> {
448 Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
450 fn read_int(&mut self) -> DecodeResult<int> {
451 let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
452 if v > (int::MAX as i64) || v < (int::MIN as i64) {
453 debug!("FIXME \\#6122: Removing this makes this function miscompile");
454 Err(IntTooBig(v as uint))
460 fn read_bool(&mut self) -> DecodeResult<bool> {
461 Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
464 fn read_f64(&mut self) -> DecodeResult<f64> {
465 let bits = doc_as_u64(try!(self.next_doc(EsF64)));
466 Ok(unsafe { transmute(bits) })
468 fn read_f32(&mut self) -> DecodeResult<f32> {
469 let bits = doc_as_u32(try!(self.next_doc(EsF32)));
470 Ok(unsafe { transmute(bits) })
472 fn read_char(&mut self) -> DecodeResult<char> {
473 Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
475 fn read_str(&mut self) -> DecodeResult<String> {
476 Ok(try!(self.next_doc(EsStr)).as_str())
480 fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
481 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
483 debug!("read_enum({})", name);
484 try!(self._check_label(name));
486 let doc = try!(self.next_doc(EsEnum));
488 let (old_parent, old_pos) = (self.parent, self.pos);
490 self.pos = self.parent.start;
492 let result = try!(f(self));
494 self.parent = old_parent;
499 fn read_enum_variant<T, F>(&mut self, _: &[&str],
500 mut f: F) -> DecodeResult<T>
501 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
503 debug!("read_enum_variant()");
504 let idx = try!(self._next_uint(EsEnumVid));
505 debug!(" idx={}", idx);
507 let doc = try!(self.next_doc(EsEnumBody));
509 let (old_parent, old_pos) = (self.parent, self.pos);
511 self.pos = self.parent.start;
513 let result = try!(f(self, idx));
515 self.parent = old_parent;
520 fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
521 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
523 debug!("read_enum_variant_arg(idx={})", idx);
527 fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
528 mut f: F) -> DecodeResult<T>
529 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
531 debug!("read_enum_struct_variant()");
532 let idx = try!(self._next_uint(EsEnumVid));
533 debug!(" idx={}", idx);
535 let doc = try!(self.next_doc(EsEnumBody));
537 let (old_parent, old_pos) = (self.parent, self.pos);
539 self.pos = self.parent.start;
541 let result = try!(f(self, idx));
543 self.parent = old_parent;
548 fn read_enum_struct_variant_field<T, F>(&mut self,
552 -> DecodeResult<T> where
553 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
555 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
559 fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
560 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
562 debug!("read_struct(name={})", name);
566 fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
567 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
569 debug!("read_struct_field(name={}, idx={})", name, idx);
570 try!(self._check_label(name));
574 fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
575 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
577 debug!("read_tuple()");
578 self.read_seq(move |d, len| {
579 if len == tuple_len {
582 Err(Expected(format!("Expected tuple of length `{}`, \
583 found tuple of length `{}`", tuple_len, len)))
588 fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
589 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
591 debug!("read_tuple_arg(idx={})", idx);
592 self.read_seq_elt(idx, f)
595 fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
596 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
598 debug!("read_tuple_struct(name={})", name);
599 self.read_tuple(len, f)
602 fn read_tuple_struct_arg<T, F>(&mut self,
605 -> DecodeResult<T> where
606 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
608 debug!("read_tuple_struct_arg(idx={})", idx);
609 self.read_tuple_arg(idx, f)
612 fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
613 F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
615 debug!("read_option()");
616 self.read_enum("Option", move |this| {
617 this.read_enum_variant(&["None", "Some"], move |this, idx| {
622 Err(Expected(format!("Expected None or Some")))
629 fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
630 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
632 debug!("read_seq()");
633 self.push_doc(EsVec, move |d| {
634 let len = try!(d._next_uint(EsVecLen));
635 debug!(" len={}", len);
640 fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
641 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
643 debug!("read_seq_elt(idx={})", idx);
644 self.push_doc(EsVecElt, f)
647 fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
648 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
650 debug!("read_map()");
651 self.push_doc(EsMap, move |d| {
652 let len = try!(d._next_uint(EsMapLen));
653 debug!(" len={}", len);
658 fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
659 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
661 debug!("read_map_elt_key(idx={})", idx);
662 self.push_doc(EsMapKey, f)
665 fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
666 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
668 debug!("read_map_elt_val(idx={})", idx);
669 self.push_doc(EsMapVal, f)
672 fn error(&mut self, err: &str) -> Error {
673 ApplicationError(err.to_string())
679 use std::clone::Clone;
680 use std::io::extensions::u64_to_be_bytes;
681 use std::io::{Writer, Seek};
685 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
686 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
687 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
688 EsOpaque, EsLabel, EbmlEncoderTag };
693 pub type EncodeResult = io::IoResult<()>;
696 pub struct Encoder<'a, W:'a> {
697 pub writer: &'a mut W,
698 size_positions: Vec<uint>,
701 fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
703 1u => w.write(&[0x80u8 | (n as u8)]),
704 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
705 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
707 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
708 (n >> 8_u) as u8, n as u8]),
709 _ => Err(io::IoError {
710 kind: io::OtherIoError,
712 detail: Some(format!("{}", n))
717 fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
718 if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
719 if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
720 if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
721 if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
723 kind: io::OtherIoError,
725 detail: Some(format!("{}", n))
729 // FIXME (#2741): Provide a function to write the standard rbml header.
730 impl<'a, W: Writer + Seek> Encoder<'a, W> {
731 pub fn new(w: &'a mut W) -> Encoder<'a, W> {
734 size_positions: vec!(),
738 /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
739 pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
741 writer: mem::transmute_copy(&self.writer),
742 size_positions: self.size_positions.clone(),
746 pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
747 debug!("Start tag {:?}", tag_id);
749 // Write the enum ID:
750 try!(write_vuint(self.writer, tag_id));
752 // Write a placeholder four-byte size.
753 self.size_positions.push(try!(self.writer.tell()) as uint);
754 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
755 self.writer.write(zeroes)
758 pub fn end_tag(&mut self) -> EncodeResult {
759 let last_size_pos = self.size_positions.pop().unwrap();
760 let cur_pos = try!(self.writer.tell());
761 try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
762 let size = cur_pos as uint - last_size_pos - 4;
763 try!(write_sized_vuint(self.writer, size, 4u));
764 let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
766 debug!("End tag (size = {:?})", size);
770 pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
771 F: FnOnce() -> EncodeResult,
773 try!(self.start_tag(tag_id));
778 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
779 try!(write_vuint(self.writer, tag_id));
780 try!(write_vuint(self.writer, b.len()));
784 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
785 u64_to_be_bytes(v, 8u, |v| {
786 self.wr_tagged_bytes(tag_id, v)
790 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
791 u64_to_be_bytes(v as u64, 4u, |v| {
792 self.wr_tagged_bytes(tag_id, v)
796 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
797 u64_to_be_bytes(v as u64, 2u, |v| {
798 self.wr_tagged_bytes(tag_id, v)
802 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
803 self.wr_tagged_bytes(tag_id, &[v])
806 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
807 u64_to_be_bytes(v as u64, 8u, |v| {
808 self.wr_tagged_bytes(tag_id, v)
812 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
813 u64_to_be_bytes(v as u64, 4u, |v| {
814 self.wr_tagged_bytes(tag_id, v)
818 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
819 u64_to_be_bytes(v as u64, 2u, |v| {
820 self.wr_tagged_bytes(tag_id, v)
824 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
825 self.wr_tagged_bytes(tag_id, &[v as u8])
828 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
829 self.wr_tagged_bytes(tag_id, v.as_bytes())
832 pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
833 debug!("Write {:?} bytes", b.len());
837 pub fn wr_str(&mut self, s: &str) -> EncodeResult {
838 debug!("Write str: {:?}", s);
839 self.writer.write(s.as_bytes())
843 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
844 // efficiently encode sizes; this is a fixed point iteration
846 // Set to true to generate more debugging in EBML code.
847 // Totally lame approach.
848 static DEBUG: bool = true;
850 impl<'a, W: Writer + Seek> Encoder<'a, W> {
851 // used internally to emit things like the vector length and so on
852 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
853 assert!(v <= 0xFFFF_FFFF_u);
854 self.wr_tagged_u32(t as uint, v as u32)
857 fn _emit_label(&mut self, label: &str) -> EncodeResult {
858 // There are various strings that we have access to, such as
859 // the name of a record field, which do not actually appear in
860 // the encoded EBML (normally). This is just for
861 // efficiency. When debugging, though, we can emit such
862 // labels and then they will be checked by decoder to
863 // try and check panics more quickly.
864 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
868 pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
869 F: FnOnce(&mut Encoder<W>) -> EncodeResult,
871 try!(self.start_tag(EsOpaque as uint));
877 impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> {
878 type Error = io::IoError;
880 fn emit_nil(&mut self) -> EncodeResult {
884 fn emit_uint(&mut self, v: uint) -> EncodeResult {
885 self.wr_tagged_u64(EsUint as uint, v as u64)
887 fn emit_u64(&mut self, v: u64) -> EncodeResult {
888 self.wr_tagged_u64(EsU64 as uint, v)
890 fn emit_u32(&mut self, v: u32) -> EncodeResult {
891 self.wr_tagged_u32(EsU32 as uint, v)
893 fn emit_u16(&mut self, v: u16) -> EncodeResult {
894 self.wr_tagged_u16(EsU16 as uint, v)
896 fn emit_u8(&mut self, v: u8) -> EncodeResult {
897 self.wr_tagged_u8(EsU8 as uint, v)
900 fn emit_int(&mut self, v: int) -> EncodeResult {
901 self.wr_tagged_i64(EsInt as uint, v as i64)
903 fn emit_i64(&mut self, v: i64) -> EncodeResult {
904 self.wr_tagged_i64(EsI64 as uint, v)
906 fn emit_i32(&mut self, v: i32) -> EncodeResult {
907 self.wr_tagged_i32(EsI32 as uint, v)
909 fn emit_i16(&mut self, v: i16) -> EncodeResult {
910 self.wr_tagged_i16(EsI16 as uint, v)
912 fn emit_i8(&mut self, v: i8) -> EncodeResult {
913 self.wr_tagged_i8(EsI8 as uint, v)
916 fn emit_bool(&mut self, v: bool) -> EncodeResult {
917 self.wr_tagged_u8(EsBool as uint, v as u8)
920 fn emit_f64(&mut self, v: f64) -> EncodeResult {
921 let bits = unsafe { mem::transmute(v) };
922 self.wr_tagged_u64(EsF64 as uint, bits)
924 fn emit_f32(&mut self, v: f32) -> EncodeResult {
925 let bits = unsafe { mem::transmute(v) };
926 self.wr_tagged_u32(EsF32 as uint, bits)
928 fn emit_char(&mut self, v: char) -> EncodeResult {
929 self.wr_tagged_u32(EsChar as uint, v as u32)
932 fn emit_str(&mut self, v: &str) -> EncodeResult {
933 self.wr_tagged_str(EsStr as uint, v)
936 fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
937 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
939 try!(self._emit_label(name));
940 try!(self.start_tag(EsEnum as uint));
945 fn emit_enum_variant<F>(&mut self,
949 f: F) -> EncodeResult where
950 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
952 try!(self._emit_tagged_uint(EsEnumVid, v_id));
953 try!(self.start_tag(EsEnumBody as uint));
958 fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
959 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
964 fn emit_enum_struct_variant<F>(&mut self,
968 f: F) -> EncodeResult where
969 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
971 self.emit_enum_variant(v_name, v_id, cnt, f)
974 fn emit_enum_struct_variant_field<F>(&mut self,
977 f: F) -> EncodeResult where
978 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
980 self.emit_enum_variant_arg(idx, f)
983 fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
984 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
989 fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
990 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
992 try!(self._emit_label(name));
996 fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
997 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
999 self.emit_seq(len, f)
1001 fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1002 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1004 self.emit_seq_elt(idx, f)
1007 fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
1008 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1010 self.emit_seq(len, f)
1012 fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1013 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1015 self.emit_seq_elt(idx, f)
1018 fn emit_option<F>(&mut self, f: F) -> EncodeResult where
1019 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1021 self.emit_enum("Option", f)
1023 fn emit_option_none(&mut self) -> EncodeResult {
1024 self.emit_enum_variant("None", 0, 0, |_| Ok(()))
1026 fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
1027 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1030 self.emit_enum_variant("Some", 1, 1, f)
1033 fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
1034 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1037 try!(self.start_tag(EsVec as uint));
1038 try!(self._emit_tagged_uint(EsVecLen, len));
1043 fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1044 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1047 try!(self.start_tag(EsVecElt as uint));
1052 fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
1053 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1056 try!(self.start_tag(EsMap as uint));
1057 try!(self._emit_tagged_uint(EsMapLen, len));
1062 fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1063 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1066 try!(self.start_tag(EsMapKey as uint));
1071 fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1072 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1074 try!(self.start_tag(EsMapVal as uint));
1081 // ___________________________________________________________________________
1086 use super::{Doc, reader, writer};
1087 use super::io::SeekableMemWriter;
1089 use serialize::{Encodable, Decodable};
1091 use std::option::Option;
1092 use std::option::Option::{None, Some};
1095 fn test_vuint_at() {
1103 0x10, 0x00, 0x00, 0x00,
1104 0x1f, 0xff, 0xff, 0xff
1107 let mut res: reader::Res;
1110 res = reader::vuint_at(data, 0).unwrap();
1111 assert_eq!(res.val, 0);
1112 assert_eq!(res.next, 1);
1113 res = reader::vuint_at(data, res.next).unwrap();
1114 assert_eq!(res.val, (1 << 7) - 1);
1115 assert_eq!(res.next, 2);
1118 res = reader::vuint_at(data, res.next).unwrap();
1119 assert_eq!(res.val, 0);
1120 assert_eq!(res.next, 4);
1121 res = reader::vuint_at(data, res.next).unwrap();
1122 assert_eq!(res.val, (1 << 14) - 1);
1123 assert_eq!(res.next, 6);
1126 res = reader::vuint_at(data, res.next).unwrap();
1127 assert_eq!(res.val, 0);
1128 assert_eq!(res.next, 9);
1129 res = reader::vuint_at(data, res.next).unwrap();
1130 assert_eq!(res.val, (1 << 21) - 1);
1131 assert_eq!(res.next, 12);
1134 res = reader::vuint_at(data, res.next).unwrap();
1135 assert_eq!(res.val, 0);
1136 assert_eq!(res.next, 16);
1137 res = reader::vuint_at(data, res.next).unwrap();
1138 assert_eq!(res.val, (1 << 28) - 1);
1139 assert_eq!(res.next, 20);
1143 fn test_option_int() {
1144 fn test_v(v: Option<int>) {
1145 debug!("v == {:?}", v);
1146 let mut wr = SeekableMemWriter::new();
1148 let mut rbml_w = writer::Encoder::new(&mut wr);
1149 let _ = v.encode(&mut rbml_w);
1151 let rbml_doc = Doc::new(wr.get_ref());
1152 let mut deser = reader::Decoder::new(rbml_doc);
1153 let v1 = Decodable::decode(&mut deser).unwrap();
1154 debug!("v1 == {:?}", v1);
1166 #![allow(non_snake_case)]
1171 pub fn vuint_at_A_aligned(b: &mut Bencher) {
1172 let data = range(0, 4*100).map(|i| {
1177 }).collect::<Vec<_>>();
1181 while i < data.len() {
1182 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1189 pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1190 let data = range(0, 4*100+1).map(|i| {
1195 }).collect::<Vec<_>>();
1199 while i < data.len() {
1200 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1207 pub fn vuint_at_D_aligned(b: &mut Bencher) {
1208 let data = range(0, 4*100).map(|i| {
1214 }).collect::<Vec<_>>();
1218 while i < data.len() {
1219 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1226 pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1227 let data = range(0, 4*100+1).map(|i| {
1233 }).collect::<Vec<_>>();
1237 while i < data.len() {
1238 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;