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"]
20 #![crate_type = "rlib"]
21 #![crate_type = "dylib"]
22 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
23 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
24 html_root_url = "http://doc.rust-lang.org/nightly/",
25 html_playground_url = "http://play.rust-lang.org/")]
26 #![allow(unknown_features)]
27 #![feature(macro_rules, phase, slicing_syntax, globs)]
28 #![feature(unboxed_closures)]
29 #![allow(missing_docs)]
31 extern crate serialize;
33 #[phase(plugin, link)] extern crate log;
34 #[cfg(test)] extern crate test;
36 pub use self::EbmlEncoderTag::*;
37 pub use self::Error::*;
43 /// Common data structures
44 #[deriving(Clone, Copy)]
51 impl<'doc> Doc<'doc> {
52 pub fn new(data: &'doc [u8]) -> Doc<'doc> {
53 Doc { data: data, start: 0u, end: data.len() }
56 pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
57 reader::get_doc(*self, tag)
60 pub fn as_str_slice<'a>(&'a self) -> &'a str {
61 str::from_utf8(self.data[self.start..self.end]).unwrap()
64 pub fn as_str(&self) -> String {
65 self.as_str_slice().to_string()
69 pub struct TaggedDoc<'a> {
74 #[deriving(Copy, Show)]
75 pub enum EbmlEncoderTag {
105 EsLabel, // Used only when debugging
112 IoError(std::io::IoError),
113 ApplicationError(String)
115 // --------------------------------------
121 use std::io::extensions::u64_from_be_bytes;
122 use std::mem::transmute;
124 use std::option::Option;
125 use std::option::Option::{None, Some};
129 use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
130 EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
131 EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
132 EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
133 Error, IntTooBig, Expected };
135 pub type DecodeResult<T> = Result<T, Error>;
138 macro_rules! try_or {
139 ($e:expr, $r:expr) => (
143 debug!("ignored error: {}", e);
157 fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
159 if a & 0x80u8 != 0u8 {
160 return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
162 if a & 0x40u8 != 0u8 {
163 return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
164 (data[start + 1u] as uint),
167 if a & 0x20u8 != 0u8 {
168 return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
169 (data[start + 1u] as uint) << 8u |
170 (data[start + 2u] as uint),
173 if a & 0x10u8 != 0u8 {
174 return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
175 (data[start + 1u] as uint) << 16u |
176 (data[start + 2u] as uint) << 8u |
177 (data[start + 3u] as uint),
180 Err(IntTooBig(a as uint))
183 pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
184 if data.len() - start < 4 {
185 return vuint_at_slow(data, start);
188 // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
189 // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
190 // Using the four most significant bits of the u32 we lookup in the table below how the
191 // element ID should be derived from it.
193 // The table stores tuples (shift, mask) where shift is the number the u32 should be right
194 // shifted with and mask is the value the right shifted value should be masked with.
195 // If for example the most significant bit is set this means it's a class A ID and the u32
196 // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
197 // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
199 // By storing the number of shifts and masks in a table instead of checking in order if
200 // the most significant bit is set, the second most significant bit is set etc. we can
201 // replace up to three "and+branch" with a single table lookup which gives us a measured
202 // speedup of around 2x on x86_64.
203 static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
204 (0, 0x0), (0, 0x0fffffff),
205 (8, 0x1fffff), (8, 0x1fffff),
206 (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
207 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
208 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
212 let ptr = data.as_ptr().offset(start as int) as *const u32;
213 let val = Int::from_be(*ptr);
215 let i = (val >> 28u) as uint;
216 let (shift, mask) = SHIFT_MASK_TABLE[i];
218 val: ((val >> shift) & mask) as uint,
219 next: start + (((32 - shift) >> 3) as uint)
224 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
225 let elt_tag = try!(vuint_at(data, start));
226 let elt_size = try!(vuint_at(data, elt_tag.next));
227 let end = elt_size.next + elt_size.val;
230 doc: Doc { data: data, start: elt_size.next, end: end }
234 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
235 let mut pos = d.start;
237 let elt_tag = try_or!(vuint_at(d.data, pos), None);
238 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
239 pos = elt_size.next + elt_size.val;
240 if elt_tag.val == tg {
241 return Some(Doc { data: d.data, start: elt_size.next,
248 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
249 match maybe_get_doc(d, tg) {
252 error!("failed to find block with tag {}", tg);
258 pub fn docs<F>(d: Doc, mut it: F) -> bool where
259 F: FnMut(uint, Doc) -> bool,
261 let mut pos = d.start;
263 let elt_tag = try_or!(vuint_at(d.data, pos), false);
264 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
265 pos = elt_size.next + elt_size.val;
266 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
267 if !it(elt_tag.val, doc) {
274 pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
275 F: FnMut(Doc) -> bool,
277 let mut pos = d.start;
279 let elt_tag = try_or!(vuint_at(d.data, pos), false);
280 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
281 pos = elt_size.next + elt_size.val;
282 if elt_tag.val == tg {
283 let doc = Doc { data: d.data, start: elt_size.next,
293 pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
294 F: FnOnce(&[u8]) -> T,
296 f(d.data[d.start..d.end])
300 pub fn doc_as_u8(d: Doc) -> u8 {
301 assert_eq!(d.end, d.start + 1u);
305 pub fn doc_as_u16(d: Doc) -> u16 {
306 assert_eq!(d.end, d.start + 2u);
307 u64_from_be_bytes(d.data, d.start, 2u) as u16
310 pub fn doc_as_u32(d: Doc) -> u32 {
311 assert_eq!(d.end, d.start + 4u);
312 u64_from_be_bytes(d.data, d.start, 4u) as u32
315 pub fn doc_as_u64(d: Doc) -> u64 {
316 assert_eq!(d.end, d.start + 8u);
317 u64_from_be_bytes(d.data, d.start, 8u)
320 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
321 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
322 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
323 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
325 pub struct Decoder<'a> {
330 impl<'doc> Decoder<'doc> {
331 pub fn new(d: Doc<'doc>) -> Decoder<'doc> {
338 fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
339 if self.pos < self.parent.end {
340 let TaggedDoc { tag: r_tag, doc: r_doc } =
341 try!(doc_at(self.parent.data, self.pos));
343 if r_tag == (EsLabel as uint) {
344 self.pos = r_doc.end;
345 let str = r_doc.as_str_slice();
347 return Err(Expected(format!("Expected label {} but \
348 found {}", lbl, str)));
355 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
356 debug!(". next_doc(exp_tag={})", exp_tag);
357 if self.pos >= self.parent.end {
358 return Err(Expected(format!("no more documents in \
361 let TaggedDoc { tag: r_tag, doc: r_doc } =
362 try!(doc_at(self.parent.data, self.pos));
363 debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
370 if r_tag != (exp_tag as uint) {
371 return Err(Expected(format!("expected EBML doc with tag {} but \
372 found tag {}", exp_tag, r_tag)));
374 if r_doc.end > self.parent.end {
375 return Err(Expected(format!("invalid EBML, child extends to \
376 {:#x}, parent to {:#x}",
377 r_doc.end, self.parent.end)));
379 self.pos = r_doc.end;
383 fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
384 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
386 let d = try!(self.next_doc(exp_tag));
387 let old_parent = self.parent;
388 let old_pos = self.pos;
391 let r = try!(f(self));
392 self.parent = old_parent;
397 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
398 let r = doc_as_u32(try!(self.next_doc(exp_tag)));
399 debug!("_next_uint exp_tag={} result={}", exp_tag, r);
403 pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
404 F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
406 let doc = try!(self.next_doc(EsOpaque));
408 let (old_parent, old_pos) = (self.parent, self.pos);
410 self.pos = doc.start;
412 let result = try!(op(self, doc));
414 self.parent = old_parent;
420 impl<'doc> serialize::Decoder<Error> for Decoder<'doc> {
421 fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
423 fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
424 fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
425 fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
426 fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
427 fn read_uint(&mut self) -> DecodeResult<uint> {
428 let v = doc_as_u64(try!(self.next_doc(EsUint)));
429 if v > (::std::uint::MAX as u64) {
430 Err(IntTooBig(v as uint))
436 fn read_i64(&mut self) -> DecodeResult<i64> {
437 Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
439 fn read_i32(&mut self) -> DecodeResult<i32> {
440 Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
442 fn read_i16(&mut self) -> DecodeResult<i16> {
443 Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
445 fn read_i8 (&mut self) -> DecodeResult<i8> {
446 Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
448 fn read_int(&mut self) -> DecodeResult<int> {
449 let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
450 if v > (int::MAX as i64) || v < (int::MIN as i64) {
451 debug!("FIXME \\#6122: Removing this makes this function miscompile");
452 Err(IntTooBig(v as uint))
458 fn read_bool(&mut self) -> DecodeResult<bool> {
459 Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
462 fn read_f64(&mut self) -> DecodeResult<f64> {
463 let bits = doc_as_u64(try!(self.next_doc(EsF64)));
464 Ok(unsafe { transmute(bits) })
466 fn read_f32(&mut self) -> DecodeResult<f32> {
467 let bits = doc_as_u32(try!(self.next_doc(EsF32)));
468 Ok(unsafe { transmute(bits) })
470 fn read_char(&mut self) -> DecodeResult<char> {
471 Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
473 fn read_str(&mut self) -> DecodeResult<String> {
474 Ok(try!(self.next_doc(EsStr)).as_str())
478 fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
479 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
481 debug!("read_enum({})", name);
482 try!(self._check_label(name));
484 let doc = try!(self.next_doc(EsEnum));
486 let (old_parent, old_pos) = (self.parent, self.pos);
488 self.pos = self.parent.start;
490 let result = try!(f(self));
492 self.parent = old_parent;
497 fn read_enum_variant<T, F>(&mut self, _: &[&str],
498 mut f: F) -> DecodeResult<T>
499 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
501 debug!("read_enum_variant()");
502 let idx = try!(self._next_uint(EsEnumVid));
503 debug!(" idx={}", idx);
505 let doc = try!(self.next_doc(EsEnumBody));
507 let (old_parent, old_pos) = (self.parent, self.pos);
509 self.pos = self.parent.start;
511 let result = try!(f(self, idx));
513 self.parent = old_parent;
518 fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
519 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
521 debug!("read_enum_variant_arg(idx={})", idx);
525 fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
526 mut f: F) -> DecodeResult<T>
527 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
529 debug!("read_enum_struct_variant()");
530 let idx = try!(self._next_uint(EsEnumVid));
531 debug!(" idx={}", idx);
533 let doc = try!(self.next_doc(EsEnumBody));
535 let (old_parent, old_pos) = (self.parent, self.pos);
537 self.pos = self.parent.start;
539 let result = try!(f(self, idx));
541 self.parent = old_parent;
546 fn read_enum_struct_variant_field<T, F>(&mut self,
550 -> DecodeResult<T> where
551 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
553 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
557 fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
558 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
560 debug!("read_struct(name={})", name);
564 fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
565 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
567 debug!("read_struct_field(name={}, idx={})", name, idx);
568 try!(self._check_label(name));
572 fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
573 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
575 debug!("read_tuple()");
576 self.read_seq(move |d, len| {
577 if len == tuple_len {
580 Err(Expected(format!("Expected tuple of length `{}`, \
581 found tuple of length `{}`", tuple_len, len)))
586 fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
587 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
589 debug!("read_tuple_arg(idx={})", idx);
590 self.read_seq_elt(idx, f)
593 fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
594 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
596 debug!("read_tuple_struct(name={})", name);
597 self.read_tuple(len, f)
600 fn read_tuple_struct_arg<T, F>(&mut self,
603 -> DecodeResult<T> where
604 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
606 debug!("read_tuple_struct_arg(idx={})", idx);
607 self.read_tuple_arg(idx, f)
610 fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
611 F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
613 debug!("read_option()");
614 self.read_enum("Option", move |this| {
615 this.read_enum_variant(&["None", "Some"], move |this, idx| {
620 Err(Expected(format!("Expected None or Some")))
627 fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
628 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
630 debug!("read_seq()");
631 self.push_doc(EsVec, move |d| {
632 let len = try!(d._next_uint(EsVecLen));
633 debug!(" len={}", len);
638 fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
639 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
641 debug!("read_seq_elt(idx={})", idx);
642 self.push_doc(EsVecElt, f)
645 fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
646 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
648 debug!("read_map()");
649 self.push_doc(EsMap, move |d| {
650 let len = try!(d._next_uint(EsMapLen));
651 debug!(" len={}", len);
656 fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
657 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
659 debug!("read_map_elt_key(idx={})", idx);
660 self.push_doc(EsMapKey, f)
663 fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
664 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
666 debug!("read_map_elt_val(idx={})", idx);
667 self.push_doc(EsMapVal, f)
670 fn error(&mut self, err: &str) -> Error {
671 ApplicationError(err.to_string())
677 use std::clone::Clone;
678 use std::io::extensions::u64_to_be_bytes;
679 use std::io::{Writer, Seek};
683 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
684 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
685 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
686 EsOpaque, EsLabel, EbmlEncoderTag };
691 pub type EncodeResult = io::IoResult<()>;
694 pub struct Encoder<'a, W:'a> {
695 pub writer: &'a mut W,
696 size_positions: Vec<uint>,
699 fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
701 1u => w.write(&[0x80u8 | (n as u8)]),
702 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
703 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
705 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
706 (n >> 8_u) as u8, n as u8]),
707 _ => Err(io::IoError {
708 kind: io::OtherIoError,
710 detail: Some(format!("{}", n))
715 fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
716 if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
717 if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
718 if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
719 if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
721 kind: io::OtherIoError,
723 detail: Some(format!("{}", n))
727 // FIXME (#2741): Provide a function to write the standard rbml header.
728 impl<'a, W: Writer + Seek> Encoder<'a, W> {
729 pub fn new(w: &'a mut W) -> Encoder<'a, W> {
732 size_positions: vec!(),
736 /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
737 pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
739 writer: mem::transmute_copy(&self.writer),
740 size_positions: self.size_positions.clone(),
744 pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
745 debug!("Start tag {}", tag_id);
747 // Write the enum ID:
748 try!(write_vuint(self.writer, tag_id));
750 // Write a placeholder four-byte size.
751 self.size_positions.push(try!(self.writer.tell()) as uint);
752 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
753 self.writer.write(zeroes)
756 pub fn end_tag(&mut self) -> EncodeResult {
757 let last_size_pos = self.size_positions.pop().unwrap();
758 let cur_pos = try!(self.writer.tell());
759 try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
760 let size = cur_pos as uint - last_size_pos - 4;
761 try!(write_sized_vuint(self.writer, size, 4u));
762 let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
764 debug!("End tag (size = {})", size);
768 pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
769 F: FnOnce() -> EncodeResult,
771 try!(self.start_tag(tag_id));
776 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
777 try!(write_vuint(self.writer, tag_id));
778 try!(write_vuint(self.writer, b.len()));
782 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
783 u64_to_be_bytes(v, 8u, |v| {
784 self.wr_tagged_bytes(tag_id, v)
788 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
789 u64_to_be_bytes(v as u64, 4u, |v| {
790 self.wr_tagged_bytes(tag_id, v)
794 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
795 u64_to_be_bytes(v as u64, 2u, |v| {
796 self.wr_tagged_bytes(tag_id, v)
800 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
801 self.wr_tagged_bytes(tag_id, &[v])
804 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
805 u64_to_be_bytes(v as u64, 8u, |v| {
806 self.wr_tagged_bytes(tag_id, v)
810 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
811 u64_to_be_bytes(v as u64, 4u, |v| {
812 self.wr_tagged_bytes(tag_id, v)
816 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
817 u64_to_be_bytes(v as u64, 2u, |v| {
818 self.wr_tagged_bytes(tag_id, v)
822 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
823 self.wr_tagged_bytes(tag_id, &[v as u8])
826 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
827 self.wr_tagged_bytes(tag_id, v.as_bytes())
830 pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
831 debug!("Write {} bytes", b.len());
835 pub fn wr_str(&mut self, s: &str) -> EncodeResult {
836 debug!("Write str: {}", s);
837 self.writer.write(s.as_bytes())
841 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
842 // efficiently encode sizes; this is a fixed point iteration
844 // Set to true to generate more debugging in EBML code.
845 // Totally lame approach.
846 static DEBUG: bool = true;
848 impl<'a, W: Writer + Seek> Encoder<'a, W> {
849 // used internally to emit things like the vector length and so on
850 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
851 assert!(v <= 0xFFFF_FFFF_u);
852 self.wr_tagged_u32(t as uint, v as u32)
855 fn _emit_label(&mut self, label: &str) -> EncodeResult {
856 // There are various strings that we have access to, such as
857 // the name of a record field, which do not actually appear in
858 // the encoded EBML (normally). This is just for
859 // efficiency. When debugging, though, we can emit such
860 // labels and then they will be checked by decoder to
861 // try and check panics more quickly.
862 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
866 pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
867 F: FnOnce(&mut Encoder<W>) -> EncodeResult,
869 try!(self.start_tag(EsOpaque as uint));
875 impl<'a, W: Writer + Seek> serialize::Encoder<io::IoError> for Encoder<'a, W> {
876 fn emit_nil(&mut self) -> EncodeResult {
880 fn emit_uint(&mut self, v: uint) -> EncodeResult {
881 self.wr_tagged_u64(EsUint as uint, v as u64)
883 fn emit_u64(&mut self, v: u64) -> EncodeResult {
884 self.wr_tagged_u64(EsU64 as uint, v)
886 fn emit_u32(&mut self, v: u32) -> EncodeResult {
887 self.wr_tagged_u32(EsU32 as uint, v)
889 fn emit_u16(&mut self, v: u16) -> EncodeResult {
890 self.wr_tagged_u16(EsU16 as uint, v)
892 fn emit_u8(&mut self, v: u8) -> EncodeResult {
893 self.wr_tagged_u8(EsU8 as uint, v)
896 fn emit_int(&mut self, v: int) -> EncodeResult {
897 self.wr_tagged_i64(EsInt as uint, v as i64)
899 fn emit_i64(&mut self, v: i64) -> EncodeResult {
900 self.wr_tagged_i64(EsI64 as uint, v)
902 fn emit_i32(&mut self, v: i32) -> EncodeResult {
903 self.wr_tagged_i32(EsI32 as uint, v)
905 fn emit_i16(&mut self, v: i16) -> EncodeResult {
906 self.wr_tagged_i16(EsI16 as uint, v)
908 fn emit_i8(&mut self, v: i8) -> EncodeResult {
909 self.wr_tagged_i8(EsI8 as uint, v)
912 fn emit_bool(&mut self, v: bool) -> EncodeResult {
913 self.wr_tagged_u8(EsBool as uint, v as u8)
916 fn emit_f64(&mut self, v: f64) -> EncodeResult {
917 let bits = unsafe { mem::transmute(v) };
918 self.wr_tagged_u64(EsF64 as uint, bits)
920 fn emit_f32(&mut self, v: f32) -> EncodeResult {
921 let bits = unsafe { mem::transmute(v) };
922 self.wr_tagged_u32(EsF32 as uint, bits)
924 fn emit_char(&mut self, v: char) -> EncodeResult {
925 self.wr_tagged_u32(EsChar as uint, v as u32)
928 fn emit_str(&mut self, v: &str) -> EncodeResult {
929 self.wr_tagged_str(EsStr as uint, v)
932 fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
933 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
935 try!(self._emit_label(name));
936 try!(self.start_tag(EsEnum as uint));
941 fn emit_enum_variant<F>(&mut self,
945 f: F) -> EncodeResult where
946 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
948 try!(self._emit_tagged_uint(EsEnumVid, v_id));
949 try!(self.start_tag(EsEnumBody as uint));
954 fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
955 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
960 fn emit_enum_struct_variant<F>(&mut self,
964 f: F) -> EncodeResult where
965 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
967 self.emit_enum_variant(v_name, v_id, cnt, f)
970 fn emit_enum_struct_variant_field<F>(&mut self,
973 f: F) -> EncodeResult where
974 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
976 self.emit_enum_variant_arg(idx, f)
979 fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
980 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
985 fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
986 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
988 try!(self._emit_label(name));
992 fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
993 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
995 self.emit_seq(len, f)
997 fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
998 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1000 self.emit_seq_elt(idx, f)
1003 fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
1004 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1006 self.emit_seq(len, f)
1008 fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1009 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1011 self.emit_seq_elt(idx, f)
1014 fn emit_option<F>(&mut self, f: F) -> EncodeResult where
1015 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1017 self.emit_enum("Option", f)
1019 fn emit_option_none(&mut self) -> EncodeResult {
1020 self.emit_enum_variant("None", 0, 0, |_| Ok(()))
1022 fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
1023 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1026 self.emit_enum_variant("Some", 1, 1, f)
1029 fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
1030 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1033 try!(self.start_tag(EsVec as uint));
1034 try!(self._emit_tagged_uint(EsVecLen, len));
1039 fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1040 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1043 try!(self.start_tag(EsVecElt as uint));
1048 fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
1049 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1052 try!(self.start_tag(EsMap as uint));
1053 try!(self._emit_tagged_uint(EsMapLen, len));
1058 fn emit_map_elt_key<F>(&mut self, _idx: uint, mut f: F) -> EncodeResult where
1059 F: FnMut(&mut Encoder<'a, W>) -> EncodeResult,
1062 try!(self.start_tag(EsMapKey as uint));
1067 fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1068 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1070 try!(self.start_tag(EsMapVal as uint));
1077 // ___________________________________________________________________________
1082 use super::{Doc, reader, writer};
1083 use super::io::SeekableMemWriter;
1085 use serialize::{Encodable, Decodable};
1087 use std::option::Option;
1088 use std::option::Option::{None, Some};
1091 fn test_vuint_at() {
1099 0x10, 0x00, 0x00, 0x00,
1100 0x1f, 0xff, 0xff, 0xff
1103 let mut res: reader::Res;
1106 res = reader::vuint_at(data, 0).unwrap();
1107 assert_eq!(res.val, 0);
1108 assert_eq!(res.next, 1);
1109 res = reader::vuint_at(data, res.next).unwrap();
1110 assert_eq!(res.val, (1 << 7) - 1);
1111 assert_eq!(res.next, 2);
1114 res = reader::vuint_at(data, res.next).unwrap();
1115 assert_eq!(res.val, 0);
1116 assert_eq!(res.next, 4);
1117 res = reader::vuint_at(data, res.next).unwrap();
1118 assert_eq!(res.val, (1 << 14) - 1);
1119 assert_eq!(res.next, 6);
1122 res = reader::vuint_at(data, res.next).unwrap();
1123 assert_eq!(res.val, 0);
1124 assert_eq!(res.next, 9);
1125 res = reader::vuint_at(data, res.next).unwrap();
1126 assert_eq!(res.val, (1 << 21) - 1);
1127 assert_eq!(res.next, 12);
1130 res = reader::vuint_at(data, res.next).unwrap();
1131 assert_eq!(res.val, 0);
1132 assert_eq!(res.next, 16);
1133 res = reader::vuint_at(data, res.next).unwrap();
1134 assert_eq!(res.val, (1 << 28) - 1);
1135 assert_eq!(res.next, 20);
1139 fn test_option_int() {
1140 fn test_v(v: Option<int>) {
1141 debug!("v == {}", v);
1142 let mut wr = SeekableMemWriter::new();
1144 let mut rbml_w = writer::Encoder::new(&mut wr);
1145 let _ = v.encode(&mut rbml_w);
1147 let rbml_doc = Doc::new(wr.get_ref());
1148 let mut deser = reader::Decoder::new(rbml_doc);
1149 let v1 = Decodable::decode(&mut deser).unwrap();
1150 debug!("v1 == {}", v1);
1162 #![allow(non_snake_case)]
1167 pub fn vuint_at_A_aligned(b: &mut Bencher) {
1168 let data = Vec::from_fn(4*100, |i| {
1177 while i < data.len() {
1178 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1185 pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1186 let data = Vec::from_fn(4*100+1, |i| {
1195 while i < data.len() {
1196 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1203 pub fn vuint_at_D_aligned(b: &mut Bencher) {
1204 let data = Vec::from_fn(4*100, |i| {
1214 while i < data.len() {
1215 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1222 pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1223 let data = Vec::from_fn(4*100+1, |i| {
1233 while i < data.len() {
1234 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;