(index<- )        ./libserialize/ebml.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Sat Apr 19 11:22:39 2014
    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.
    4  //
    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.
   10  
   11  #![allow(missing_doc)]
   12  
   13  use std::io;
   14  use std::str;
   15  
   16  // Simple Extensible Binary Markup Language (ebml) reader and writer on a
   17  // cursor model. See the specification here:
   18  //     http://www.matroska.org/technical/specs/rfc/index.html
   19  
   20  // Common data structures
   21  #[deriving(Clone)]
   22  pub struct Doc<'a> {
   23      pub data: &'a [u8],
   24      pub start: uint,
   25      pub end: uint,
   26  }
   27  
   28  impl<'doc> Doc<'doc> {
   29      pub fn get<'a>(&'a self, taguint) -> Doc<'a> {
   30          reader::get_doc(*self, tag)
   31      }
   32  
   33      pub fn as_str_slice<'a>(&'a self) -> &'a str {
   34          str::from_utf8(self.data.slice(self.start, self.end)).unwrap()
   35      }
   36  
   37      pub fn as_str(&self) -> ~str {
   38          self.as_str_slice().to_owned()
   39      }
   40  }
   41  
   42  pub struct TaggedDoc<'a> {
   43      tag: uint,
   44      pub doc: Doc<'a>,
   45  }
   46  
   47  pub enum EbmlEncoderTag {
   48      EsUint,     // 0
   49      EsU64,      // 1
   50      EsU32,      // 2
   51      EsU16,      // 3
   52      EsU8,       // 4
   53      EsInt,      // 5
   54      EsI64,      // 6
   55      EsI32,      // 7
   56      EsI16,      // 8
   57      EsI8,       // 9
   58      EsBool,     // 10
   59      EsChar,     // 11
   60      EsStr,      // 12
   61      EsF64,      // 13
   62      EsF32,      // 14
   63      EsFloat,    // 15
   64      EsEnum,     // 16
   65      EsEnumVid,  // 17
   66      EsEnumBody, // 18
   67      EsVec,      // 19
   68      EsVecLen,   // 20
   69      EsVecElt,   // 21
   70      EsMap,      // 22
   71      EsMapLen,   // 23
   72      EsMapKey,   // 24
   73      EsMapVal,   // 25
   74  
   75      EsOpaque,
   76  
   77      EsLabel, // Used only when debugging
   78  }
   79  
   80  #[deriving(Show)]
   81  pub enum Error {
   82      IntTooBig(uint),
   83      Expected(~str),
   84      IoError(io::IoError)
   85  }
   86  // --------------------------------------
   87  
   88  pub mod reader {
   89      use std::char;
   90  
   91      use std::cast::transmute;
   92      use std::int;
   93      use std::option::{None, Option, Some};
   94      use std::io::extensions::u64_from_be_bytes;
   95  
   96      use serialize;
   97  
   98      use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
   99          EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
  100          EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
  101          EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc, Error, IntTooBig,
  102          Expected };
  103  
  104      pub type DecodeResult<T> = Result<T, Error>;
  105      // ebml reading
  106  
  107      macro_rules! try_or(
  108          ($e:expr, $r:expr) => (
  109              match $e {
  110                  Ok(e) => e,
  111                  Err(e) => {
  112                      debug!("ignored error: {}", e);
  113                      return $r
  114                  }
  115              }
  116          )
  117      )
  118  
  119      pub struct Res {
  120          pub val: uint,
  121          pub next: uint
  122      }
  123  
  124      #[inline(never)]
  125      fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
  126          let a = data[start];
  127          if a & 0x80u8 != 0u8 {
  128              return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
  129          }
  130          if a & 0x40u8 != 0u8 {
  131              return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
  132                          (data[start + 1u] as uint),
  133                      next: start + 2u});
  134          }
  135          if a & 0x20u8 != 0u8 {
  136              return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
  137                          (data[start + 1u] as uint) << 8u |
  138                          (data[start + 2u] as uint),
  139                      next: start + 3u});
  140          }
  141          if a & 0x10u8 != 0u8 {
  142              return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
  143                          (data[start + 1u] as uint) << 16u |
  144                          (data[start + 2u] as uint) << 8u |
  145                          (data[start + 3u] as uint),
  146                      next: start + 4u});
  147          }
  148          Err(IntTooBig(a as uint))
  149      }
  150  
  151      pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
  152          use std::mem::from_be32;
  153  
  154          if data.len() - start < 4 {
  155              return vuint_at_slow(data, start);
  156          }
  157  
  158          // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
  159          // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
  160          // Using the four most significant bits of the u32 we lookup in the table below how the
  161          // element ID should be derived from it.
  162          //
  163          // The table stores tuples (shift, mask) where shift is the number the u32 should be right
  164          // shifted with and mask is the value the right shifted value should be masked with.
  165          // If for example the most significant bit is set this means it's a class A ID and the u32
  166          // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
  167          // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
  168          //
  169          // By storing the number of shifts and masks in a table instead of checking in order if
  170          // the most significant bit is set, the second most significant bit is set etc. we can
  171          // replace up to three "and+branch" with a single table lookup which gives us a measured
  172          // speedup of around 2x on x86_64.
  173          static SHIFT_MASK_TABLE: [(u32, u32), ..16] = [
  174              (0, 0x0), (0, 0x0fffffff),
  175              (8, 0x1fffff), (8, 0x1fffff),
  176              (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
  177              (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
  178              (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
  179          ];
  180  
  181          unsafe {
  182              let ptr = data.as_ptr().offset(start as int) as *u32;
  183              let val = from_be32(*ptr);
  184  
  185              let i = (val >> 28u) as uint;
  186              let (shift, mask) = SHIFT_MASK_TABLE[i];
  187              Ok(Res {
  188                  val: ((val >> shift) & mask) as uint,
  189                  next: start + (((32 - shift) >> 3) as uint)
  190              })
  191          }
  192      }
  193  
  194      pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> {
  195          Doc { data: data, start: 0u, end: data.len() }
  196      }
  197  
  198      pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
  199          let elt_tag = try!(vuint_at(data, start));
  200          let elt_size = try!(vuint_at(data, elt_tag.next));
  201          let end = elt_size.next + elt_size.val;
  202          Ok(TaggedDoc {
  203              tag: elt_tag.val,
  204              doc: Doc { data: data, start: elt_size.next, end: end }
  205          })
  206      }
  207  
  208      pub fn maybe_get_doc<'a>(dDoc<'a>, tg: uint) -> Option<Doc<'a>> {
  209          let mut pos = d.start;
  210          while pos < d.end {
  211              let elt_tag = try_or!(vuint_at(d.data, pos), None);
  212              let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
  213              pos = elt_size.next + elt_size.val;
  214              if elt_tag.val == tg {
  215                  return Some(Doc { data: d.data, start: elt_size.next,
  216                                    end: pos });
  217              }
  218          }
  219          None
  220      }
  221  
  222      pub fn get_doc<'a>(dDoc<'a>, tg: uint) -> Doc<'a> {
  223          match maybe_get_doc(d, tg) {
  224              Some(d) => d,
  225              None => {
  226                  error!("failed to find block with tag {}", tg);
  227                  fail!();
  228              }
  229          }
  230      }
  231  
  232      pub fn docs<'a>(dDoc<'a>, it: |uint, Doc<'a>-> bool) -> bool {
  233          let mut pos = d.start;
  234          while pos < d.end {
  235              let elt_tag = try_or!(vuint_at(d.data, pos), false);
  236              let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
  237              pos = elt_size.next + elt_size.val;
  238              let doc = Doc { data: d.data, start: elt_size.next, end: pos };
  239              if !it(elt_tag.val, doc) {
  240                  return false;
  241              }
  242          }
  243          return true;
  244      }
  245  
  246      pub fn tagged_docs<'a>(dDoc<'a>, tg: uint, it: |Doc<'a>-> bool) -> bool {
  247          let mut pos = d.start;
  248          while pos < d.end {
  249              let elt_tag = try_or!(vuint_at(d.data, pos), false);
  250              let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
  251              pos = elt_size.next + elt_size.val;
  252              if elt_tag.val == tg {
  253                  let doc = Doc { data: d.data, start: elt_size.next,
  254                                  end: pos };
  255                  if !it(doc) {
  256                      return false;
  257                  }
  258              }
  259          }
  260          return true;
  261      }
  262  
  263      pub fn with_doc_data<'a, T>(dDoc<'a>, f: |x: &'a [u8]-> T) -> T {
  264          f(d.data.slice(d.start, d.end))
  265      }
  266  
  267  
  268      pub fn doc_as_u8(dDoc) -> u8 {
  269          assert_eq!(d.end, d.start + 1u);
  270          d.data[d.start]
  271      }
  272  
  273      pub fn doc_as_u16(dDoc) -> u16 {
  274          assert_eq!(d.end, d.start + 2u);
  275          u64_from_be_bytes(d.data, d.start, 2u) as u16
  276      }
  277  
  278      pub fn doc_as_u32(dDoc) -> u32 {
  279          assert_eq!(d.end, d.start + 4u);
  280          u64_from_be_bytes(d.data, d.start, 4u) as u32
  281      }
  282  
  283      pub fn doc_as_u64(dDoc) -> u64 {
  284          assert_eq!(d.end, d.start + 8u);
  285          u64_from_be_bytes(d.data, d.start, 8u)
  286      }
  287  
  288      pub fn doc_as_i8(dDoc) -> i8 { doc_as_u8(d) as i8 }
  289      pub fn doc_as_i16(dDoc) -> i16 { doc_as_u16(d) as i16 }
  290      pub fn doc_as_i32(dDoc) -> i32 { doc_as_u32(d) as i32 }
  291      pub fn doc_as_i64(dDoc) -> i64 { doc_as_u64(d) as i64 }
  292  
  293      pub struct Decoder<'a> {
  294          parent: Doc<'a>,
  295          pos: uint,
  296      }
  297  
  298      pub fn Decoder<'a>(dDoc<'a>) -> Decoder<'a> {
  299          Decoder {
  300              parent: d,
  301              pos: d.start
  302          }
  303      }
  304  
  305      impl<'doc> Decoder<'doc> {
  306          fn _check_label(&mut self, lbl&str) -> DecodeResult<()> {
  307              if self.pos < self.parent.end {
  308                  let TaggedDoc { tag: r_tag, doc: r_doc } =
  309                      try!(doc_at(self.parent.data, self.pos));
  310  
  311                  if r_tag == (EsLabel as uint) {
  312                      self.pos = r_doc.end;
  313                      let str = r_doc.as_str_slice();
  314                      if lbl != str {
  315                          return Err(Expected(format!("Expected label {} but found {}", lbl, str)));
  316                      }
  317                  }
  318              }
  319              Ok(())
  320          }
  321  
  322          fn next_doc(&mut self, exp_tagEbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
  323              debug!(". next_doc(exp_tag={:?})", exp_tag);
  324              if self.pos >= self.parent.end {
  325                  return Err(Expected(format!("no more documents in current node!")));
  326              }
  327              let TaggedDoc { tag: r_tag, doc: r_doc } =
  328                  try!(doc_at(self.parent.data, self.pos));
  329              debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
  330                     self.parent.start,
  331                     self.parent.end,
  332                     self.pos,
  333                     r_tag,
  334                     r_doc.start,
  335                     r_doc.end);
  336              if r_tag != (exp_tag as uint) {
  337                  return Err(Expected(format!("expected EBML doc with tag {:?} but found tag {:?}",
  338                         exp_tag, r_tag)));
  339              }
  340              if r_doc.end > self.parent.end {
  341                  return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to {:#x}",
  342                        r_doc.end, self.parent.end)));
  343              }
  344              self.pos = r_doc.end;
  345              Ok(r_doc)
  346          }
  347  
  348          fn push_doc<T>(&mut self, exp_tagEbmlEncoderTag,
  349                         f|&mut Decoder<'doc>-> DecodeResult<T>) -> DecodeResult<T> {
  350              let d = try!(self.next_doc(exp_tag));
  351              let old_parent = self.parent;
  352              let old_pos = self.pos;
  353              self.parent = d;
  354              self.pos = d.start;
  355              let r = try!(f(self));
  356              self.parent = old_parent;
  357              self.pos = old_pos;
  358              Ok(r)
  359          }
  360  
  361          fn _next_uint(&mut self, exp_tagEbmlEncoderTag) -> DecodeResult<uint> {
  362              let r = doc_as_u32(try!(self.next_doc(exp_tag)));
  363              debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
  364              Ok(r as uint)
  365          }
  366  
  367          pub fn read_opaque<R>(&mut self,
  368                                op|&mut Decoder<'doc>, Doc-> DecodeResult<R>) -> DecodeResult<R> {
  369              let doc = try!(self.next_doc(EsOpaque));
  370  
  371              let (old_parent, old_pos) = (self.parent, self.pos);
  372              self.parent = doc;
  373              self.pos = doc.start;
  374  
  375              let result = try!(op(self, doc));
  376  
  377              self.parent = old_parent;
  378              self.pos = old_pos;
  379              Ok(result)
  380          }
  381      }
  382  
  383      impl<'doc> serialize::Decoder<Error> for Decoder<'doc> {
  384          fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
  385  
  386          fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
  387          fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
  388          fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
  389          fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
  390          fn read_uint(&mut self) -> DecodeResult<uint> {
  391              let v = doc_as_u64(try!(self.next_doc(EsUint)));
  392              if v > (::std::uint::MAX as u64) {
  393                  Err(IntTooBig(v as uint))
  394              } else {
  395                  Ok(v as uint)
  396              }
  397          }
  398  
  399          fn read_i64(&mut self) -> DecodeResult<i64> {
  400              Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
  401          }
  402          fn read_i32(&mut self) -> DecodeResult<i32> {
  403              Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
  404          }
  405          fn read_i16(&mut self) -> DecodeResult<i16> {
  406              Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
  407          }
  408          fn read_i8 (&mut self) -> DecodeResult<i8> {
  409              Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
  410          }
  411          fn read_int(&mut self) -> DecodeResult<int> {
  412              let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
  413              if v > (int::MAX as i64) || v < (int::MIN as i64) {
  414                  debug!("FIXME \\#6122: Removing this makes this function miscompile");
  415                  Err(IntTooBig(v as uint))
  416              } else {
  417                  Ok(v as int)
  418              }
  419          }
  420  
  421          fn read_bool(&mut self) -> DecodeResult<bool> {
  422              Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
  423          }
  424  
  425          fn read_f64(&mut self) -> DecodeResult<f64> {
  426              let bits = doc_as_u64(try!(self.next_doc(EsF64)));
  427              Ok(unsafe { transmute(bits) })
  428          }
  429          fn read_f32(&mut self) -> DecodeResult<f32> {
  430              let bits = doc_as_u32(try!(self.next_doc(EsF32)));
  431              Ok(unsafe { transmute(bits) })
  432          }
  433          fn read_char(&mut self) -> DecodeResult<char> {
  434              Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
  435          }
  436          fn read_str(&mut self) -> DecodeResult<~str> {
  437              Ok(try!(self.next_doc(EsStr)).as_str())
  438          }
  439  
  440          // Compound types:
  441          fn read_enum<T>(&mut self,
  442                          name&str,
  443                          f|&mut Decoder<'doc>-> DecodeResult<T>) -> DecodeResult<T> {
  444              debug!("read_enum({})", name);
  445              try!(self._check_label(name));
  446  
  447              let doc = try!(self.next_doc(EsEnum));
  448  
  449              let (old_parent, old_pos) = (self.parent, self.pos);
  450              self.parent = doc;
  451              self.pos = self.parent.start;
  452  
  453              let result = try!(f(self));
  454  
  455              self.parent = old_parent;
  456              self.pos = old_pos;
  457              Ok(result)
  458          }
  459  
  460          fn read_enum_variant<T>(&mut self,
  461                                  _&[&str],
  462                                  f|&mut Decoder<'doc>, uint| -> DecodeResult<T>)
  463                                  -> DecodeResult<T> {
  464              debug!("read_enum_variant()");
  465              let idx = try!(self._next_uint(EsEnumVid));
  466              debug!("  idx={}", idx);
  467  
  468              let doc = try!(self.next_doc(EsEnumBody));
  469  
  470              let (old_parent, old_pos) = (self.parent, self.pos);
  471              self.parent = doc;
  472              self.pos = self.parent.start;
  473  
  474              let result = try!(f(self, idx));
  475  
  476              self.parent = old_parent;
  477              self.pos = old_pos;
  478              Ok(result)
  479          }
  480  
  481          fn read_enum_variant_arg<T>(&mut self,
  482                                      idxuint,
  483                                      f|&mut Decoder<'doc>-> DecodeResult<T>) -> DecodeResult<T> {
  484              debug!("read_enum_variant_arg(idx={})", idx);
  485              f(self)
  486          }
  487  
  488          fn read_enum_struct_variant<T>(&mut self,
  489                                         _&[&str],
  490                                         f|&mut Decoder<'doc>, uint| -> DecodeResult<T>)
  491                                         -> DecodeResult<T> {
  492              debug!("read_enum_struct_variant()");
  493              let idx = try!(self._next_uint(EsEnumVid));
  494              debug!("  idx={}", idx);
  495  
  496              let doc = try!(self.next_doc(EsEnumBody));
  497  
  498              let (old_parent, old_pos) = (self.parent, self.pos);
  499              self.parent = doc;
  500              self.pos = self.parent.start;
  501  
  502              let result = try!(f(self, idx));
  503  
  504              self.parent = old_parent;
  505              self.pos = old_pos;
  506              Ok(result)
  507          }
  508  
  509          fn read_enum_struct_variant_field<T>(&mut self,
  510                                               name&str,
  511                                               idxuint,
  512                                               f|&mut Decoder<'doc>-> DecodeResult<T>)
  513                                               -> DecodeResult<T> {
  514              debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
  515              f(self)
  516          }
  517  
  518          fn read_struct<T>(&mut self,
  519                            name&str,
  520                            _uint,
  521                            f|&mut Decoder<'doc>-> DecodeResult<T>)
  522                            -> DecodeResult<T> {
  523              debug!("read_struct(name={})", name);
  524              f(self)
  525          }
  526  
  527          fn read_struct_field<T>(&mut self,
  528                                  name&str,
  529                                  idxuint,
  530                                  f|&mut Decoder<'doc>-> DecodeResult<T>)
  531                                  -> DecodeResult<T> {
  532              debug!("read_struct_field(name={}, idx={})", name, idx);
  533              try!(self._check_label(name));
  534              f(self)
  535          }
  536  
  537          fn read_tuple<T>(&mut self,
  538                           f|&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
  539              debug!("read_tuple()");
  540              self.read_seq(f)
  541          }
  542  
  543          fn read_tuple_arg<T>(&mut self, idxuint, f|&mut Decoder<'doc>-> DecodeResult<T>)
  544                               -> DecodeResult<T> {
  545              debug!("read_tuple_arg(idx={})", idx);
  546              self.read_seq_elt(idx, f)
  547          }
  548  
  549          fn read_tuple_struct<T>(&mut self,
  550                                  name&str,
  551                                  f|&mut Decoder<'doc>, uint| -> DecodeResult<T>)
  552                                  -> DecodeResult<T> {
  553              debug!("read_tuple_struct(name={})", name);
  554              self.read_tuple(f)
  555          }
  556  
  557          fn read_tuple_struct_arg<T>(&mut self,
  558                                      idxuint,
  559                                      f|&mut Decoder<'doc>-> DecodeResult<T>)
  560                                      -> DecodeResult<T> {
  561              debug!("read_tuple_struct_arg(idx={})", idx);
  562              self.read_tuple_arg(idx, f)
  563          }
  564  
  565          fn read_option<T>(&mut self,
  566                            f|&mut Decoder<'doc>, bool| -> DecodeResult<T>) -> DecodeResult<T> {
  567              debug!("read_option()");
  568              self.read_enum("Option", |this| {
  569                  this.read_enum_variant(["None", "Some"], |this, idx| {
  570                      match idx {
  571                          0 => f(this, false),
  572                          1 => f(this, true),
  573                          _ => Err(Expected(format!("Expected None or Some"))),
  574                      }
  575                  })
  576              })
  577          }
  578  
  579          fn read_seq<T>(&mut self,
  580                         f|&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
  581              debug!("read_seq()");
  582              self.push_doc(EsVec, |d| {
  583                  let len = try!(d._next_uint(EsVecLen));
  584                  debug!("  len={}", len);
  585                  f(d, len)
  586              })
  587          }
  588  
  589          fn read_seq_elt<T>(&mut self, idxuint, f|&mut Decoder<'doc>-> DecodeResult<T>)
  590                             -> DecodeResult<T> {
  591              debug!("read_seq_elt(idx={})", idx);
  592              self.push_doc(EsVecElt, f)
  593          }
  594  
  595          fn read_map<T>(&mut self,
  596                         f|&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
  597              debug!("read_map()");
  598              self.push_doc(EsMap, |d| {
  599                  let len = try!(d._next_uint(EsMapLen));
  600                  debug!("  len={}", len);
  601                  f(d, len)
  602              })
  603          }
  604  
  605          fn read_map_elt_key<T>(&mut self, idxuint, f|&mut Decoder<'doc>-> DecodeResult<T>)
  606                                 -> DecodeResult<T> {
  607              debug!("read_map_elt_key(idx={})", idx);
  608              self.push_doc(EsMapKey, f)
  609          }
  610  
  611          fn read_map_elt_val<T>(&mut self, idxuint, f|&mut Decoder<'doc>-> DecodeResult<T>)
  612                                 -> DecodeResult<T> {
  613              debug!("read_map_elt_val(idx={})", idx);
  614              self.push_doc(EsMapVal, f)
  615          }
  616      }
  617  }
  618  
  619  pub mod writer {
  620      use std::cast;
  621      use std::clone::Clone;
  622      use std::io;
  623      use std::io::{Writer, Seek};
  624      use std::io::extensions::u64_to_be_bytes;
  625  
  626      use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
  627          EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
  628          EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
  629          EsOpaque, EsLabel, EbmlEncoderTag };
  630  
  631      use serialize;
  632  
  633  
  634      pub type EncodeResult = io::IoResult<()>;
  635  
  636      // ebml writing
  637      pub struct Encoder<'a, W> {
  638          pub writer: &'a mut W,
  639          size_positions: Vec<uint>,
  640      }
  641  
  642      fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
  643          match size {
  644              1u => w.write(&[0x80u8 | (n as u8)]),
  645              2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
  646              3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
  647                              n as u8]),
  648              4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
  649                              (n >> 8_u) as u8, n as u8]),
  650              _ => Err(io::IoError {
  651                  kind: io::OtherIoError,
  652                  desc: "int too big",
  653                  detail: Some(format!("{}", n))
  654              })
  655          }
  656      }
  657  
  658      fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
  659          if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
  660          if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
  661          if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
  662          if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
  663          Err(io::IoError {
  664              kind: io::OtherIoError,
  665              desc: "int too big",
  666              detail: Some(format!("{}", n))
  667          })
  668      }
  669  
  670      pub fn Encoder<'a, W: Writer + Seek>(w: &'a mut W) -> Encoder<'a, W> {
  671          Encoder {
  672              writer: w,
  673              size_positions: vec!(),
  674          }
  675      }
  676  
  677      // FIXME (#2741): Provide a function to write the standard ebml header.
  678      impl<'a, W: Writer + Seek> Encoder<'a, W> {
  679          /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
  680          pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
  681              Encoder {
  682                  writer: cast::transmute_copy(&self.writer),
  683                  size_positions: self.size_positions.clone(),
  684              }
  685          }
  686  
  687          pub fn start_tag(&mut self, tag_iduint) -> EncodeResult {
  688              debug!("Start tag {}", tag_id);
  689  
  690              // Write the enum ID:
  691              try!(write_vuint(self.writer, tag_id));
  692  
  693              // Write a placeholder four-byte size.
  694              self.size_positions.push(try!(self.writer.tell()) as uint);
  695              let zeroes&[u8] = &[0u8, 0u8, 0u8, 0u8];
  696              self.writer.write(zeroes)
  697          }
  698  
  699          pub fn end_tag(&mut self) -> EncodeResult {
  700              let last_size_pos = self.size_positions.pop().unwrap();
  701              let cur_pos = try!(self.writer.tell());
  702              try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
  703              let size = cur_pos as uint - last_size_pos - 4;
  704              try!(write_sized_vuint(self.writer, size, 4u));
  705              let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
  706  
  707              debug!("End tag (size = {})", size);
  708              Ok(r)
  709          }
  710  
  711          pub fn wr_tag(&mut self, tag_iduint, blk|| -> EncodeResult) -> EncodeResult {
  712              try!(self.start_tag(tag_id));
  713              try!(blk());
  714              self.end_tag()
  715          }
  716  
  717          pub fn wr_tagged_bytes(&mut self, tag_iduint, b&[u8]) -> EncodeResult {
  718              try!(write_vuint(self.writer, tag_id));
  719              try!(write_vuint(self.writer, b.len()));
  720              self.writer.write(b)
  721          }
  722  
  723          pub fn wr_tagged_u64(&mut self, tag_iduint, vu64) -> EncodeResult {
  724              u64_to_be_bytes(v, 8u, |v| {
  725                  self.wr_tagged_bytes(tag_id, v)
  726              })
  727          }
  728  
  729          pub fn wr_tagged_u32(&mut self, tag_iduint, vu32)  -> EncodeResult{
  730              u64_to_be_bytes(v as u64, 4u, |v| {
  731                  self.wr_tagged_bytes(tag_id, v)
  732              })
  733          }
  734  
  735          pub fn wr_tagged_u16(&mut self, tag_iduint, vu16) -> EncodeResult {
  736              u64_to_be_bytes(v as u64, 2u, |v| {
  737                  self.wr_tagged_bytes(tag_id, v)
  738              })
  739          }
  740  
  741          pub fn wr_tagged_u8(&mut self, tag_iduint, vu8) -> EncodeResult {
  742              self.wr_tagged_bytes(tag_id, &[v])
  743          }
  744  
  745          pub fn wr_tagged_i64(&mut self, tag_iduint, vi64) -> EncodeResult {
  746              u64_to_be_bytes(v as u64, 8u, |v| {
  747                  self.wr_tagged_bytes(tag_id, v)
  748              })
  749          }
  750  
  751          pub fn wr_tagged_i32(&mut self, tag_iduint, vi32) -> EncodeResult {
  752              u64_to_be_bytes(v as u64, 4u, |v| {
  753                  self.wr_tagged_bytes(tag_id, v)
  754              })
  755          }
  756  
  757          pub fn wr_tagged_i16(&mut self, tag_iduint, vi16) -> EncodeResult {
  758              u64_to_be_bytes(v as u64, 2u, |v| {
  759                  self.wr_tagged_bytes(tag_id, v)
  760              })
  761          }
  762  
  763          pub fn wr_tagged_i8(&mut self, tag_iduint, vi8) -> EncodeResult {
  764              self.wr_tagged_bytes(tag_id, &[v as u8])
  765          }
  766  
  767          pub fn wr_tagged_str(&mut self, tag_iduint, v&str) -> EncodeResult {
  768              self.wr_tagged_bytes(tag_id, v.as_bytes())
  769          }
  770  
  771          pub fn wr_bytes(&mut self, b&[u8]) -> EncodeResult {
  772              debug!("Write {} bytes", b.len());
  773              self.writer.write(b)
  774          }
  775  
  776          pub fn wr_str(&mut self, s&str) -> EncodeResult {
  777              debug!("Write str: {}", s);
  778              self.writer.write(s.as_bytes())
  779          }
  780      }
  781  
  782      // FIXME (#2743): optionally perform "relaxations" on end_tag to more
  783      // efficiently encode sizes; this is a fixed point iteration
  784  
  785      // Set to true to generate more debugging in EBML code.
  786      // Totally lame approach.
  787      static DEBUG: bool = true;
  788  
  789      impl<'a, W: Writer + Seek> Encoder<'a, W> {
  790          // used internally to emit things like the vector length and so on
  791          fn _emit_tagged_uint(&mut self, tEbmlEncoderTag, vuint) -> EncodeResult {
  792              assert!(v <= 0xFFFF_FFFF_u);
  793              self.wr_tagged_u32(t as uint, v as u32)
  794          }
  795  
  796          fn _emit_label(&mut self, label&str) -> EncodeResult {
  797              // There are various strings that we have access to, such as
  798              // the name of a record field, which do not actually appear in
  799              // the encoded EBML (normally).  This is just for
  800              // efficiency.  When debugging, though, we can emit such
  801              // labels and then they will be checked by decoder to
  802              // try and check failures more quickly.
  803              if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
  804              else { Ok(()) }
  805          }
  806  
  807          pub fn emit_opaque(&mut self, f|&mut Encoder<W>-> EncodeResult) -> EncodeResult {
  808              try!(self.start_tag(EsOpaque as uint));
  809              try!(f(self));
  810              self.end_tag()
  811          }
  812      }
  813  
  814      impl<'a, W: Writer + Seek> serialize::Encoder<io::IoError> for Encoder<'a, W> {
  815          fn emit_nil(&mut self) -> EncodeResult {
  816              Ok(())
  817          }
  818  
  819          fn emit_uint(&mut self, vuint) -> EncodeResult {
  820              self.wr_tagged_u64(EsUint as uint, v as u64)
  821          }
  822          fn emit_u64(&mut self, vu64) -> EncodeResult {
  823              self.wr_tagged_u64(EsU64 as uint, v)
  824          }
  825          fn emit_u32(&mut self, vu32) -> EncodeResult {
  826              self.wr_tagged_u32(EsU32 as uint, v)
  827          }
  828          fn emit_u16(&mut self, vu16) -> EncodeResult {
  829              self.wr_tagged_u16(EsU16 as uint, v)
  830          }
  831          fn emit_u8(&mut self, vu8) -> EncodeResult {
  832              self.wr_tagged_u8(EsU8 as uint, v)
  833          }
  834  
  835          fn emit_int(&mut self, vint) -> EncodeResult {
  836              self.wr_tagged_i64(EsInt as uint, v as i64)
  837          }
  838          fn emit_i64(&mut self, vi64) -> EncodeResult {
  839              self.wr_tagged_i64(EsI64 as uint, v)
  840          }
  841          fn emit_i32(&mut self, vi32) -> EncodeResult {
  842              self.wr_tagged_i32(EsI32 as uint, v)
  843          }
  844          fn emit_i16(&mut self, vi16) -> EncodeResult {
  845              self.wr_tagged_i16(EsI16 as uint, v)
  846          }
  847          fn emit_i8(&mut self, vi8) -> EncodeResult {
  848              self.wr_tagged_i8(EsI8 as uint, v)
  849          }
  850  
  851          fn emit_bool(&mut self, vbool) -> EncodeResult {
  852              self.wr_tagged_u8(EsBool as uint, v as u8)
  853          }
  854  
  855          fn emit_f64(&mut self, vf64) -> EncodeResult {
  856              let bits = unsafe { cast::transmute(v) };
  857              self.wr_tagged_u64(EsF64 as uint, bits)
  858          }
  859          fn emit_f32(&mut self, vf32) -> EncodeResult {
  860              let bits = unsafe { cast::transmute(v) };
  861              self.wr_tagged_u32(EsF32 as uint, bits)
  862          }
  863          fn emit_char(&mut self, vchar) -> EncodeResult {
  864              self.wr_tagged_u32(EsChar as uint, v as u32)
  865          }
  866  
  867          fn emit_str(&mut self, v&str) -> EncodeResult {
  868              self.wr_tagged_str(EsStr as uint, v)
  869          }
  870  
  871          fn emit_enum(&mut self,
  872                       name&str,
  873                       f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  874              try!(self._emit_label(name));
  875              try!(self.start_tag(EsEnum as uint));
  876              try!(f(self));
  877              self.end_tag()
  878          }
  879  
  880          fn emit_enum_variant(&mut self,
  881                               _&str,
  882                               v_iduint,
  883                               _uint,
  884                               f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  885              try!(self._emit_tagged_uint(EsEnumVid, v_id));
  886              try!(self.start_tag(EsEnumBody as uint));
  887              try!(f(self));
  888              self.end_tag()
  889          }
  890  
  891          fn emit_enum_variant_arg(&mut self,
  892                                   _uint,
  893                                   f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  894              f(self)
  895          }
  896  
  897          fn emit_enum_struct_variant(&mut self,
  898                                      v_name&str,
  899                                      v_iduint,
  900                                      cntuint,
  901                                      f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  902              self.emit_enum_variant(v_name, v_id, cnt, f)
  903          }
  904  
  905          fn emit_enum_struct_variant_field(&mut self,
  906                                            _&str,
  907                                            idxuint,
  908                                            f|&mut Encoder<'a, W>-> EncodeResult)
  909              -> EncodeResult {
  910              self.emit_enum_variant_arg(idx, f)
  911          }
  912  
  913          fn emit_struct(&mut self,
  914                         _&str,
  915                         _lenuint,
  916                         f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  917              f(self)
  918          }
  919  
  920          fn emit_struct_field(&mut self,
  921                               name&str,
  922                               _uint,
  923                               f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  924              try!(self._emit_label(name));
  925              f(self)
  926          }
  927  
  928          fn emit_tuple(&mut self,
  929                        lenuint,
  930                        f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  931              self.emit_seq(len, f)
  932          }
  933          fn emit_tuple_arg(&mut self,
  934                            idxuint,
  935                            f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  936              self.emit_seq_elt(idx, f)
  937          }
  938  
  939          fn emit_tuple_struct(&mut self,
  940                               _&str,
  941                               lenuint,
  942                               f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  943              self.emit_seq(len, f)
  944          }
  945          fn emit_tuple_struct_arg(&mut self,
  946                                   idxuint,
  947                                   f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  948              self.emit_seq_elt(idx, f)
  949          }
  950  
  951          fn emit_option(&mut self,
  952                         f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  953              self.emit_enum("Option", f)
  954          }
  955          fn emit_option_none(&mut self) -> EncodeResult {
  956              self.emit_enum_variant("None", 0, 0, |_| Ok(()))
  957          }
  958          fn emit_option_some(&mut self,
  959                              f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  960  
  961              self.emit_enum_variant("Some", 1, 1, f)
  962          }
  963  
  964          fn emit_seq(&mut self,
  965                      lenuint,
  966                      f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  967  
  968              try!(self.start_tag(EsVec as uint));
  969              try!(self._emit_tagged_uint(EsVecLen, len));
  970              try!(f(self));
  971              self.end_tag()
  972          }
  973  
  974          fn emit_seq_elt(&mut self,
  975                          _idxuint,
  976                          f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  977  
  978              try!(self.start_tag(EsVecElt as uint));
  979              try!(f(self));
  980              self.end_tag()
  981          }
  982  
  983          fn emit_map(&mut self,
  984                      lenuint,
  985                      f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  986  
  987              try!(self.start_tag(EsMap as uint));
  988              try!(self._emit_tagged_uint(EsMapLen, len));
  989              try!(f(self));
  990              self.end_tag()
  991          }
  992  
  993          fn emit_map_elt_key(&mut self,
  994                              _idxuint,
  995                              f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
  996  
  997              try!(self.start_tag(EsMapKey as uint));
  998              try!(f(self));
  999              self.end_tag()
 1000          }
 1001  
 1002          fn emit_map_elt_val(&mut self,
 1003                              _idxuint,
 1004                              f|&mut Encoder<'a, W>-> EncodeResult) -> EncodeResult {
 1005              try!(self.start_tag(EsMapVal as uint));
 1006              try!(f(self));
 1007              self.end_tag()
 1008          }
 1009      }
 1010  }
 1011  
 1012  // ___________________________________________________________________________
 1013  // Testing
 1014  
 1015  #[cfg(test)]
 1016  mod tests {
 1017      use ebml::reader;
 1018      use ebml::writer;
 1019      use {Encodable, Decodable};
 1020  
 1021      use std::io::MemWriter;
 1022      use std::option::{None, Option, Some};
 1023  
 1024      #[test]
 1025      fn test_vuint_at() {
 1026          let data = [
 1027              0x80,
 1028              0xff,
 1029              0x40, 0x00,
 1030              0x7f, 0xff,
 1031              0x20, 0x00, 0x00,
 1032              0x3f, 0xff, 0xff,
 1033              0x10, 0x00, 0x00, 0x00,
 1034              0x1f, 0xff, 0xff, 0xff
 1035          ];
 1036  
 1037          let mut res: reader::Res;
 1038  
 1039          // Class A
 1040          res = reader::vuint_at(data, 0).unwrap();
 1041          assert_eq!(res.val, 0);
 1042          assert_eq!(res.next, 1);
 1043          res = reader::vuint_at(data, res.next).unwrap();
 1044          assert_eq!(res.val, (1 << 7) - 1);
 1045          assert_eq!(res.next, 2);
 1046  
 1047          // Class B
 1048          res = reader::vuint_at(data, res.next).unwrap();
 1049          assert_eq!(res.val, 0);
 1050          assert_eq!(res.next, 4);
 1051          res = reader::vuint_at(data, res.next).unwrap();
 1052          assert_eq!(res.val, (1 << 14) - 1);
 1053          assert_eq!(res.next, 6);
 1054  
 1055          // Class C
 1056          res = reader::vuint_at(data, res.next).unwrap();
 1057          assert_eq!(res.val, 0);
 1058          assert_eq!(res.next, 9);
 1059          res = reader::vuint_at(data, res.next).unwrap();
 1060          assert_eq!(res.val, (1 << 21) - 1);
 1061          assert_eq!(res.next, 12);
 1062  
 1063          // Class D
 1064          res = reader::vuint_at(data, res.next).unwrap();
 1065          assert_eq!(res.val, 0);
 1066          assert_eq!(res.next, 16);
 1067          res = reader::vuint_at(data, res.next).unwrap();
 1068          assert_eq!(res.val, (1 << 28) - 1);
 1069          assert_eq!(res.next, 20);
 1070      }
 1071  
 1072      #[test]
 1073      fn test_option_int() {
 1074          fn test_v(v: Option<int>) {
 1075              debug!("v == {:?}", v);
 1076              let mut wr = MemWriter::new();
 1077              {
 1078                  let mut ebml_w = writer::Encoder(&mut wr);
 1079                  let _ = v.encode(&mut ebml_w);
 1080              }
 1081              let ebml_doc = reader::Doc(wr.get_ref());
 1082              let mut deser = reader::Decoder(ebml_doc);
 1083              let v1 = Decodable::decode(&mut deser).unwrap();
 1084              debug!("v1 == {:?}", v1);
 1085              assert_eq!(v, v1);
 1086          }
 1087  
 1088          test_v(Some(22));
 1089          test_v(None);
 1090          test_v(Some(3));
 1091      }
 1092  }
 1093  
 1094  #[cfg(test)]
 1095  mod bench {
 1096      extern crate test;
 1097      use self::test::Bencher;
 1098      use ebml::reader;
 1099  
 1100      #[bench]
 1101      pub fn vuint_at_A_aligned(b: &mut Bencher) {
 1102          let data = Vec::from_fn(4*100, |i| {
 1103              match i % 2 {
 1104                0 => 0x80u8,
 1105                _ => i as u8,
 1106              }
 1107          });
 1108          let mut sum = 0u;
 1109          b.iter(|| {
 1110              let mut i = 0;
 1111              while i < data.len() {
 1112                  sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
 1113                  i += 4;
 1114              }
 1115          });
 1116      }
 1117  
 1118      #[bench]
 1119      pub fn vuint_at_A_unaligned(b: &mut Bencher) {
 1120          let data = Vec::from_fn(4*100+1, |i| {
 1121              match i % 2 {
 1122                1 => 0x80u8,
 1123                _ => i as u8
 1124              }
 1125          });
 1126          let mut sum = 0u;
 1127          b.iter(|| {
 1128              let mut i = 1;
 1129              while i < data.len() {
 1130                  sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
 1131                  i += 4;
 1132              }
 1133          });
 1134      }
 1135  
 1136      #[bench]
 1137      pub fn vuint_at_D_aligned(b: &mut Bencher) {
 1138          let data = Vec::from_fn(4*100, |i| {
 1139              match i % 4 {
 1140                0 => 0x10u8,
 1141                3 => i as u8,
 1142                _ => 0u8
 1143              }
 1144          });
 1145          let mut sum = 0u;
 1146          b.iter(|| {
 1147              let mut i = 0;
 1148              while i < data.len() {
 1149                  sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
 1150                  i += 4;
 1151              }
 1152          });
 1153      }
 1154  
 1155      #[bench]
 1156      pub fn vuint_at_D_unaligned(b: &mut Bencher) {
 1157          let data = Vec::from_fn(4*100+1, |i| {
 1158              match i % 4 {
 1159                1 => 0x10u8,
 1160                0 => i as u8,
 1161                _ => 0u8
 1162              }
 1163          });
 1164          let mut sum = 0u;
 1165          b.iter(|| {
 1166              let mut i = 1;
 1167              while i < data.len() {
 1168                  sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
 1169                  i += 4;
 1170              }
 1171          });
 1172      }
 1173  }


libserialize/ebml.rs:642:4-642:4 -fn- definition:
    fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
        match size {
            1u => w.write(&[0x80u8 | (n as u8)]),
references:- 5
659:         if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
660:         if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
661:         if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
--
703:             let size = cur_pos as uint - last_size_pos - 4;
704:             try!(write_sized_vuint(self.writer, size, 4u));
705:             let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));


libserialize/ebml.rs:21:19-21:19 -struct- definition:
pub struct Doc<'a> {
    pub data: &'a [u8],
    pub start: uint,
references:- 34


libserialize/ebml.rs:104:4-104:4 -NK_AS_STR_TODO- definition:
    pub type DecodeResult<T> = Result<T, Error>;
    // ebml reading
    macro_rules! try_or(
references:- 60


libserialize/ebml.rs:283:4-283:4 -fn- definition:
    pub fn doc_as_u64(d: Doc) -> u64 {
        assert_eq!(d.end, d.start + 8u);
        u64_from_be_bytes(d.data, d.start, 8u)
references:- 6
386:         fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
387:         fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
--
411:         fn read_int(&mut self) -> DecodeResult<int> {
412:             let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
413:             if v > (int::MAX as i64) || v < (int::MIN as i64) {
--
425:         fn read_f64(&mut self) -> DecodeResult<f64> {
426:             let bits = doc_as_u64(try!(self.next_doc(EsF64)));
427:             Ok(unsafe { transmute(bits) })


libserialize/ebml.rs:637:4-637:4 -struct- definition:
    pub struct Encoder<'a, W> {
        pub writer: &'a mut W,
        size_positions: Vec<uint>,
references:- 26
670:     pub fn Encoder<'a, W: Writer + Seek>(w: &'a mut W) -> Encoder<'a, W> {
671:         Encoder {
672:             writer: w,
--
680:         pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
681:             Encoder {
682:                 writer: cast::transmute_copy(&self.writer),
--
814:     impl<'a, W: Writer + Seek> serialize::Encoder<io::IoError> for Encoder<'a, W> {
815:         fn emit_nil(&mut self) -> EncodeResult {
--
934:                           idx: uint,
935:                           f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
936:             self.emit_seq_elt(idx, f)
--
958:         fn emit_option_some(&mut self,
959:                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
--
1003:                             _idx: uint,
1004:                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
1005:             try!(self.start_tag(EsMapVal as uint));


libserialize/ebml.rs:293:4-293:4 -struct- definition:
    pub struct Decoder<'a> {
        parent: Doc<'a>,
        pos: uint,
references:- 23
298:     pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> {
299:         Decoder {
300:             parent: d,
--
595:         fn read_map<T>(&mut self,
596:                        f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
597:             debug!("read_map()");
--
605:         fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
606:                                -> DecodeResult<T> {
--
611:         fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
612:                                -> DecodeResult<T> {


libserialize/ebml.rs:634:4-634:4 -NK_AS_STR_TODO- definition:
    pub type EncodeResult = io::IoResult<()>;
    // ebml writing
    pub struct Encoder<'a, W> {
references:- 75


libserialize/ebml.rs:151:4-151:4 -fn- definition:
    pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
        use std::mem::from_be32;
        if data.len() - start < 4 {
references:- 8
198:     pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
199:         let elt_tag = try!(vuint_at(data, start));
200:         let elt_size = try!(vuint_at(data, elt_tag.next));
--
248:         while pos < d.end {
249:             let elt_tag = try_or!(vuint_at(d.data, pos), false);
250:             let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
251:             pos = elt_size.next + elt_size.val;


libserialize/ebml.rs:46:1-46:1 -enum- definition:
pub enum EbmlEncoderTag {
    EsUint,     // 0
    EsU64,      // 1
references:- 4
361:         fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
362:             let r = doc_as_u32(try!(self.next_doc(exp_tag)));
--
790:         // used internally to emit things like the vector length and so on
791:         fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
792:             assert!(v <= 0xFFFF_FFFF_u);


libserialize/ebml.rs:268:4-268:4 -fn- definition:
    pub fn doc_as_u8(d: Doc) -> u8 {
        assert_eq!(d.end, d.start + 1u);
        d.data[d.start]
references:- 4
421:         fn read_bool(&mut self) -> DecodeResult<bool> {
422:             Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
423:         }


libserialize/ebml.rs:273:4-273:4 -fn- definition:
    pub fn doc_as_u16(d: Doc) -> u16 {
        assert_eq!(d.end, d.start + 2u);
        u64_from_be_bytes(d.data, d.start, 2u) as u16
references:- 3
387:         fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
388:         fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
389:         fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
--
405:         fn read_i16(&mut self) -> DecodeResult<i16> {
406:             Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
407:         }


libserialize/ebml.rs:41:1-41:1 -struct- definition:
pub struct TaggedDoc<'a> {
    tag: uint,
    pub doc: Doc<'a>,
references:- 4
201:         let end = elt_size.next + elt_size.val;
202:         Ok(TaggedDoc {
203:             tag: elt_tag.val,
--
326:             }
327:             let TaggedDoc { tag: r_tag, doc: r_doc } =
328:                 try!(doc_at(self.parent.data, self.pos));


libserialize/ebml.rs:80:18-80:18 -enum- definition:
pub enum Error {
    IntTooBig(uint),
    Expected(~str),
references:- 3
104:     pub type DecodeResult<T> = Result<T, Error>;
105:     // ebml reading
--
383:     impl<'doc> serialize::Decoder<Error> for Decoder<'doc> {
384:         fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }


libserialize/ebml.rs:658:4-658:4 -fn- definition:
    fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
        if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
        if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
references:- 3
717:         pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
718:             try!(write_vuint(self.writer, tag_id));
719:             try!(write_vuint(self.writer, b.len()));
720:             self.writer.write(b)


libserialize/ebml.rs:119:4-119:4 -struct- definition:
    pub struct Res {
        pub val: uint,
        pub next: uint
references:- 7
135:         if a & 0x20u8 != 0u8 {
136:             return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
137:                         (data[start + 1u] as uint) << 8u |
--
141:         if a & 0x10u8 != 0u8 {
142:             return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
143:                         (data[start + 1u] as uint) << 16u |
--
186:             let (shift, mask) = SHIFT_MASK_TABLE[i];
187:             Ok(Res {
188:                 val: ((val >> shift) & mask) as uint,


libserialize/ebml.rs:198:4-198:4 -fn- definition:
    pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
        let elt_tag = try!(vuint_at(data, start));
        let elt_size = try!(vuint_at(data, elt_tag.next));
references:- 2
327:             let TaggedDoc { tag: r_tag, doc: r_doc } =
328:                 try!(doc_at(self.parent.data, self.pos));
329:             debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",


libserialize/ebml.rs:278:4-278:4 -fn- definition:
    pub fn doc_as_u32(d: Doc) -> u32 {
        assert_eq!(d.end, d.start + 4u);
        u64_from_be_bytes(d.data, d.start, 4u) as u32
references:- 6
361:         fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
362:             let r = doc_as_u32(try!(self.next_doc(exp_tag)));
363:             debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
--
433:         fn read_char(&mut self) -> DecodeResult<char> {
434:             Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
435:         }