diff options
| author | Jeff Olson <olson.jeffery@gmail.com> | 2014-02-05 08:52:54 -0800 |
|---|---|---|
| committer | Jeff Olson <olson.jeffery@gmail.com> | 2014-02-05 10:38:22 -0800 |
| commit | b8852e89ced0a0cdf66963aba08382ff18fd2d4b (patch) | |
| tree | 436f978485e7ceb1fc7daa36ab999afcdea30193 /src/libextra | |
| parent | 2bf575c86fd3c053df83b90862441fec71c7a622 (diff) | |
| download | rust-b8852e89ced0a0cdf66963aba08382ff18fd2d4b.tar.gz rust-b8852e89ced0a0cdf66963aba08382ff18fd2d4b.zip | |
pull extra::{serialize, ebml} into a separate libserialize crate
- `extra::json` didn't make the cut, because of `extra::json` required dep on `extra::TreeMap`. If/when `extra::TreeMap` moves out of `extra`, then `extra::json` could move into `serialize` - `libextra`, `libsyntax` and `librustc` depend on the newly created `libserialize` - The extensions to various `extra` types like `DList`, `RingBuf`, `TreeMap` and `TreeSet` for `Encodable`/`Decodable` were moved into the respective modules in `extra` - There is some trickery, evident in `src/libextra/lib.rs` where a stub of `extra::serialize` is set up (in `src/libextra/serialize.rs`) for use in the stage0 build, where the snapshot rustc is still making deriving for `Encodable` and `Decodable` point at extra. Big props to @huonw for help working out the re-export solution for this extra: inline extra::serialize stub fix stuff clobbered in rebase + don't reexport serialize::serialize no more globs in libserialize syntax: fix import of libserialize traits librustc: fix bad imports in encoder/decoder add serialize dep to librustdoc fix failing run-pass tests w/ serialize dep adjust uuid dep more rebase de-clobbering for libserialize fixing tests, pushing libextra dep into cfg(test) fix doc code in extra::json adjust index.md links to serialize and uuid library
Diffstat (limited to 'src/libextra')
| -rw-r--r-- | src/libextra/dlist.rs | 27 | ||||
| -rw-r--r-- | src/libextra/ebml.rs | 1113 | ||||
| -rw-r--r-- | src/libextra/json.rs | 22 | ||||
| -rw-r--r-- | src/libextra/lib.rs | 13 | ||||
| -rw-r--r-- | src/libextra/ringbuf.rs | 27 | ||||
| -rw-r--r-- | src/libextra/serialize.rs | 883 | ||||
| -rw-r--r-- | src/libextra/treemap.rs | 67 |
7 files changed, 145 insertions, 2007 deletions
diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index ee80fa1c4c4..88df73845d0 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -30,6 +30,8 @@ use std::iter; use container::Deque; +use serialize::{Encodable, Decodable, Encoder, Decoder}; + /// A doubly-linked list. pub struct DList<T> { priv length: uint, @@ -628,6 +630,31 @@ impl<A: Clone> Clone for DList<A> { } } +impl< + S: Encoder, + T: Encodable<S> +> Encodable<S> for DList<T> { + fn encode(&self, s: &mut S) { + s.emit_seq(self.len(), |s| { + for (i, e) in self.iter().enumerate() { + s.emit_seq_elt(i, |s| e.encode(s)); + } + }) + } +} + +impl<D:Decoder,T:Decodable<D>> Decodable<D> for DList<T> { + fn decode(d: &mut D) -> DList<T> { + let mut list = DList::new(); + d.read_seq(|d, len| { + for i in range(0u, len) { + list.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))); + } + }); + list + } +} + #[cfg(test)] mod tests { use container::Deque; diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs deleted file mode 100644 index 1900313ab6c..00000000000 --- a/src/libextra/ebml.rs +++ /dev/null @@ -1,1113 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[allow(missing_doc)]; - -use std::str; - -macro_rules! if_ok( ($e:expr) => ( - match $e { Ok(e) => e, Err(e) => { self.last_error = Err(e); return } } -) ) - -// Simple Extensible Binary Markup Language (ebml) reader and writer on a -// cursor model. See the specification here: -// http://www.matroska.org/technical/specs/rfc/index.html - -// Common data structures -#[deriving(Clone)] -pub struct Doc<'a> { - data: &'a [u8], - start: uint, - end: uint, -} - -impl<'doc> Doc<'doc> { - pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> { - reader::get_doc(*self, tag) - } - - pub fn as_str_slice<'a>(&'a self) -> &'a str { - str::from_utf8(self.data.slice(self.start, self.end)).unwrap() - } - - pub fn as_str(&self) -> ~str { - self.as_str_slice().to_owned() - } -} - -pub struct TaggedDoc<'a> { - priv tag: uint, - doc: Doc<'a>, -} - -pub enum EbmlEncoderTag { - EsUint, // 0 - EsU64, // 1 - EsU32, // 2 - EsU16, // 3 - EsU8, // 4 - EsInt, // 5 - EsI64, // 6 - EsI32, // 7 - EsI16, // 8 - EsI8, // 9 - EsBool, // 10 - EsChar, // 11 - EsStr, // 12 - EsF64, // 13 - EsF32, // 14 - EsFloat, // 15 - EsEnum, // 16 - EsEnumVid, // 17 - EsEnumBody, // 18 - EsVec, // 19 - EsVecLen, // 20 - EsVecElt, // 21 - EsMap, // 22 - EsMapLen, // 23 - EsMapKey, // 24 - EsMapVal, // 25 - - EsOpaque, - - EsLabel, // Used only when debugging -} -// -------------------------------------- - -pub mod reader { - use std::char; - use super::*; - - use serialize; - - use std::cast::transmute; - use std::int; - use std::option::{None, Option, Some}; - use std::io::extensions::u64_from_be_bytes; - - // ebml reading - - pub struct Res { - val: uint, - next: uint - } - - #[inline(never)] - fn vuint_at_slow(data: &[u8], start: uint) -> Res { - let a = data[start]; - if a & 0x80u8 != 0u8 { - return Res {val: (a & 0x7fu8) as uint, next: start + 1u}; - } - if a & 0x40u8 != 0u8 { - return Res {val: ((a & 0x3fu8) as uint) << 8u | - (data[start + 1u] as uint), - next: start + 2u}; - } - if a & 0x20u8 != 0u8 { - return Res {val: ((a & 0x1fu8) as uint) << 16u | - (data[start + 1u] as uint) << 8u | - (data[start + 2u] as uint), - next: start + 3u}; - } - if a & 0x10u8 != 0u8 { - return Res {val: ((a & 0x0fu8) as uint) << 24u | - (data[start + 1u] as uint) << 16u | - (data[start + 2u] as uint) << 8u | - (data[start + 3u] as uint), - next: start + 4u}; - } - fail!("vint too big"); - } - - pub fn vuint_at(data: &[u8], start: uint) -> Res { - use std::ptr::offset; - use std::unstable::intrinsics::from_be32; - - if data.len() - start < 4 { - return vuint_at_slow(data, start); - } - - // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/ - // The Element IDs are parsed by reading a big endian u32 positioned at data[start]. - // Using the four most significant bits of the u32 we lookup in the table below how the - // element ID should be derived from it. - // - // The table stores tuples (shift, mask) where shift is the number the u32 should be right - // shifted with and mask is the value the right shifted value should be masked with. - // If for example the most significant bit is set this means it's a class A ID and the u32 - // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at - // index 0x8 - 0xF (four bit numbers where the most significant bit is set). - // - // By storing the number of shifts and masks in a table instead of checking in order if - // the most significant bit is set, the second most significant bit is set etc. we can - // replace up to three "and+branch" with a single table lookup which gives us a measured - // speedup of around 2x on x86_64. - static SHIFT_MASK_TABLE: [(u32, u32), ..16] = [ - (0, 0x0), (0, 0x0fffffff), - (8, 0x1fffff), (8, 0x1fffff), - (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), - (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f), - (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f) - ]; - - unsafe { - let (ptr, _): (*u8, uint) = transmute(data); - let ptr = offset(ptr, start as int); - let ptr: *i32 = transmute(ptr); - let val = from_be32(*ptr) as u32; - - let i = (val >> 28u) as uint; - let (shift, mask) = SHIFT_MASK_TABLE[i]; - Res { - val: ((val >> shift) & mask) as uint, - next: start + (((32 - shift) >> 3) as uint) - } - } - } - - pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> { - Doc { data: data, start: 0u, end: data.len() } - } - - pub fn doc_at<'a>(data: &'a [u8], start: uint) -> TaggedDoc<'a> { - let elt_tag = vuint_at(data, start); - let elt_size = vuint_at(data, elt_tag.next); - let end = elt_size.next + elt_size.val; - TaggedDoc { - tag: elt_tag.val, - doc: Doc { data: data, start: elt_size.next, end: end } - } - } - - pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(d.data, pos); - let elt_size = vuint_at(d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - return Some(Doc { data: d.data, start: elt_size.next, - end: pos }); - } - } - None - } - - pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> { - match maybe_get_doc(d, tg) { - Some(d) => d, - None => { - error!("failed to find block with tag {}", tg); - fail!(); - } - } - } - - pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(d.data, pos); - let elt_size = vuint_at(d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - let doc = Doc { data: d.data, start: elt_size.next, end: pos }; - if !it(elt_tag.val, doc) { - return false; - } - } - return true; - } - - pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(d.data, pos); - let elt_size = vuint_at(d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - let doc = Doc { data: d.data, start: elt_size.next, - end: pos }; - if !it(doc) { - return false; - } - } - } - return true; - } - - pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T { - f(d.data.slice(d.start, d.end)) - } - - - pub fn doc_as_u8(d: Doc) -> u8 { - assert_eq!(d.end, d.start + 1u); - d.data[d.start] - } - - 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 - } - - 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 - } - - pub fn doc_as_u64(d: Doc) -> u64 { - assert_eq!(d.end, d.start + 8u); - u64_from_be_bytes(d.data, d.start, 8u) - } - - pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } - pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } - pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } - pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } - - pub struct Decoder<'a> { - priv parent: Doc<'a>, - priv pos: uint, - } - - pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> { - Decoder { - parent: d, - pos: d.start - } - } - - impl<'doc> Decoder<'doc> { - fn _check_label(&mut self, lbl: &str) { - if self.pos < self.parent.end { - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - - if r_tag == (EsLabel as uint) { - self.pos = r_doc.end; - let str = r_doc.as_str_slice(); - if lbl != str { - fail!("Expected label {} but found {}", lbl, str); - } - } - } - } - - fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc<'doc> { - debug!(". next_doc(exp_tag={:?})", exp_tag); - if self.pos >= self.parent.end { - fail!("no more documents in current node!"); - } - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}", - self.parent.start, - self.parent.end, - self.pos, - r_tag, - r_doc.start, - r_doc.end); - if r_tag != (exp_tag as uint) { - fail!("expected EBML doc with tag {:?} but found tag {:?}", - exp_tag, r_tag); - } - if r_doc.end > self.parent.end { - fail!("invalid EBML, child extends to {:#x}, parent to {:#x}", - r_doc.end, self.parent.end); - } - self.pos = r_doc.end; - r_doc - } - - fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag, - f: |&mut Decoder<'doc>| -> T) -> T { - let d = self.next_doc(exp_tag); - let old_parent = self.parent; - let old_pos = self.pos; - self.parent = d; - self.pos = d.start; - let r = f(self); - self.parent = old_parent; - self.pos = old_pos; - r - } - - fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint { - let r = doc_as_u32(self.next_doc(exp_tag)); - debug!("_next_uint exp_tag={:?} result={}", exp_tag, r); - r as uint - } - - pub fn read_opaque<R>(&mut self, op: |&mut Decoder<'doc>, Doc| -> R) -> R { - let doc = self.next_doc(EsOpaque); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = doc.start; - - let result = op(self, doc); - - self.parent = old_parent; - self.pos = old_pos; - result - } - } - - impl<'doc> serialize::Decoder for Decoder<'doc> { - fn read_nil(&mut self) -> () { () } - - fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) } - fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) } - fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) } - fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } - fn read_uint(&mut self) -> uint { - let v = doc_as_u64(self.next_doc(EsUint)); - if v > (::std::uint::MAX as u64) { - fail!("uint {} too large for this architecture", v); - } - v as uint - } - - fn read_i64(&mut self) -> i64 { - doc_as_u64(self.next_doc(EsI64)) as i64 - } - fn read_i32(&mut self) -> i32 { - doc_as_u32(self.next_doc(EsI32)) as i32 - } - fn read_i16(&mut self) -> i16 { - doc_as_u16(self.next_doc(EsI16)) as i16 - } - fn read_i8 (&mut self) -> i8 { - doc_as_u8(self.next_doc(EsI8 )) as i8 - } - fn read_int(&mut self) -> int { - let v = doc_as_u64(self.next_doc(EsInt)) as i64; - if v > (int::MAX as i64) || v < (int::MIN as i64) { - debug!("FIXME \\#6122: Removing this makes this function miscompile"); - fail!("int {} out of range for this architecture", v); - } - v as int - } - - fn read_bool(&mut self) -> bool { - doc_as_u8(self.next_doc(EsBool)) != 0 - } - - fn read_f64(&mut self) -> f64 { - let bits = doc_as_u64(self.next_doc(EsF64)); - unsafe { transmute(bits) } - } - fn read_f32(&mut self) -> f32 { - let bits = doc_as_u32(self.next_doc(EsF32)); - unsafe { transmute(bits) } - } - fn read_char(&mut self) -> char { - char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap() - } - fn read_str(&mut self) -> ~str { - self.next_doc(EsStr).as_str() - } - - // Compound types: - fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder<'doc>| -> T) -> T { - debug!("read_enum({})", name); - self._check_label(name); - - let doc = self.next_doc(EsEnum); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = self.parent.start; - - let result = f(self); - - self.parent = old_parent; - self.pos = old_pos; - result - } - - fn read_enum_variant<T>(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> T) - -> T { - debug!("read_enum_variant()"); - let idx = self._next_uint(EsEnumVid); - debug!(" idx={}", idx); - - let doc = self.next_doc(EsEnumBody); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = self.parent.start; - - let result = f(self, idx); - - self.parent = old_parent; - self.pos = old_pos; - result - } - - fn read_enum_variant_arg<T>(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> T) -> T { - debug!("read_enum_variant_arg(idx={})", idx); - f(self) - } - - fn read_enum_struct_variant<T>(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> T) - -> T { - debug!("read_enum_struct_variant()"); - let idx = self._next_uint(EsEnumVid); - debug!(" idx={}", idx); - - let doc = self.next_doc(EsEnumBody); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = self.parent.start; - - let result = f(self, idx); - - self.parent = old_parent; - self.pos = old_pos; - result - } - - fn read_enum_struct_variant_field<T>(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); - f(self) - } - - fn read_struct<T>(&mut self, - name: &str, - _: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_struct(name={})", name); - f(self) - } - - fn read_struct_field<T>(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_struct_field(name={}, idx={})", name, idx); - self._check_label(name); - f(self) - } - - fn read_tuple<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T { - debug!("read_tuple()"); - self.read_seq(f) - } - - fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_tuple_arg(idx={})", idx); - self.read_seq_elt(idx, f) - } - - fn read_tuple_struct<T>(&mut self, - name: &str, - f: |&mut Decoder<'doc>, uint| -> T) - -> T { - debug!("read_tuple_struct(name={})", name); - self.read_tuple(f) - } - - fn read_tuple_struct_arg<T>(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_tuple_struct_arg(idx={})", idx); - self.read_tuple_arg(idx, f) - } - - fn read_option<T>(&mut self, f: |&mut Decoder<'doc>, bool| -> T) -> T { - debug!("read_option()"); - self.read_enum("Option", |this| { - this.read_enum_variant(["None", "Some"], |this, idx| { - match idx { - 0 => f(this, false), - 1 => f(this, true), - _ => fail!(), - } - }) - }) - } - - fn read_seq<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T { - debug!("read_seq()"); - self.push_doc(EsVec, |d| { - let len = d._next_uint(EsVecLen); - debug!(" len={}", len); - f(d, len) - }) - } - - fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_seq_elt(idx={})", idx); - self.push_doc(EsVecElt, f) - } - - fn read_map<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T { - debug!("read_map()"); - self.push_doc(EsMap, |d| { - let len = d._next_uint(EsMapLen); - debug!(" len={}", len); - f(d, len) - }) - } - - fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_map_elt_key(idx={})", idx); - self.push_doc(EsMapKey, f) - } - - fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_map_elt_val(idx={})", idx); - self.push_doc(EsMapVal, f) - } - } -} - -pub mod writer { - use super::*; - - use std::cast; - use std::clone::Clone; - use std::io; - use std::io::{Writer, Seek}; - use std::io::MemWriter; - use std::io::extensions::u64_to_be_bytes; - - // ebml writing - pub struct Encoder<'a> { - // FIXME(#5665): this should take a trait object. Note that if you - // delete this comment you should consider removing the - // unwrap()'s below of the results of the calls to - // write(). We're guaranteed that writing into a MemWriter - // won't fail, but this is not true for all I/O streams in - // general. - writer: &'a mut MemWriter, - priv size_positions: ~[uint], - last_error: io::IoResult<()>, - } - - fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) { - match size { - 1u => w.write(&[0x80u8 | (n as u8)]), - 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]), - 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8, - n as u8]), - 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8, - (n >> 8_u) as u8, n as u8]), - _ => fail!("vint to write too big: {}", n) - }.unwrap() - } - - fn write_vuint(w: &mut MemWriter, n: uint) { - if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; } - if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; } - if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; } - if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; } - fail!("vint to write too big: {}", n); - } - - pub fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> { - let size_positions: ~[uint] = ~[]; - Encoder { - writer: w, - size_positions: size_positions, - last_error: Ok(()), - } - } - - // FIXME (#2741): Provide a function to write the standard ebml header. - impl<'a> Encoder<'a> { - /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME. - pub unsafe fn unsafe_clone(&self) -> Encoder<'a> { - Encoder { - writer: cast::transmute_copy(&self.writer), - size_positions: self.size_positions.clone(), - last_error: Ok(()), - } - } - - pub fn start_tag(&mut self, tag_id: uint) { - debug!("Start tag {}", tag_id); - - // Write the enum ID: - write_vuint(self.writer, tag_id); - - // Write a placeholder four-byte size. - self.size_positions.push(if_ok!(self.writer.tell()) as uint); - let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; - if_ok!(self.writer.write(zeroes)); - } - - pub fn end_tag(&mut self) { - let last_size_pos = self.size_positions.pop().unwrap(); - let cur_pos = if_ok!(self.writer.tell()); - if_ok!(self.writer.seek(last_size_pos as i64, io::SeekSet)); - let size = (cur_pos as uint - last_size_pos - 4); - write_sized_vuint(self.writer, size, 4u); - if_ok!(self.writer.seek(cur_pos as i64, io::SeekSet)); - - debug!("End tag (size = {})", size); - } - - pub fn wr_tag(&mut self, tag_id: uint, blk: ||) { - self.start_tag(tag_id); - blk(); - self.end_tag(); - } - - pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) { - write_vuint(self.writer, tag_id); - write_vuint(self.writer, b.len()); - self.writer.write(b).unwrap(); - } - - pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) { - u64_to_be_bytes(v, 8u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) { - u64_to_be_bytes(v as u64, 4u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) { - u64_to_be_bytes(v as u64, 2u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) { - self.wr_tagged_bytes(tag_id, &[v]); - } - - pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) { - u64_to_be_bytes(v as u64, 8u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) { - u64_to_be_bytes(v as u64, 4u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) { - u64_to_be_bytes(v as u64, 2u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) { - self.wr_tagged_bytes(tag_id, &[v as u8]); - } - - pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) { - self.wr_tagged_bytes(tag_id, v.as_bytes()); - } - - pub fn wr_bytes(&mut self, b: &[u8]) { - debug!("Write {} bytes", b.len()); - self.writer.write(b).unwrap(); - } - - pub fn wr_str(&mut self, s: &str) { - debug!("Write str: {}", s); - self.writer.write(s.as_bytes()).unwrap(); - } - } - - // FIXME (#2743): optionally perform "relaxations" on end_tag to more - // efficiently encode sizes; this is a fixed point iteration - - // Set to true to generate more debugging in EBML code. - // Totally lame approach. - static DEBUG: bool = true; - - impl<'a> Encoder<'a> { - // used internally to emit things like the vector length and so on - fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) { - assert!(v <= 0xFFFF_FFFF_u); - self.wr_tagged_u32(t as uint, v as u32); - } - - fn _emit_label(&mut self, label: &str) { - // There are various strings that we have access to, such as - // the name of a record field, which do not actually appear in - // the encoded EBML (normally). This is just for - // efficiency. When debugging, though, we can emit such - // labels and then they will be checked by decoder to - // try and check failures more quickly. - if DEBUG { self.wr_tagged_str(EsLabel as uint, label) } - } - - pub fn emit_opaque(&mut self, f: |&mut Encoder|) { - self.start_tag(EsOpaque as uint); - f(self); - self.end_tag(); - } - } - - impl<'a> ::serialize::Encoder for Encoder<'a> { - fn emit_nil(&mut self) {} - - fn emit_uint(&mut self, v: uint) { - self.wr_tagged_u64(EsUint as uint, v as u64); - } - fn emit_u64(&mut self, v: u64) { - self.wr_tagged_u64(EsU64 as uint, v); - } - fn emit_u32(&mut self, v: u32) { - self.wr_tagged_u32(EsU32 as uint, v); - } - fn emit_u16(&mut self, v: u16) { - self.wr_tagged_u16(EsU16 as uint, v); - } - fn emit_u8(&mut self, v: u8) { - self.wr_tagged_u8(EsU8 as uint, v); - } - - fn emit_int(&mut self, v: int) { - self.wr_tagged_i64(EsInt as uint, v as i64); - } - fn emit_i64(&mut self, v: i64) { - self.wr_tagged_i64(EsI64 as uint, v); - } - fn emit_i32(&mut self, v: i32) { - self.wr_tagged_i32(EsI32 as uint, v); - } - fn emit_i16(&mut self, v: i16) { - self.wr_tagged_i16(EsI16 as uint, v); - } - fn emit_i8(&mut self, v: i8) { - self.wr_tagged_i8(EsI8 as uint, v); - } - - fn emit_bool(&mut self, v: bool) { - self.wr_tagged_u8(EsBool as uint, v as u8) - } - - fn emit_f64(&mut self, v: f64) { - let bits = unsafe { cast::transmute(v) }; - self.wr_tagged_u64(EsF64 as uint, bits); - } - fn emit_f32(&mut self, v: f32) { - let bits = unsafe { cast::transmute(v) }; - self.wr_tagged_u32(EsF32 as uint, bits); - } - fn emit_char(&mut self, v: char) { - self.wr_tagged_u32(EsChar as uint, v as u32); - } - - fn emit_str(&mut self, v: &str) { - self.wr_tagged_str(EsStr as uint, v) - } - - fn emit_enum(&mut self, name: &str, f: |&mut Encoder<'a>|) { - self._emit_label(name); - self.start_tag(EsEnum as uint); - f(self); - self.end_tag(); - } - - fn emit_enum_variant(&mut self, - _: &str, - v_id: uint, - _: uint, - f: |&mut Encoder<'a>|) { - self._emit_tagged_uint(EsEnumVid, v_id); - self.start_tag(EsEnumBody as uint); - f(self); - self.end_tag(); - } - - fn emit_enum_variant_arg(&mut self, _: uint, f: |&mut Encoder<'a>|) { - f(self) - } - - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: uint, - cnt: uint, - f: |&mut Encoder<'a>|) { - self.emit_enum_variant(v_name, v_id, cnt, f) - } - - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: uint, - f: |&mut Encoder<'a>|) { - self.emit_enum_variant_arg(idx, f) - } - - fn emit_struct(&mut self, - _: &str, - _len: uint, - f: |&mut Encoder<'a>|) { - f(self) - } - - fn emit_struct_field(&mut self, - name: &str, - _: uint, - f: |&mut Encoder<'a>|) { - self._emit_label(name); - f(self) - } - - fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_tuple_struct(&mut self, - _: &str, - len: uint, - f: |&mut Encoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_option(&mut self, f: |&mut Encoder<'a>|) { - self.emit_enum("Option", f); - } - fn emit_option_none(&mut self) { - self.emit_enum_variant("None", 0, 0, |_| ()) - } - fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { - self.emit_enum_variant("Some", 1, 1, f) - } - - fn emit_seq(&mut self, len: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsVec as uint); - self._emit_tagged_uint(EsVecLen, len); - f(self); - self.end_tag(); - } - - fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsVecElt as uint); - f(self); - self.end_tag(); - } - - fn emit_map(&mut self, len: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsMap as uint); - self._emit_tagged_uint(EsMapLen, len); - f(self); - self.end_tag(); - } - - fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsMapKey as uint); - f(self); - self.end_tag(); - } - - fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsMapVal as uint); - f(self); - self.end_tag(); - } - } -} - -// ___________________________________________________________________________ -// Testing - -#[cfg(test)] -mod tests { - use ebml::reader; - use ebml::writer; - use serialize::Encodable; - use serialize; - - use std::io::MemWriter; - use std::option::{None, Option, Some}; - - #[test] - fn test_vuint_at() { - let data = [ - 0x80, - 0xff, - 0x40, 0x00, - 0x7f, 0xff, - 0x20, 0x00, 0x00, - 0x3f, 0xff, 0xff, - 0x10, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff - ]; - - let mut res: reader::Res; - - // Class A - res = reader::vuint_at(data, 0); - assert_eq!(res.val, 0); - assert_eq!(res.next, 1); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 7) - 1); - assert_eq!(res.next, 2); - - // Class B - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, 0); - assert_eq!(res.next, 4); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 14) - 1); - assert_eq!(res.next, 6); - - // Class C - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, 0); - assert_eq!(res.next, 9); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 21) - 1); - assert_eq!(res.next, 12); - - // Class D - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, 0); - assert_eq!(res.next, 16); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 28) - 1); - assert_eq!(res.next, 20); - } - - #[test] - fn test_option_int() { - fn test_v(v: Option<int>) { - debug!("v == {:?}", v); - let mut wr = MemWriter::new(); - { - let mut ebml_w = writer::Encoder(&mut wr); - v.encode(&mut ebml_w); - } - let ebml_doc = reader::Doc(wr.get_ref()); - let mut deser = reader::Decoder(ebml_doc); - let v1 = serialize::Decodable::decode(&mut deser); - debug!("v1 == {:?}", v1); - assert_eq!(v, v1); - } - - test_v(Some(22)); - test_v(None); - test_v(Some(3)); - } -} - -#[cfg(test)] -mod bench { - use ebml::reader; - use test::BenchHarness; - - #[bench] - pub fn vuint_at_A_aligned(bh: &mut BenchHarness) { - use std::vec; - let data = vec::from_fn(4*100, |i| { - match i % 2 { - 0 => 0x80u8, - _ => i as u8, - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 0; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } - - #[bench] - pub fn vuint_at_A_unaligned(bh: &mut BenchHarness) { - use std::vec; - let data = vec::from_fn(4*100+1, |i| { - match i % 2 { - 1 => 0x80u8, - _ => i as u8 - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 1; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } - - #[bench] - pub fn vuint_at_D_aligned(bh: &mut BenchHarness) { - use std::vec; - let data = vec::from_fn(4*100, |i| { - match i % 4 { - 0 => 0x10u8, - 3 => i as u8, - _ => 0u8 - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 0; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } - - #[bench] - pub fn vuint_at_D_unaligned(bh: &mut BenchHarness) { - use std::vec; - let data = vec::from_fn(4*100+1, |i| { - match i % 4 { - 1 => 0x10u8, - 0 => i as u8, - _ => 0u8 - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 1; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } -} diff --git a/src/libextra/json.rs b/src/libextra/json.rs index ef8e0999521..8b082bf3056 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -51,17 +51,18 @@ A simple JSON document encoding a person, his/her age, address and phone numbers Rust provides a mechanism for low boilerplate encoding & decoding of values to and from JSON via the serialization API. -To be able to encode a piece of data, it must implement the `extra::serialize::Encodable` trait. -To be able to decode a piece of data, it must implement the `extra::serialize::Decodable` trait. +To be able to encode a piece of data, it must implement the `serialize::Encodable` trait. +To be able to decode a piece of data, it must implement the `serialize::Decodable` trait. The Rust compiler provides an annotation to automatically generate the code for these traits: `#[deriving(Decodable, Encodable)]` To encode using Encodable : ```rust +extern mod serialize; use extra::json; use std::io; -use extra::serialize::Encodable; +use serialize::Encodable; #[deriving(Encodable)] pub struct TestStruct { @@ -125,7 +126,8 @@ fn main() { To decode a json string using `Decodable` trait : ```rust -use extra::serialize::Decodable; +extern mod serialize; +use serialize::Decodable; #[deriving(Decodable)] pub struct MyStruct { @@ -150,8 +152,9 @@ Create a struct called TestStruct1 and serialize and deserialize it to and from using the serialization API, using the derived serialization code. ```rust +extern mod serialize; use extra::json; -use extra::serialize::{Encodable, Decodable}; +use serialize::{Encodable, Decodable}; #[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl. pub struct TestStruct1 { @@ -181,9 +184,10 @@ This example use the ToJson impl to unserialize the json string. Example of `ToJson` trait implementation for TestStruct1. ```rust +extern mod serialize; use extra::json; use extra::json::ToJson; -use extra::serialize::{Encodable, Decodable}; +use serialize::{Encodable, Decodable}; use extra::treemap::TreeMap; #[deriving(Decodable, Encodable)] // generate Decodable, Encodable impl. @@ -312,7 +316,7 @@ impl<'a> Encoder<'a> { } /// Encode the specified struct into a json [u8] - pub fn buffer_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~[u8] { + pub fn buffer_encode<T:serialize::Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~[u8] { //Serialize the object in a string using a writer let mut m = MemWriter::new(); { @@ -323,7 +327,7 @@ impl<'a> Encoder<'a> { } /// Encode the specified struct into a json str - pub fn str_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~str { + pub fn str_encode<T:serialize::Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~str { let buff:~[u8] = Encoder::buffer_encode(to_encode_object); str::from_utf8_owned(buff).unwrap() } @@ -684,7 +688,7 @@ impl<E: serialize::Encoder> serialize::Encodable<E> for Json { } } -impl Json{ +impl Json { /// Encodes a json value into a io::writer. Uses a single line. pub fn to_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> { let mut encoder = Encoder::new(wr); diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs index 401ece64a5d..37b4d3cc524 100644 --- a/src/libextra/lib.rs +++ b/src/libextra/lib.rs @@ -35,6 +35,17 @@ Rust extras are part of the standard Rust distribution. #[deny(missing_doc)]; extern mod sync; +#[cfg(not(stage0))] +extern mod serialize; + +#[cfg(stage0)] +pub mod serialize { + #[allow(missing_doc)]; + // Temp re-export until after a snapshot + extern mod serialize = "serialize"; + pub use self::serialize::{Encoder, Decoder, Encodable, Decodable, + EncoderHelpers, DecoderHelpers}; +} #[cfg(stage0)] macro_rules! if_ok ( @@ -62,7 +73,6 @@ pub mod lru_cache; // And ... other stuff pub mod url; -pub mod ebml; pub mod getopts; pub mod json; pub mod tempfile; @@ -85,7 +95,6 @@ mod unicode; // Compiler support modules pub mod test; -pub mod serialize; // A curious inner-module that's not exported that contains the binding // 'extra' so that macro-expanded references to extra::serialize and such diff --git a/src/libextra/ringbuf.rs b/src/libextra/ringbuf.rs index 4da35942935..17631f5bdff 100644 --- a/src/libextra/ringbuf.rs +++ b/src/libextra/ringbuf.rs @@ -19,6 +19,8 @@ use std::iter::{Rev, RandomAccessIterator}; use container::Deque; +use serialize::{Encodable, Decodable, Encoder, Decoder}; + static INITIAL_CAPACITY: uint = 8u; // 2^3 static MINIMUM_CAPACITY: uint = 2u; @@ -402,6 +404,31 @@ impl<A> Extendable<A> for RingBuf<A> { } } +impl< + S: Encoder, + T: Encodable<S> +> Encodable<S> for RingBuf<T> { + fn encode(&self, s: &mut S) { + s.emit_seq(self.len(), |s| { + for (i, e) in self.iter().enumerate() { + s.emit_seq_elt(i, |s| e.encode(s)); + } + }) + } +} + +impl<D:Decoder,T:Decodable<D>> Decodable<D> for RingBuf<T> { + fn decode(d: &mut D) -> RingBuf<T> { + let mut deque = RingBuf::new(); + d.read_seq(|d, len| { + for i in range(0u, len) { + deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))); + } + }); + deque + } +} + #[cfg(test)] mod tests { use container::Deque; diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs deleted file mode 100644 index 9b1b1e0548e..00000000000 --- a/src/libextra/serialize.rs +++ /dev/null @@ -1,883 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Support code for encoding and decoding types. - -/* -Core encoding and decoding interfaces. -*/ - -#[allow(missing_doc)]; -#[forbid(non_camel_case_types)]; - - -use std::hashmap::{HashMap, HashSet}; -use std::rc::Rc; -use std::trie::{TrieMap, TrieSet}; -use std::vec; -use ringbuf::RingBuf; -use container::Deque; -use dlist::DList; -use treemap::{TreeMap, TreeSet}; - -pub trait Encoder { - // Primitive types: - fn emit_nil(&mut self); - fn emit_uint(&mut self, v: uint); - fn emit_u64(&mut self, v: u64); - fn emit_u32(&mut self, v: u32); - fn emit_u16(&mut self, v: u16); - fn emit_u8(&mut self, v: u8); - fn emit_int(&mut self, v: int); - fn emit_i64(&mut self, v: i64); - fn emit_i32(&mut self, v: i32); - fn emit_i16(&mut self, v: i16); - fn emit_i8(&mut self, v: i8); - fn emit_bool(&mut self, v: bool); - fn emit_f64(&mut self, v: f64); - fn emit_f32(&mut self, v: f32); - fn emit_char(&mut self, v: char); - fn emit_str(&mut self, v: &str); - - // Compound types: - fn emit_enum(&mut self, name: &str, f: |&mut Self|); - - fn emit_enum_variant(&mut self, - v_name: &str, - v_id: uint, - len: uint, - f: |&mut Self|); - fn emit_enum_variant_arg(&mut self, a_idx: uint, f: |&mut Self|); - - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: uint, - len: uint, - f: |&mut Self|); - fn emit_enum_struct_variant_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self|); - - fn emit_struct(&mut self, name: &str, len: uint, f: |&mut Self|); - fn emit_struct_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self|); - - fn emit_tuple(&mut self, len: uint, f: |&mut Self|); - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Self|); - - fn emit_tuple_struct(&mut self, name: &str, len: uint, f: |&mut Self|); - fn emit_tuple_struct_arg(&mut self, f_idx: uint, f: |&mut Self|); - - // Specialized types: - fn emit_option(&mut self, f: |&mut Self|); - fn emit_option_none(&mut self); - fn emit_option_some(&mut self, f: |&mut Self|); - - fn emit_seq(&mut self, len: uint, f: |this: &mut Self|); - fn emit_seq_elt(&mut self, idx: uint, f: |this: &mut Self|); - - fn emit_map(&mut self, len: uint, f: |&mut Self|); - fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Self|); - fn emit_map_elt_val(&mut self, idx: uint, f: |&mut Self|); -} - -pub trait Decoder { - // Primitive types: - fn read_nil(&mut self) -> (); - fn read_uint(&mut self) -> uint; - fn read_u64(&mut self) -> u64; - fn read_u32(&mut self) -> u32; - fn read_u16(&mut self) -> u16; - fn read_u8(&mut self) -> u8; - fn read_int(&mut self) -> int; - fn read_i64(&mut self) -> i64; - fn read_i32(&mut self) -> i32; - fn read_i16(&mut self) -> i16; - fn read_i8(&mut self) -> i8; - fn read_bool(&mut self) -> bool; - fn read_f64(&mut self) -> f64; - fn read_f32(&mut self) -> f32; - fn read_char(&mut self) -> char; - fn read_str(&mut self) -> ~str; - - // Compound types: - fn read_enum<T>(&mut self, name: &str, f: |&mut Self| -> T) -> T; - - fn read_enum_variant<T>(&mut self, - names: &[&str], - f: |&mut Self, uint| -> T) - -> T; - fn read_enum_variant_arg<T>(&mut self, - a_idx: uint, - f: |&mut Self| -> T) - -> T; - - fn read_enum_struct_variant<T>(&mut self, - names: &[&str], - f: |&mut Self, uint| -> T) - -> T; - fn read_enum_struct_variant_field<T>(&mut self, - &f_name: &str, - f_idx: uint, - f: |&mut Self| -> T) - -> T; - - fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Self| -> T) - -> T; - fn read_struct_field<T>(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self| -> T) - -> T; - - fn read_tuple<T>(&mut self, f: |&mut Self, uint| -> T) -> T; - fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Self| -> T) -> T; - - fn read_tuple_struct<T>(&mut self, - s_name: &str, - f: |&mut Self, uint| -> T) - -> T; - fn read_tuple_struct_arg<T>(&mut self, - a_idx: uint, - f: |&mut Self| -> T) - -> T; - - // Specialized types: - fn read_option<T>(&mut self, f: |&mut Self, bool| -> T) -> T; - - fn read_seq<T>(&mut self, f: |&mut Self, uint| -> T) -> T; - fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T; - - fn read_map<T>(&mut self, f: |&mut Self, uint| -> T) -> T; - fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T; - fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T; -} - -pub trait Encodable<S:Encoder> { - fn encode(&self, s: &mut S); -} - -pub trait Decodable<D:Decoder> { - fn decode(d: &mut D) -> Self; -} - -impl<S:Encoder> Encodable<S> for uint { - fn encode(&self, s: &mut S) { - s.emit_uint(*self) - } -} - -impl<D:Decoder> Decodable<D> for uint { - fn decode(d: &mut D) -> uint { - d.read_uint() - } -} - -impl<S:Encoder> Encodable<S> for u8 { - fn encode(&self, s: &mut S) { - s.emit_u8(*self) - } -} - -impl<D:Decoder> Decodable<D> for u8 { - fn decode(d: &mut D) -> u8 { - d.read_u8() - } -} - -impl<S:Encoder> Encodable<S> for u16 { - fn encode(&self, s: &mut S) { - s.emit_u16(*self) - } -} - -impl<D:Decoder> Decodable<D> for u16 { - fn decode(d: &mut D) -> u16 { - d.read_u16() - } -} - -impl<S:Encoder> Encodable<S> for u32 { - fn encode(&self, s: &mut S) { - s.emit_u32(*self) - } -} - -impl<D:Decoder> Decodable<D> for u32 { - fn decode(d: &mut D) -> u32 { - d.read_u32() - } -} - -impl<S:Encoder> Encodable<S> for u64 { - fn encode(&self, s: &mut S) { - s.emit_u64(*self) - } -} - -impl<D:Decoder> Decodable<D> for u64 { - fn decode(d: &mut D) -> u64 { - d.read_u64() - } -} - -impl<S:Encoder> Encodable<S> for int { - fn encode(&self, s: &mut S) { - s.emit_int(*self) - } -} - -impl<D:Decoder> Decodable<D> for int { - fn decode(d: &mut D) -> int { - d.read_int() - } -} - -impl<S:Encoder> Encodable<S> for i8 { - fn encode(&self, s: &mut S) { - s.emit_i8(*self) - } -} - -impl<D:Decoder> Decodable<D> for i8 { - fn decode(d: &mut D) -> i8 { - d.read_i8() - } -} - -impl<S:Encoder> Encodable<S> for i16 { - fn encode(&self, s: &mut S) { - s.emit_i16(*self) - } -} - -impl<D:Decoder> Decodable<D> for i16 { - fn decode(d: &mut D) -> i16 { - d.read_i16() - } -} - -impl<S:Encoder> Encodable<S> for i32 { - fn encode(&self, s: &mut S) { - s.emit_i32(*self) - } -} - -impl<D:Decoder> Decodable<D> for i32 { - fn decode(d: &mut D) -> i32 { - d.read_i32() - } -} - -impl<S:Encoder> Encodable<S> for i64 { - fn encode(&self, s: &mut S) { - s.emit_i64(*self) - } -} - -impl<D:Decoder> Decodable<D> for i64 { - fn decode(d: &mut D) -> i64 { - d.read_i64() - } -} - -impl<'a, S:Encoder> Encodable<S> for &'a str { - fn encode(&self, s: &mut S) { - s.emit_str(*self) - } -} - -impl<S:Encoder> Encodable<S> for ~str { - fn encode(&self, s: &mut S) { - s.emit_str(*self) - } -} - -impl<D:Decoder> Decodable<D> for ~str { - fn decode(d: &mut D) -> ~str { - d.read_str() - } -} - -impl<S:Encoder> Encodable<S> for f32 { - fn encode(&self, s: &mut S) { - s.emit_f32(*self) - } -} - -impl<D:Decoder> Decodable<D> for f32 { - fn decode(d: &mut D) -> f32 { - d.read_f32() - } -} - -impl<S:Encoder> Encodable<S> for f64 { - fn encode(&self, s: &mut S) { - s.emit_f64(*self) - } -} - -impl<D:Decoder> Decodable<D> for f64 { - fn decode(d: &mut D) -> f64 { - d.read_f64() - } -} - -impl<S:Encoder> Encodable<S> for bool { - fn encode(&self, s: &mut S) { - s.emit_bool(*self) - } -} - -impl<D:Decoder> Decodable<D> for bool { - fn decode(d: &mut D) -> bool { - d.read_bool() - } -} - -impl<S:Encoder> Encodable<S> for char { - fn encode(&self, s: &mut S) { - s.emit_char(*self) - } -} - -impl<D:Decoder> Decodable<D> for char { - fn decode(d: &mut D) -> char { - d.read_char() - } -} - -impl<S:Encoder> Encodable<S> for () { - fn encode(&self, s: &mut S) { - s.emit_nil() - } -} - -impl<D:Decoder> Decodable<D> for () { - fn decode(d: &mut D) -> () { - d.read_nil() - } -} - -impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a T { - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~T { - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~T { - fn decode(d: &mut D) -> ~T { - ~Decodable::decode(d) - } -} - -impl<S:Encoder,T:Encodable<S>> Encodable<S> for @T { - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl<S:Encoder,T:Encodable<S>> Encodable<S> for Rc<T> { - #[inline] - fn encode(&self, s: &mut S) { - self.borrow().encode(s) - } -} - -impl<D:Decoder,T:Decodable<D>> Decodable<D> for Rc<T> { - #[inline] - fn decode(d: &mut D) -> Rc<T> { - Rc::new(Decodable::decode(d)) - } -} - -impl<D:Decoder,T:Decodable<D> + 'static> Decodable<D> for @T { - fn decode(d: &mut D) -> @T { - @Decodable::decode(d) - } -} - -impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a [T] { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)) - } - }) - } -} - -impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)) - } - }) - } -} - -impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] { - fn decode(d: &mut D) -> ~[T] { - d.read_seq(|d, len| { - vec::from_fn(len, |i| { - d.read_seq_elt(i, |d| Decodable::decode(d)) - }) - }) - } -} - -impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> { - fn encode(&self, s: &mut S) { - s.emit_option(|s| { - match *self { - None => s.emit_option_none(), - Some(ref v) => s.emit_option_some(|s| v.encode(s)), - } - }) - } -} - -impl<D:Decoder,T:Decodable<D>> Decodable<D> for Option<T> { - fn decode(d: &mut D) -> Option<T> { - d.read_option(|d, b| { - if b { - Some(Decodable::decode(d)) - } else { - None - } - }) - } -} - -impl<S:Encoder,T0:Encodable<S>,T1:Encodable<S>> Encodable<S> for (T0, T1) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1) => { - s.emit_seq(2, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - }) - } - } - } -} - -impl<D:Decoder,T0:Decodable<D>,T1:Decodable<D>> Decodable<D> for (T0, T1) { - fn decode(d: &mut D) -> (T0, T1) { - d.read_seq(|d, len| { - assert_eq!(len, 2); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)) - ) - }) - } -} - -impl< - S: Encoder, - T0: Encodable<S>, - T1: Encodable<S>, - T2: Encodable<S> -> Encodable<S> for (T0, T1, T2) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1, ref t2) => { - s.emit_seq(3, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - s.emit_seq_elt(2, |s| t2.encode(s)); - }) - } - } - } -} - -impl< - D: Decoder, - T0: Decodable<D>, - T1: Decodable<D>, - T2: Decodable<D> -> Decodable<D> for (T0, T1, T2) { - fn decode(d: &mut D) -> (T0, T1, T2) { - d.read_seq(|d, len| { - assert_eq!(len, 3); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)), - d.read_seq_elt(2, |d| Decodable::decode(d)) - ) - }) - } -} - -impl< - S: Encoder, - T0: Encodable<S>, - T1: Encodable<S>, - T2: Encodable<S>, - T3: Encodable<S> -> Encodable<S> for (T0, T1, T2, T3) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1, ref t2, ref t3) => { - s.emit_seq(4, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - s.emit_seq_elt(2, |s| t2.encode(s)); - s.emit_seq_elt(3, |s| t3.encode(s)); - }) - } - } - } -} - -impl< - D: Decoder, - T0: Decodable<D>, - T1: Decodable<D>, - T2: Decodable<D>, - T3: Decodable<D> -> Decodable<D> for (T0, T1, T2, T3) { - fn decode(d: &mut D) -> (T0, T1, T2, T3) { - d.read_seq(|d, len| { - assert_eq!(len, 4); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)), - d.read_seq_elt(2, |d| Decodable::decode(d)), - d.read_seq_elt(3, |d| Decodable::decode(d)) - ) - }) - } -} - -impl< - S: Encoder, - T0: Encodable<S>, - T1: Encodable<S>, - T2: Encodable<S>, - T3: Encodable<S>, - T4: Encodable<S> -> Encodable<S> for (T0, T1, T2, T3, T4) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1, ref t2, ref t3, ref t4) => { - s.emit_seq(5, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - s.emit_seq_elt(2, |s| t2.encode(s)); - s.emit_seq_elt(3, |s| t3.encode(s)); - s.emit_seq_elt(4, |s| t4.encode(s)); - }) - } - } - } -} - -impl< - D: Decoder, - T0: Decodable<D>, - T1: Decodable<D>, - T2: Decodable<D>, - T3: Decodable<D>, - T4: Decodable<D> -> Decodable<D> for (T0, T1, T2, T3, T4) { - fn decode(d: &mut D) -> (T0, T1, T2, T3, T4) { - d.read_seq(|d, len| { - assert_eq!(len, 5); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)), - d.read_seq_elt(2, |d| Decodable::decode(d)), - d.read_seq_elt(3, |d| Decodable::decode(d)), - d.read_seq_elt(4, |d| Decodable::decode(d)) - ) - }) - } -} - -impl< - S: Encoder, - T: Encodable<S> -> Encodable<S> for DList<T> { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)); - } - }) - } -} - -impl<D:Decoder,T:Decodable<D>> Decodable<D> for DList<T> { - fn decode(d: &mut D) -> DList<T> { - let mut list = DList::new(); - d.read_seq(|d, len| { - for i in range(0u, len) { - list.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - }); - list - } -} - -impl< - S: Encoder, - T: Encodable<S> -> Encodable<S> for RingBuf<T> { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)); - } - }) - } -} - -impl<D:Decoder,T:Decodable<D>> Decodable<D> for RingBuf<T> { - fn decode(d: &mut D) -> RingBuf<T> { - let mut deque = RingBuf::new(); - d.read_seq(|d, len| { - for i in range(0u, len) { - deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - }); - deque - } -} - -impl< - E: Encoder, - K: Encodable<E> + Hash + IterBytes + Eq, - V: Encodable<E> -> Encodable<E> for HashMap<K, V> { - fn encode(&self, e: &mut E) { - e.emit_map(self.len(), |e| { - let mut i = 0; - for (key, val) in self.iter() { - e.emit_map_elt_key(i, |e| key.encode(e)); - e.emit_map_elt_val(i, |e| val.encode(e)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - K: Decodable<D> + Hash + IterBytes + Eq, - V: Decodable<D> -> Decodable<D> for HashMap<K, V> { - fn decode(d: &mut D) -> HashMap<K, V> { - d.read_map(|d, len| { - let mut map = HashMap::with_capacity(len); - for i in range(0u, len) { - let key = d.read_map_elt_key(i, |d| Decodable::decode(d)); - let val = d.read_map_elt_val(i, |d| Decodable::decode(d)); - map.insert(key, val); - } - map - }) - } -} - -impl< - S: Encoder, - T: Encodable<S> + Hash + IterBytes + Eq -> Encodable<S> for HashSet<T> { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - let mut i = 0; - for e in self.iter() { - s.emit_seq_elt(i, |s| e.encode(s)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - T: Decodable<D> + Hash + IterBytes + Eq -> Decodable<D> for HashSet<T> { - fn decode(d: &mut D) -> HashSet<T> { - d.read_seq(|d, len| { - let mut set = HashSet::with_capacity(len); - for i in range(0u, len) { - set.insert(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - set - }) - } -} - -impl< - E: Encoder, - V: Encodable<E> -> Encodable<E> for TrieMap<V> { - fn encode(&self, e: &mut E) { - e.emit_map(self.len(), |e| { - for (i, (key, val)) in self.iter().enumerate() { - e.emit_map_elt_key(i, |e| key.encode(e)); - e.emit_map_elt_val(i, |e| val.encode(e)); - } - }); - } -} - -impl< - D: Decoder, - V: Decodable<D> -> Decodable<D> for TrieMap<V> { - fn decode(d: &mut D) -> TrieMap<V> { - d.read_map(|d, len| { - let mut map = TrieMap::new(); - for i in range(0u, len) { - let key = d.read_map_elt_key(i, |d| Decodable::decode(d)); - let val = d.read_map_elt_val(i, |d| Decodable::decode(d)); - map.insert(key, val); - } - map - }) - } -} - -impl<S: Encoder> Encodable<S> for TrieSet { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)); - } - }) - } -} - -impl<D: Decoder> Decodable<D> for TrieSet { - fn decode(d: &mut D) -> TrieSet { - d.read_seq(|d, len| { - let mut set = TrieSet::new(); - for i in range(0u, len) { - set.insert(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - set - }) - } -} - -impl< - E: Encoder, - K: Encodable<E> + Eq + TotalOrd, - V: Encodable<E> + Eq -> Encodable<E> for TreeMap<K, V> { - fn encode(&self, e: &mut E) { - e.emit_map(self.len(), |e| { - let mut i = 0; - for (key, val) in self.iter() { - e.emit_map_elt_key(i, |e| key.encode(e)); - e.emit_map_elt_val(i, |e| val.encode(e)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - K: Decodable<D> + Eq + TotalOrd, - V: Decodable<D> + Eq -> Decodable<D> for TreeMap<K, V> { - fn decode(d: &mut D) -> TreeMap<K, V> { - d.read_map(|d, len| { - let mut map = TreeMap::new(); - for i in range(0u, len) { - let key = d.read_map_elt_key(i, |d| Decodable::decode(d)); - let val = d.read_map_elt_val(i, |d| Decodable::decode(d)); - map.insert(key, val); - } - map - }) - } -} - -impl< - S: Encoder, - T: Encodable<S> + Eq + TotalOrd -> Encodable<S> for TreeSet<T> { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - let mut i = 0; - for e in self.iter() { - s.emit_seq_elt(i, |s| e.encode(s)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - T: Decodable<D> + Eq + TotalOrd -> Decodable<D> for TreeSet<T> { - fn decode(d: &mut D) -> TreeSet<T> { - d.read_seq(|d, len| { - let mut set = TreeSet::new(); - for i in range(0u, len) { - set.insert(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - set - }) - } -} - -// ___________________________________________________________________________ -// Helper routines -// -// In some cases, these should eventually be coded as traits. - -pub trait EncoderHelpers { - fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut Self, v: &T|); -} - -impl<S:Encoder> EncoderHelpers for S { - fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut S, &T|) { - self.emit_seq(v.len(), |this| { - for (i, e) in v.iter().enumerate() { - this.emit_seq_elt(i, |this| { - f(this, e) - }) - } - }) - } -} - -pub trait DecoderHelpers { - fn read_to_vec<T>(&mut self, f: |&mut Self| -> T) -> ~[T]; -} - -impl<D:Decoder> DecoderHelpers for D { - fn read_to_vec<T>(&mut self, f: |&mut D| -> T) -> ~[T] { - self.read_seq(|this, len| { - vec::from_fn(len, |i| { - this.read_seq_elt(i, |this| f(this)) - }) - }) - } -} diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 6605ea00c44..449e72dd0ec 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -17,6 +17,8 @@ use std::iter::{Peekable}; use std::cmp::Ordering; use std::ptr; +use serialize::{Encodable, Decodable, Encoder, Decoder}; + // This is implemented as an AA tree, which is a simplified variation of // a red-black tree where red (horizontal) nodes can only be added // as a right child. The time complexity is the same, and re-balancing @@ -1004,6 +1006,71 @@ impl<T: TotalOrd> Extendable<T> for TreeSet<T> { } } +impl< + E: Encoder, + K: Encodable<E> + Eq + TotalOrd, + V: Encodable<E> + Eq +> Encodable<E> for TreeMap<K, V> { + fn encode(&self, e: &mut E) { + e.emit_map(self.len(), |e| { + let mut i = 0; + for (key, val) in self.iter() { + e.emit_map_elt_key(i, |e| key.encode(e)); + e.emit_map_elt_val(i, |e| val.encode(e)); + i += 1; + } + }) + } +} + +impl< + D: Decoder, + K: Decodable<D> + Eq + TotalOrd, + V: Decodable<D> + Eq +> Decodable<D> for TreeMap<K, V> { + fn decode(d: &mut D) -> TreeMap<K, V> { + d.read_map(|d, len| { + let mut map = TreeMap::new(); + for i in range(0u, len) { + let key = d.read_map_elt_key(i, |d| Decodable::decode(d)); + let val = d.read_map_elt_val(i, |d| Decodable::decode(d)); + map.insert(key, val); + } + map + }) + } +} + +impl< + S: Encoder, + T: Encodable<S> + Eq + TotalOrd +> Encodable<S> for TreeSet<T> { + fn encode(&self, s: &mut S) { + s.emit_seq(self.len(), |s| { + let mut i = 0; + for e in self.iter() { + s.emit_seq_elt(i, |s| e.encode(s)); + i += 1; + } + }) + } +} + +impl< + D: Decoder, + T: Decodable<D> + Eq + TotalOrd +> Decodable<D> for TreeSet<T> { + fn decode(d: &mut D) -> TreeSet<T> { + d.read_seq(|d, len| { + let mut set = TreeSet::new(); + for i in range(0u, len) { + set.insert(d.read_seq_elt(i, |d| Decodable::decode(d))); + } + set + }) + } +} + #[cfg(test)] mod test_treemap { |
