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"]
19 #![unstable(feature = "rustc_private")]
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/")]
28 #![feature(collections)]
32 #![feature(rustc_private)]
33 #![feature(slicing_syntax)]
34 #![feature(staged_api)]
36 extern crate serialize;
37 #[macro_use] extern crate log;
39 #[cfg(test)] extern crate test;
41 pub use self::EbmlEncoderTag::*;
42 pub use self::Error::*;
49 /// Common data structures
50 #[derive(Clone, Copy)]
57 impl<'doc> Doc<'doc> {
58 pub fn new(data: &'doc [u8]) -> Doc<'doc> {
59 Doc { data: data, start: 0, end: data.len() }
62 pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
63 reader::get_doc(*self, tag)
66 pub fn as_str_slice<'a>(&'a self) -> &'a str {
67 str::from_utf8(&self.data[self.start..self.end]).unwrap()
70 pub fn as_str(&self) -> String {
71 self.as_str_slice().to_string()
75 pub struct TaggedDoc<'a> {
80 #[derive(Copy, Debug)]
81 pub enum EbmlEncoderTag {
111 EsLabel, // Used only when debugging
118 IoError(std::old_io::IoError),
119 ApplicationError(String)
122 impl fmt::Display for Error {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 // FIXME: this should be a more useful display form
125 fmt::Debug::fmt(self, f)
128 // --------------------------------------
134 use std::old_io::extensions::u64_from_be_bytes;
135 use std::mem::transmute;
137 use std::option::Option;
138 use std::option::Option::{None, Some};
142 use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
143 EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
144 EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
145 EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
146 Error, IntTooBig, Expected };
148 pub type DecodeResult<T> = Result<T, Error>;
151 macro_rules! try_or {
152 ($e:expr, $r:expr) => (
156 debug!("ignored error: {:?}", e);
170 fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
172 if a & 0x80u8 != 0u8 {
173 return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1});
175 if a & 0x40u8 != 0u8 {
176 return Ok(Res {val: ((a & 0x3fu8) as uint) << 8 |
177 (data[start + 1] as uint),
180 if a & 0x20u8 != 0u8 {
181 return Ok(Res {val: ((a & 0x1fu8) as uint) << 16 |
182 (data[start + 1] as uint) << 8 |
183 (data[start + 2] as uint),
186 if a & 0x10u8 != 0u8 {
187 return Ok(Res {val: ((a & 0x0fu8) as uint) << 24 |
188 (data[start + 1] as uint) << 16 |
189 (data[start + 2] as uint) << 8 |
190 (data[start + 3] as uint),
193 Err(IntTooBig(a as uint))
196 pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
197 if data.len() - start < 4 {
198 return vuint_at_slow(data, start);
201 // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
202 // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
203 // Using the four most significant bits of the u32 we lookup in the table below how the
204 // element ID should be derived from it.
206 // The table stores tuples (shift, mask) where shift is the number the u32 should be right
207 // shifted with and mask is the value the right shifted value should be masked with.
208 // If for example the most significant bit is set this means it's a class A ID and the u32
209 // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
210 // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
212 // By storing the number of shifts and masks in a table instead of checking in order if
213 // the most significant bit is set, the second most significant bit is set etc. we can
214 // replace up to three "and+branch" with a single table lookup which gives us a measured
215 // speedup of around 2x on x86_64.
216 static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
217 (0, 0x0), (0, 0x0fffffff),
218 (8, 0x1fffff), (8, 0x1fffff),
219 (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
220 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
221 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
225 let ptr = data.as_ptr().offset(start as int) as *const u32;
226 let val = Int::from_be(*ptr);
228 let i = (val >> 28) as uint;
229 let (shift, mask) = SHIFT_MASK_TABLE[i];
231 val: ((val >> shift) & mask) as uint,
232 next: start + (((32 - shift) >> 3) as uint)
237 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
238 let elt_tag = try!(vuint_at(data, start));
239 let elt_size = try!(vuint_at(data, elt_tag.next));
240 let end = elt_size.next + elt_size.val;
243 doc: Doc { data: data, start: elt_size.next, end: end }
247 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
248 let mut pos = d.start;
250 let elt_tag = try_or!(vuint_at(d.data, pos), None);
251 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
252 pos = elt_size.next + elt_size.val;
253 if elt_tag.val == tg {
254 return Some(Doc { data: d.data, start: elt_size.next,
261 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
262 match maybe_get_doc(d, tg) {
265 error!("failed to find block with tag {:?}", tg);
271 pub fn docs<F>(d: Doc, mut it: F) -> bool where
272 F: FnMut(uint, Doc) -> bool,
274 let mut pos = d.start;
276 let elt_tag = try_or!(vuint_at(d.data, pos), false);
277 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
278 pos = elt_size.next + elt_size.val;
279 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
280 if !it(elt_tag.val, doc) {
287 pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
288 F: FnMut(Doc) -> bool,
290 let mut pos = d.start;
292 let elt_tag = try_or!(vuint_at(d.data, pos), false);
293 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
294 pos = elt_size.next + elt_size.val;
295 if elt_tag.val == tg {
296 let doc = Doc { data: d.data, start: elt_size.next,
306 pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
307 F: FnOnce(&[u8]) -> T,
309 f(&d.data[d.start..d.end])
313 pub fn doc_as_u8(d: Doc) -> u8 {
314 assert_eq!(d.end, d.start + 1);
318 pub fn doc_as_u16(d: Doc) -> u16 {
319 assert_eq!(d.end, d.start + 2);
320 u64_from_be_bytes(d.data, d.start, 2) as u16
323 pub fn doc_as_u32(d: Doc) -> u32 {
324 assert_eq!(d.end, d.start + 4);
325 u64_from_be_bytes(d.data, d.start, 4) as u32
328 pub fn doc_as_u64(d: Doc) -> u64 {
329 assert_eq!(d.end, d.start + 8);
330 u64_from_be_bytes(d.data, d.start, 8)
333 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
334 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
335 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
336 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
338 pub struct Decoder<'a> {
343 impl<'doc> Decoder<'doc> {
344 pub fn new(d: Doc<'doc>) -> Decoder<'doc> {
351 fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
352 if self.pos < self.parent.end {
353 let TaggedDoc { tag: r_tag, doc: r_doc } =
354 try!(doc_at(self.parent.data, self.pos));
356 if r_tag == (EsLabel as uint) {
357 self.pos = r_doc.end;
358 let str = r_doc.as_str_slice();
360 return Err(Expected(format!("Expected label {:?} but \
361 found {:?}", lbl, str)));
368 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
369 debug!(". next_doc(exp_tag={:?})", exp_tag);
370 if self.pos >= self.parent.end {
371 return Err(Expected(format!("no more documents in \
374 let TaggedDoc { tag: r_tag, doc: r_doc } =
375 try!(doc_at(self.parent.data, self.pos));
376 debug!("self.parent={:?}-{:?} self.pos={:?} r_tag={:?} r_doc={:?}-{:?}",
383 if r_tag != (exp_tag as uint) {
384 return Err(Expected(format!("expected EBML doc with tag {:?} but \
385 found tag {:?}", exp_tag, r_tag)));
387 if r_doc.end > self.parent.end {
388 return Err(Expected(format!("invalid EBML, child extends to \
389 {:#x}, parent to {:#x}",
390 r_doc.end, self.parent.end)));
392 self.pos = r_doc.end;
396 fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
397 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
399 let d = try!(self.next_doc(exp_tag));
400 let old_parent = self.parent;
401 let old_pos = self.pos;
404 let r = try!(f(self));
405 self.parent = old_parent;
410 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
411 let r = doc_as_u32(try!(self.next_doc(exp_tag)));
412 debug!("_next_uint exp_tag={:?} result={:?}", exp_tag, r);
416 pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
417 F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
419 let doc = try!(self.next_doc(EsOpaque));
421 let (old_parent, old_pos) = (self.parent, self.pos);
423 self.pos = doc.start;
425 let result = try!(op(self, doc));
427 self.parent = old_parent;
433 impl<'doc> serialize::Decoder for Decoder<'doc> {
435 fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
437 fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
438 fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
439 fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
440 fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
441 fn read_uint(&mut self) -> DecodeResult<uint> {
442 let v = doc_as_u64(try!(self.next_doc(EsUint)));
443 if v > (::std::uint::MAX as u64) {
444 Err(IntTooBig(v as uint))
450 fn read_i64(&mut self) -> DecodeResult<i64> {
451 Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
453 fn read_i32(&mut self) -> DecodeResult<i32> {
454 Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
456 fn read_i16(&mut self) -> DecodeResult<i16> {
457 Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
459 fn read_i8 (&mut self) -> DecodeResult<i8> {
460 Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
462 fn read_int(&mut self) -> DecodeResult<int> {
463 let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
464 if v > (int::MAX as i64) || v < (int::MIN as i64) {
465 debug!("FIXME \\#6122: Removing this makes this function miscompile");
466 Err(IntTooBig(v as uint))
472 fn read_bool(&mut self) -> DecodeResult<bool> {
473 Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
476 fn read_f64(&mut self) -> DecodeResult<f64> {
477 let bits = doc_as_u64(try!(self.next_doc(EsF64)));
478 Ok(unsafe { transmute(bits) })
480 fn read_f32(&mut self) -> DecodeResult<f32> {
481 let bits = doc_as_u32(try!(self.next_doc(EsF32)));
482 Ok(unsafe { transmute(bits) })
484 fn read_char(&mut self) -> DecodeResult<char> {
485 Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
487 fn read_str(&mut self) -> DecodeResult<String> {
488 Ok(try!(self.next_doc(EsStr)).as_str())
492 fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
493 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
495 debug!("read_enum({})", name);
496 try!(self._check_label(name));
498 let doc = try!(self.next_doc(EsEnum));
500 let (old_parent, old_pos) = (self.parent, self.pos);
502 self.pos = self.parent.start;
504 let result = try!(f(self));
506 self.parent = old_parent;
511 fn read_enum_variant<T, F>(&mut self, _: &[&str],
512 mut f: F) -> DecodeResult<T>
513 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
515 debug!("read_enum_variant()");
516 let idx = try!(self._next_uint(EsEnumVid));
517 debug!(" idx={}", idx);
519 let doc = try!(self.next_doc(EsEnumBody));
521 let (old_parent, old_pos) = (self.parent, self.pos);
523 self.pos = self.parent.start;
525 let result = try!(f(self, idx));
527 self.parent = old_parent;
532 fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
533 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
535 debug!("read_enum_variant_arg(idx={})", idx);
539 fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
540 mut f: F) -> DecodeResult<T>
541 where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
543 debug!("read_enum_struct_variant()");
544 let idx = try!(self._next_uint(EsEnumVid));
545 debug!(" idx={}", idx);
547 let doc = try!(self.next_doc(EsEnumBody));
549 let (old_parent, old_pos) = (self.parent, self.pos);
551 self.pos = self.parent.start;
553 let result = try!(f(self, idx));
555 self.parent = old_parent;
560 fn read_enum_struct_variant_field<T, F>(&mut self,
564 -> DecodeResult<T> where
565 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
567 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
571 fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
572 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
574 debug!("read_struct(name={})", name);
578 fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
579 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
581 debug!("read_struct_field(name={}, idx={})", name, idx);
582 try!(self._check_label(name));
586 fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
587 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
589 debug!("read_tuple()");
590 self.read_seq(move |d, len| {
591 if len == tuple_len {
594 Err(Expected(format!("Expected tuple of length `{}`, \
595 found tuple of length `{}`", tuple_len, len)))
600 fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
601 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
603 debug!("read_tuple_arg(idx={})", idx);
604 self.read_seq_elt(idx, f)
607 fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
608 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
610 debug!("read_tuple_struct(name={})", name);
611 self.read_tuple(len, f)
614 fn read_tuple_struct_arg<T, F>(&mut self,
617 -> DecodeResult<T> where
618 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
620 debug!("read_tuple_struct_arg(idx={})", idx);
621 self.read_tuple_arg(idx, f)
624 fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
625 F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
627 debug!("read_option()");
628 self.read_enum("Option", move |this| {
629 this.read_enum_variant(&["None", "Some"], move |this, idx| {
634 Err(Expected(format!("Expected None or Some")))
641 fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
642 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
644 debug!("read_seq()");
645 self.push_doc(EsVec, move |d| {
646 let len = try!(d._next_uint(EsVecLen));
647 debug!(" len={}", len);
652 fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
653 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
655 debug!("read_seq_elt(idx={})", idx);
656 self.push_doc(EsVecElt, f)
659 fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
660 F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
662 debug!("read_map()");
663 self.push_doc(EsMap, move |d| {
664 let len = try!(d._next_uint(EsMapLen));
665 debug!(" len={}", len);
670 fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
671 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
673 debug!("read_map_elt_key(idx={})", idx);
674 self.push_doc(EsMapKey, f)
677 fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
678 F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
680 debug!("read_map_elt_val(idx={})", idx);
681 self.push_doc(EsMapVal, f)
684 fn error(&mut self, err: &str) -> Error {
685 ApplicationError(err.to_string())
691 use std::clone::Clone;
692 use std::old_io::extensions::u64_to_be_bytes;
693 use std::old_io::{Writer, Seek};
697 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
698 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
699 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
700 EsOpaque, EsLabel, EbmlEncoderTag };
705 pub type EncodeResult = old_io::IoResult<()>;
708 pub struct Encoder<'a, W:'a> {
709 pub writer: &'a mut W,
710 size_positions: Vec<uint>,
713 fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
715 1 => w.write_all(&[0x80u8 | (n as u8)]),
716 2 => w.write_all(&[0x40u8 | ((n >> 8) as u8), n as u8]),
717 3 => w.write_all(&[0x20u8 | ((n >> 16) as u8), (n >> 8_u) as u8,
719 4 => w.write_all(&[0x10u8 | ((n >> 24) as u8), (n >> 16_u) as u8,
720 (n >> 8_u) as u8, n as u8]),
721 _ => Err(old_io::IoError {
722 kind: old_io::OtherIoError,
724 detail: Some(format!("{}", n))
729 fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
730 if n < 0x7f { return write_sized_vuint(w, n, 1); }
731 if n < 0x4000 { return write_sized_vuint(w, n, 2); }
732 if n < 0x200000 { return write_sized_vuint(w, n, 3); }
733 if n < 0x10000000 { return write_sized_vuint(w, n, 4); }
734 Err(old_io::IoError {
735 kind: old_io::OtherIoError,
737 detail: Some(format!("{}", n))
741 // FIXME (#2741): Provide a function to write the standard rbml header.
742 impl<'a, W: Writer + Seek> Encoder<'a, W> {
743 pub fn new(w: &'a mut W) -> Encoder<'a, W> {
746 size_positions: vec!(),
750 /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
751 pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
753 writer: mem::transmute_copy(&self.writer),
754 size_positions: self.size_positions.clone(),
758 pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
759 debug!("Start tag {:?}", tag_id);
761 // Write the enum ID:
762 try!(write_vuint(self.writer, tag_id));
764 // Write a placeholder four-byte size.
765 self.size_positions.push(try!(self.writer.tell()) as uint);
766 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
767 self.writer.write_all(zeroes)
770 pub fn end_tag(&mut self) -> EncodeResult {
771 let last_size_pos = self.size_positions.pop().unwrap();
772 let cur_pos = try!(self.writer.tell());
773 try!(self.writer.seek(last_size_pos as i64, old_io::SeekSet));
774 let size = cur_pos as uint - last_size_pos - 4;
775 try!(write_sized_vuint(self.writer, size, 4));
776 let r = try!(self.writer.seek(cur_pos as i64, old_io::SeekSet));
778 debug!("End tag (size = {:?})", size);
782 pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
783 F: FnOnce() -> EncodeResult,
785 try!(self.start_tag(tag_id));
790 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
791 try!(write_vuint(self.writer, tag_id));
792 try!(write_vuint(self.writer, b.len()));
793 self.writer.write_all(b)
796 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
797 u64_to_be_bytes(v, 8, |v| {
798 self.wr_tagged_bytes(tag_id, v)
802 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
803 u64_to_be_bytes(v as u64, 4, |v| {
804 self.wr_tagged_bytes(tag_id, v)
808 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
809 u64_to_be_bytes(v as u64, 2, |v| {
810 self.wr_tagged_bytes(tag_id, v)
814 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
815 self.wr_tagged_bytes(tag_id, &[v])
818 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
819 u64_to_be_bytes(v as u64, 8, |v| {
820 self.wr_tagged_bytes(tag_id, v)
824 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
825 u64_to_be_bytes(v as u64, 4, |v| {
826 self.wr_tagged_bytes(tag_id, v)
830 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
831 u64_to_be_bytes(v as u64, 2, |v| {
832 self.wr_tagged_bytes(tag_id, v)
836 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
837 self.wr_tagged_bytes(tag_id, &[v as u8])
840 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
841 self.wr_tagged_bytes(tag_id, v.as_bytes())
844 pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
845 debug!("Write {:?} bytes", b.len());
846 self.writer.write_all(b)
849 pub fn wr_str(&mut self, s: &str) -> EncodeResult {
850 debug!("Write str: {:?}", s);
851 self.writer.write_all(s.as_bytes())
855 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
856 // efficiently encode sizes; this is a fixed point iteration
858 // Set to true to generate more debugging in EBML code.
859 // Totally lame approach.
861 static DEBUG: bool = true;
863 static DEBUG: bool = false;
865 impl<'a, W: Writer + Seek> Encoder<'a, W> {
866 // used internally to emit things like the vector length and so on
867 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
868 assert!(v <= 0xFFFF_FFFF_u);
869 self.wr_tagged_u32(t as uint, v as u32)
872 fn _emit_label(&mut self, label: &str) -> EncodeResult {
873 // There are various strings that we have access to, such as
874 // the name of a record field, which do not actually appear in
875 // the encoded EBML (normally). This is just for
876 // efficiency. When debugging, though, we can emit such
877 // labels and then they will be checked by decoder to
878 // try and check panics more quickly.
879 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
883 pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
884 F: FnOnce(&mut Encoder<W>) -> EncodeResult,
886 try!(self.start_tag(EsOpaque as uint));
892 impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> {
893 type Error = old_io::IoError;
895 fn emit_nil(&mut self) -> EncodeResult {
899 fn emit_uint(&mut self, v: uint) -> EncodeResult {
900 self.wr_tagged_u64(EsUint as uint, v as u64)
902 fn emit_u64(&mut self, v: u64) -> EncodeResult {
903 self.wr_tagged_u64(EsU64 as uint, v)
905 fn emit_u32(&mut self, v: u32) -> EncodeResult {
906 self.wr_tagged_u32(EsU32 as uint, v)
908 fn emit_u16(&mut self, v: u16) -> EncodeResult {
909 self.wr_tagged_u16(EsU16 as uint, v)
911 fn emit_u8(&mut self, v: u8) -> EncodeResult {
912 self.wr_tagged_u8(EsU8 as uint, v)
915 fn emit_int(&mut self, v: int) -> EncodeResult {
916 self.wr_tagged_i64(EsInt as uint, v as i64)
918 fn emit_i64(&mut self, v: i64) -> EncodeResult {
919 self.wr_tagged_i64(EsI64 as uint, v)
921 fn emit_i32(&mut self, v: i32) -> EncodeResult {
922 self.wr_tagged_i32(EsI32 as uint, v)
924 fn emit_i16(&mut self, v: i16) -> EncodeResult {
925 self.wr_tagged_i16(EsI16 as uint, v)
927 fn emit_i8(&mut self, v: i8) -> EncodeResult {
928 self.wr_tagged_i8(EsI8 as uint, v)
931 fn emit_bool(&mut self, v: bool) -> EncodeResult {
932 self.wr_tagged_u8(EsBool as uint, v as u8)
935 fn emit_f64(&mut self, v: f64) -> EncodeResult {
936 let bits = unsafe { mem::transmute(v) };
937 self.wr_tagged_u64(EsF64 as uint, bits)
939 fn emit_f32(&mut self, v: f32) -> EncodeResult {
940 let bits = unsafe { mem::transmute(v) };
941 self.wr_tagged_u32(EsF32 as uint, bits)
943 fn emit_char(&mut self, v: char) -> EncodeResult {
944 self.wr_tagged_u32(EsChar as uint, v as u32)
947 fn emit_str(&mut self, v: &str) -> EncodeResult {
948 self.wr_tagged_str(EsStr as uint, v)
951 fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
952 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
954 try!(self._emit_label(name));
955 try!(self.start_tag(EsEnum as uint));
960 fn emit_enum_variant<F>(&mut self,
964 f: F) -> EncodeResult where
965 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
967 try!(self._emit_tagged_uint(EsEnumVid, v_id));
968 try!(self.start_tag(EsEnumBody as uint));
973 fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
974 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
979 fn emit_enum_struct_variant<F>(&mut self,
983 f: F) -> EncodeResult where
984 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
986 self.emit_enum_variant(v_name, v_id, cnt, f)
989 fn emit_enum_struct_variant_field<F>(&mut self,
992 f: F) -> EncodeResult where
993 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
995 self.emit_enum_variant_arg(idx, f)
998 fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
999 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1004 fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
1005 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1007 try!(self._emit_label(name));
1011 fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
1012 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1014 self.emit_seq(len, f)
1016 fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1017 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1019 self.emit_seq_elt(idx, f)
1022 fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
1023 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1025 self.emit_seq(len, f)
1027 fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
1028 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1030 self.emit_seq_elt(idx, f)
1033 fn emit_option<F>(&mut self, f: F) -> EncodeResult where
1034 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1036 self.emit_enum("Option", f)
1038 fn emit_option_none(&mut self) -> EncodeResult {
1039 self.emit_enum_variant("None", 0, 0, |_| Ok(()))
1041 fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
1042 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1045 self.emit_enum_variant("Some", 1, 1, f)
1048 fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
1049 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1052 try!(self.start_tag(EsVec as uint));
1053 try!(self._emit_tagged_uint(EsVecLen, len));
1058 fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1059 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1062 try!(self.start_tag(EsVecElt as uint));
1067 fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
1068 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1071 try!(self.start_tag(EsMap as uint));
1072 try!(self._emit_tagged_uint(EsMapLen, len));
1077 fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1078 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1081 try!(self.start_tag(EsMapKey as uint));
1086 fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
1087 F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
1089 try!(self.start_tag(EsMapVal as uint));
1096 // ___________________________________________________________________________
1101 use super::{Doc, reader, writer};
1102 use super::io::SeekableMemWriter;
1104 use serialize::{Encodable, Decodable};
1106 use std::option::Option;
1107 use std::option::Option::{None, Some};
1110 fn test_vuint_at() {
1118 0x10, 0x00, 0x00, 0x00,
1119 0x1f, 0xff, 0xff, 0xff
1122 let mut res: reader::Res;
1125 res = reader::vuint_at(data, 0).unwrap();
1126 assert_eq!(res.val, 0);
1127 assert_eq!(res.next, 1);
1128 res = reader::vuint_at(data, res.next).unwrap();
1129 assert_eq!(res.val, (1 << 7) - 1);
1130 assert_eq!(res.next, 2);
1133 res = reader::vuint_at(data, res.next).unwrap();
1134 assert_eq!(res.val, 0);
1135 assert_eq!(res.next, 4);
1136 res = reader::vuint_at(data, res.next).unwrap();
1137 assert_eq!(res.val, (1 << 14) - 1);
1138 assert_eq!(res.next, 6);
1141 res = reader::vuint_at(data, res.next).unwrap();
1142 assert_eq!(res.val, 0);
1143 assert_eq!(res.next, 9);
1144 res = reader::vuint_at(data, res.next).unwrap();
1145 assert_eq!(res.val, (1 << 21) - 1);
1146 assert_eq!(res.next, 12);
1149 res = reader::vuint_at(data, res.next).unwrap();
1150 assert_eq!(res.val, 0);
1151 assert_eq!(res.next, 16);
1152 res = reader::vuint_at(data, res.next).unwrap();
1153 assert_eq!(res.val, (1 << 28) - 1);
1154 assert_eq!(res.next, 20);
1158 fn test_option_int() {
1159 fn test_v(v: Option<int>) {
1160 debug!("v == {:?}", v);
1161 let mut wr = SeekableMemWriter::new();
1163 let mut rbml_w = writer::Encoder::new(&mut wr);
1164 let _ = v.encode(&mut rbml_w);
1166 let rbml_doc = Doc::new(wr.get_ref());
1167 let mut deser = reader::Decoder::new(rbml_doc);
1168 let v1 = Decodable::decode(&mut deser).unwrap();
1169 debug!("v1 == {:?}", v1);
1181 #![allow(non_snake_case)]
1186 pub fn vuint_at_A_aligned(b: &mut Bencher) {
1187 let data = (0i32..4*100).map(|i| {
1192 }).collect::<Vec<_>>();
1196 while i < data.len() {
1197 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1204 pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1205 let data = (0i32..4*100+1).map(|i| {
1210 }).collect::<Vec<_>>();
1214 while i < data.len() {
1215 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1222 pub fn vuint_at_D_aligned(b: &mut Bencher) {
1223 let data = (0i32..4*100).map(|i| {
1229 }).collect::<Vec<_>>();
1233 while i < data.len() {
1234 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1241 pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1242 let data = (0i32..4*100+1).map(|i| {
1248 }).collect::<Vec<_>>();
1252 while i < data.len() {
1253 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;