├── .gitignore
├── .travis.yml
├── Cargo.toml
├── LICENSE.md
├── examples
├── basic.rs
└── bitvec.rs
├── logo.png
├── readme.md
├── src
├── bitpack.rs
├── bitvec.rs
├── float.rs
├── lib.rs
├── refbox.rs
├── rustc_serialize
│ ├── mod.rs
│ ├── reader.rs
│ └── writer.rs
└── serde
│ ├── mod.rs
│ ├── reader.rs
│ └── writer.rs
└── tests
└── test.rs
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /Cargo.lock
3 | *.swp
4 | *.swo
5 | .cargo
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | lang: c
2 | after_success: |
3 | [ $TRAVIS_BRANCH = master ] &&
4 | [ $TRAVIS_PULL_REQUEST = false ] &&
5 | cargo doc &&
6 | echo "" > target/doc/index.html &&
7 | sudo pip install ghp-import &&
8 | ghp-import -n target/doc &&
9 | git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
10 |
11 | env:
12 | matrix:
13 | - CHANNEL='stable'
14 | - CHANNEL='beta'
15 | - CHANNEL='nightly'
16 | global:
17 | - secure: SZSxNqg9wiGx8EnJhifJ2kb/aCRcLim9TzTQyfurPqd8qVGkDOeVjTtbs+VTxLVXYtMJAz+YYnrQDwsu8kc/uYpQajU+gRMqNGEP5gNj3Ha5iNGDasAS6piIHQSMROayZ+D9g22nlGnjk8t9eZtLHC/Z8IWMCnjcIHvqMFY6cgI=
18 |
19 | install:
20 | - curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh > ./rustup.sh
21 | - chmod +x ./rustup.sh
22 | - ./rustup.sh --yes
23 |
24 | script:
25 | - multirust default $CHANNEL
26 | - cargo build
27 | - cargo build --no-default-features --features "rustc-serialize"
28 | - cargo build --no-default-features --features "serde"
29 | - if [ $CHANNEL = 'nightly' ] ; then cargo test ; fi
30 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "mincode"
3 | version = "0.6.0"
4 | authors = ["Ty Overby ", "Francesco Mazzoli ", "Boscop "]
5 |
6 | repository = "https://github.com/Boscop/mincode"
7 | documentation = "http://tyoverby.github.io/bincode/bincode/"
8 | keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
9 |
10 | license = "MIT"
11 | description = "A binary serialization / deserialization strategy and implementation with serde and rustc-serialize backends."
12 |
13 | [dependencies]
14 | byteorder = "0.5.*"
15 | num-traits = "0.1.32"
16 | # leb128 = "0.2.*"
17 | leb128 = { git = 'https://github.com/Boscop/leb128' }
18 | bit-vec = "0.4.*"
19 | # bitpack = "0.1.*"
20 | # bitpack = { git = 'https://github.com/Boscop/bitpack' }
21 | conv = "0.3.*"
22 | half = "*"
23 |
24 | [dependencies.rustc-serialize]
25 | version = "0.3.*"
26 | optional = true
27 |
28 | [dependencies.serde]
29 | version = "0.8.*"
30 | optional = true
31 |
32 | [dev-dependencies]
33 | serde_derive = "0.8.*"
34 |
35 | [features]
36 | default = ["rustc-serialize", "serde"]
37 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Ty Overby
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/basic.rs:
--------------------------------------------------------------------------------
1 | extern crate mincode;
2 | extern crate rustc_serialize;
3 |
4 | use mincode::{SizeLimit, FloatEncoding};
5 | use mincode::rustc_serialize::{encode, decode};
6 |
7 | #[derive(RustcEncodable, RustcDecodable, PartialEq)]
8 | struct Entity {
9 | x: f32,
10 | y: f32,
11 | }
12 |
13 | #[derive(RustcEncodable, RustcDecodable, PartialEq)]
14 | struct World {
15 | id: u32,
16 | entities: Vec
17 | }
18 |
19 | fn main() {
20 | let world = World {
21 | id: 127,
22 | entities: vec![Entity {x: 0.25, y: 4.0}, Entity {x: 10.0, y: 20.5}]
23 | };
24 |
25 | let encoded: Vec = encode(&world, SizeLimit::Infinite, FloatEncoding::F16).unwrap();
26 |
27 | // 1 byte for id, 1 byte for the length of the vector, 2 bytes per float.
28 | assert_eq!(encoded.len(), 1 + 1 + 4 * 2);
29 |
30 | let decoded: World = decode(&encoded, FloatEncoding::F16).unwrap();
31 |
32 | assert!(world == decoded);
33 | }
34 |
--------------------------------------------------------------------------------
/examples/bitvec.rs:
--------------------------------------------------------------------------------
1 | extern crate mincode;
2 | extern crate rustc_serialize;
3 |
4 | use mincode::{SizeLimit, FloatEncoding, BVec, BitVec};
5 | use mincode::rustc_serialize::{encode, decode};
6 |
7 | fn main() {
8 | let bitvec = BVec::new(BitVec::from_fn(126, |i| { i % 2 == 0 }));
9 |
10 | let encoded: Vec = encode(&bitvec, SizeLimit::Infinite, FloatEncoding::Normal).unwrap();
11 |
12 | // 1 byte for the length of the vector, ceil(126 / 8) == 16 bytes for the bits.
13 | assert_eq!(encoded.len(), 17);
14 |
15 | let decoded: BVec = decode(&encoded, FloatEncoding::Normal).unwrap();
16 |
17 | assert!(bitvec == decoded);
18 | }
19 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Boscop/mincode/042f3d9ec674524dce1f8bb146cf67a0ea7976e0/logo.png
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Mincode - minimal encoding
2 |
3 | Based on bincode, but encodes to smaller size.
4 | Useful for encoding messages for real-time multiplayer game networking.
5 |
6 | A compact encoder / decoder pair that uses an binary zero-fluff encoding scheme.
7 | The size of the encoded object will be the same or smaller than the size that
8 | the object takes up in memory in a running Rust program.
9 |
10 | In addition to exposing two simple functions that encode to Vec and decode
11 | from Vec, mincode exposes a Reader/Writer API that makes it work
12 | perfectly with other stream-based apis such as rust files, network streams,
13 | and the [flate2-rs](https://github.com/alexcrichton/flate2-rs) compression
14 | library.
15 |
16 | ## Example
17 |
18 | ```rust
19 | extern crate mincode;
20 | extern crate rustc_serialize;
21 |
22 | use mincode::{SizeLimit, FloatEncoding};
23 | use mincode::rustc_serialize::{encode, decode};
24 |
25 | #[derive(RustcEncodable, RustcDecodable, PartialEq)]
26 | struct Entity {
27 | x: f32,
28 | y: f32,
29 | }
30 |
31 | #[derive(RustcEncodable, RustcDecodable, PartialEq)]
32 | struct World {
33 | id: u32,
34 | entities: Vec
35 | }
36 |
37 | fn main() {
38 | let world = World {
39 | id: 127,
40 | entities: vec![Entity {x: 0.25, y: 4.0}, Entity {x: 10.0, y: 20.5}]
41 | };
42 |
43 | let encoded: Vec = encode(&world, SizeLimit::Infinite, FloatEncoding::F16).unwrap();
44 |
45 | // 1 byte for id, 1 byte for the length of the vector, 2 bytes per float.
46 | assert_eq!(encoded.len(), 1 + 1 + 4 * 2);
47 |
48 | let decoded: World = decode(&encoded, FloatEncoding::F16).unwrap();
49 |
50 | assert!(world == decoded);
51 | }
52 |
53 | ```
54 |
55 |
56 | It also supports efficient encoding of [bit vectors](https://crates.io/crates/bit-vec):
57 |
58 | ```rust
59 | extern crate mincode;
60 | extern crate rustc_serialize;
61 |
62 | use mincode::{SizeLimit, FloatEncoding, BVec, BitVec};
63 | use mincode::rustc_serialize::{encode, decode};
64 |
65 | fn main() {
66 | let bitvec = BVec::new(BitVec::from_fn(126, |i| { i % 2 == 0 }));
67 |
68 | let encoded: Vec = encode(&bitvec, SizeLimit::Infinite, FloatEncoding::Normal).unwrap();
69 |
70 | // 1 byte for the length of the vector, ceil(126 / 8) == 16 bytes for the bits.
71 | assert_eq!(encoded.len(), 17);
72 |
73 | let decoded: BVec = decode(&encoded, FloatEncoding::Normal).unwrap();
74 |
75 | assert!(bitvec == decoded);
76 | }
77 | ```
78 |
79 |
80 | ## Details
81 |
82 | All integer types use [variable length encoding](https://crates.io/crates/leb128), taking only the necessary number of bytes.
83 | This includes e.g. enum tags, Vec lengths and the elements of Vecs.
84 | Tuples and structs are encoded by encoding their fields one-by-one, and enums are
85 | encoded by first writing out the tag representing the variant and
86 | then the contents.
87 | Floats can be encoded in their original precision, [half precision (f16)](https://crates.io/crates/half),
88 | always f32 or at half of their original precision.
89 |
90 |
--------------------------------------------------------------------------------
/src/bitpack.rs:
--------------------------------------------------------------------------------
1 | #[cfg(feature = "rustc-serialize")]
2 | use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder};
3 |
4 | #[cfg(feature = "serde")]
5 | use serde_crate as serde;
6 |
7 | pub use bit_pack::BitPack;
8 |
9 | #[derive(Debug, PartialEq, Eq)]
10 | pub struct BPack {
11 | pack: BitPack>
12 | }
13 | impl BPack {
14 | pub fn new<'b>(buf: Vec) -> BPack {
15 | BPack { pack: BitPack::>::new(buf) }
16 | }
17 | pub fn get(&self) -> &BitPack> {
18 | &self.pack
19 | }
20 | pub fn get_mut(&mut self) -> &mut BitPack> {
21 | &mut self.pack
22 | }
23 | }
24 |
25 | #[cfg(feature = "rustc-serialize")]
26 | impl Encodable for BPack {
27 | fn encode(&self, s: &mut S) -> Result<(), S::Error> {
28 | self.pack.buff.encode(s)
29 | }
30 | }
31 |
32 | #[cfg(feature = "rustc-serialize")]
33 | impl Decodable for BPack {
34 | fn decode(d: &mut D) -> Result {
35 | let v = Decodable::decode(d)?;
36 | Ok(BPack { pack: BitPack::>::new(v) })
37 | }
38 | }
39 |
40 | #[cfg(feature = "serde")]
41 | impl serde::Serialize for BPack {
42 | fn serialize(&self, s: &mut S) -> Result<(), S::Error>
43 | where S: serde::Serializer
44 | {
45 | serde::Serialize::serialize(&self.pack.buff, s)
46 | }
47 | }
48 |
49 | #[cfg(feature = "serde")]
50 | impl serde::Deserialize for BPack {
51 | fn deserialize(d: &mut D) -> Result
52 | where D: serde::Deserializer
53 | {
54 | let v = serde::Deserialize::deserialize(d)?;
55 | Ok(BPack { pack: BitPack::>::new(v) })
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/bitvec.rs:
--------------------------------------------------------------------------------
1 | #[cfg(feature = "rustc-serialize")]
2 | use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder};
3 |
4 | #[cfg(feature = "serde")]
5 | use serde_crate as serde;
6 |
7 | pub use bit_vec::BitVec;
8 |
9 | #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
10 | pub struct BVec {
11 | vec: BitVec,
12 | }
13 | impl BVec {
14 | pub fn new(vec: BitVec) -> Self {
15 | BVec { vec: vec }
16 | }
17 | pub fn get(&self) -> &BitVec {
18 | &self.vec
19 | }
20 | pub fn get_mut(&mut self) -> &mut BitVec {
21 | &mut self.vec
22 | }
23 | }
24 |
25 | #[cfg(feature = "rustc-serialize")]
26 | impl Encodable for BVec {
27 | fn encode(&self, s: &mut S) -> Result<(), S::Error> {
28 | self.vec.len().encode(s)?;
29 | //self.vec.to_bytes().encode(s)
30 |
31 | // avoid encoding the Vec's len
32 | for b in self.vec.to_bytes() {
33 | b.encode(s)?;
34 | }
35 | Ok(())
36 | }
37 | }
38 |
39 | #[cfg(feature = "rustc-serialize")]
40 | impl Decodable for BVec {
41 | fn decode(d: &mut D) -> Result {
42 | let bit_len: usize = Decodable::decode(d)?;
43 | //let bytes: Vec = Decodable::decode(d)?;
44 | let byte_len = if bit_len % 8 == 0 { bit_len / 8 } else { bit_len / 8 + 1 };
45 | let mut bytes = Vec::with_capacity(byte_len);
46 | for _ in 0..byte_len {
47 | bytes.push(Decodable::decode(d)?);
48 | }
49 | let mut vec = BitVec::from_bytes(&bytes);
50 | unsafe { vec.set_len(bit_len); }
51 | Ok(BVec { vec: vec })
52 | }
53 | }
54 |
55 | #[cfg(feature = "serde")]
56 | impl serde::Serialize for BVec {
57 | fn serialize(&self, s: &mut S) -> Result<(), S::Error>
58 | where S: serde::Serializer
59 | {
60 | serde::Serialize::serialize(&self.vec.len(), s)?;
61 |
62 | // avoid encoding the Vec's len
63 | for b in self.vec.to_bytes() {
64 | serde::Serialize::serialize(&b, s)?;
65 | }
66 | Ok(())
67 | }
68 | }
69 |
70 | #[cfg(feature = "serde")]
71 | impl serde::Deserialize for BVec {
72 | fn deserialize(d: &mut D) -> Result
73 | where D: serde::Deserializer
74 | {
75 | let bit_len: usize = serde::Deserialize::deserialize(d)?;
76 | let byte_len = if bit_len % 8 == 0 { bit_len / 8 } else { bit_len / 8 + 1 };
77 | let mut bytes = Vec::with_capacity(byte_len);
78 | for _ in 0..byte_len {
79 | bytes.push(serde::Deserialize::deserialize(d)?);
80 | }
81 | let mut vec = BitVec::from_bytes(&bytes);
82 | unsafe { vec.set_len(bit_len); }
83 | Ok(BVec { vec: vec })
84 | }
85 | }
--------------------------------------------------------------------------------
/src/float.rs:
--------------------------------------------------------------------------------
1 | use std::io::{Read, Write};
2 | use std::io::Error as IoError;
3 |
4 | use byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt};
5 |
6 | use num_traits;
7 |
8 | use half::f16;
9 |
10 | /// How floats will be encoded.
11 | #[repr(usize)]
12 | #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
13 | pub enum FloatEncoding {
14 | /// encode f32 as f32 and f64 as f64.
15 | Normal,
16 | /// f32 and f64 will be endoded as half precision floats using the half crate.
17 | F16,
18 | /// f32 and f64 will be endoded as f32.
19 | F32,
20 | /// f32 will be encoded as [half](https://docs.rs/half/)::F16 and f64 will be endoded as f32.
21 | HalvePrecision,
22 | }
23 |
24 | pub type FloatEncoder = fn(&mut Write, F) -> Result<(), IoError>;
25 | pub type FloatDecoder = fn(&mut Read) -> Result;
26 |
27 | static FLOAT_ENCODERS: [(FloatEncoder, FloatEncoder); 4] = [
28 | (write_f32_normal, write_f64_normal),
29 | (write_f32_f16, write_f64_f16),
30 | (write_f32_normal, write_f64_f32),
31 | (write_f32_f16, write_f64_f32),
32 | ];
33 | static FLOAT_DECODERS: [(FloatDecoder, FloatDecoder); 4] = [
34 | (read_f32_normal, read_f64_normal),
35 | (read_f32_f16, read_f64_f16),
36 | (read_f32_normal, read_f64_f32),
37 | (read_f32_f16, read_f64_f32),
38 | ];
39 | static FLOAT_SIZES: [(usize, usize); 4] = [
40 | // (size_of::(), size_of::()),
41 | // (size_of::(), size_of::()),
42 | // (size_of::(), size_of::()),
43 | // (size_of::(), size_of::()),
44 | (4, 8),
45 | (2, 2),
46 | (4, 4),
47 | (2, 4),
48 | ];
49 |
50 | #[inline(always)]
51 | pub fn float_encoder(float_enc: FloatEncoding) -> (FloatEncoder, FloatEncoder) {
52 | unsafe { *FLOAT_ENCODERS.get_unchecked(float_enc as usize) }
53 | }
54 |
55 | #[inline(always)]
56 | pub fn float_decoder(float_enc: FloatEncoding) -> (FloatDecoder, FloatDecoder) {
57 | unsafe { *FLOAT_DECODERS.get_unchecked(float_enc as usize) }
58 | }
59 |
60 | #[inline(always)]
61 | pub fn float_sizes(float_enc: FloatEncoding) -> (usize, usize) {
62 | unsafe { *FLOAT_SIZES.get_unchecked(float_enc as usize) }
63 | }
64 |
65 | fn write_f32_normal(w: &mut Write, v: f32) -> Result<(), IoError> {
66 | w.write_f32::(v)
67 | }
68 | fn write_f64_normal(w: &mut Write, v: f64) -> Result<(), IoError> {
69 | w.write_f64::(v)
70 | }
71 | fn write_f32_f16(w: &mut Write, v: f32) -> Result<(), IoError> {
72 | w.write_u16::(f16::from_f32(v).as_bits())
73 | }
74 | fn write_f64_f16(w: &mut Write, v: f64) -> Result<(), IoError> {
75 | w.write_u16::(f16::from_f64(v).as_bits())
76 | }
77 | fn write_f64_f32(w: &mut Write, v: f64) -> Result<(), IoError> {
78 | w.write_f32::(v as f32)
79 | }
80 |
81 | fn read_f32_normal(r: &mut Read) -> Result {
82 | r.read_f32::()
83 | }
84 | fn read_f64_normal(r: &mut Read) -> Result {
85 | r.read_f64::()
86 | }
87 | fn read_f32_f16(r: &mut Read) -> Result {
88 | r.read_u16::().map(|v| f32::from(f16::from_bits(v)))
89 | }
90 | fn read_f64_f16(r: &mut Read) -> Result {
91 | r.read_u16::().map(|v| f64::from(f16::from_bits(v)))
92 | }
93 | fn read_f64_f32(r: &mut Read) -> Result {
94 | r.read_f32::().map(|v| v as f64)
95 | }
96 |
--------------------------------------------------------------------------------
/src/lib.rs:
--------------------------------------------------------------------------------
1 | //! `bincode` is a crate for encoding and decoding using a tiny binary
2 | //! serialization strategy.
3 | //!
4 | //! There are simple functions for encoding to `Vec` and decoding from
5 | //! `&[u8]`, but the meat of the library is the `encode_into` and `decode_from`
6 | //! functions which respectively allow encoding into a `std::io::Writer`
7 | //! and decoding from a `std::io::Buffer`.
8 | //!
9 | //! ## Modules
10 | //! There are two ways to encode and decode structs using `bincode`, either using `rustc_serialize`
11 | //! or the `serde` crate. `rustc_serialize` and `serde` are crates and and also the names of their
12 | //! corresponding modules inside of `bincode`. Both modules have exactly equivalant functions, and
13 | //! and the only difference is whether or not the library user wants to use `rustc_serialize` or
14 | //! `serde`.
15 | //!
16 | //! ### Using Basic Functions
17 | //!
18 | //! ```rust
19 | //! #![allow(unstable)]
20 | //! extern crate mincode;
21 | //! use mincode::rustc_serialize::{encode, decode};
22 | //! use mincode::{SizeLimit, FloatEncoding};
23 | //! fn main() {
24 | //! // The object that we will serialize.
25 | //! let target = Some("hello world".to_string());
26 | //! // The maximum size of the encoded message.
27 | //! let limit = SizeLimit::Bounded(20);
28 | //!
29 | //! let encoded: Vec = encode(&target, limit, FloatEncoding::Normal).unwrap();
30 | //! let decoded: Option = decode(&encoded[..], FloatEncoding::Normal).unwrap();
31 | //! assert_eq!(target, decoded);
32 | //! }
33 | //! ```
34 |
35 | #![crate_name = "mincode"]
36 | #![crate_type = "rlib"]
37 | #![crate_type = "dylib"]
38 |
39 | #![doc(html_logo_url = "./icon.png")]
40 |
41 | #[cfg(feature = "rustc-serialize")]
42 | extern crate rustc_serialize as rustc_serialize_crate;
43 | extern crate byteorder;
44 | extern crate num_traits;
45 | #[cfg(feature = "serde")]
46 | extern crate serde as serde_crate;
47 | extern crate bit_vec;
48 | // extern crate bitpack as bit_pack;
49 | extern crate leb128;
50 | extern crate conv;
51 | extern crate half;
52 |
53 | pub use refbox::{RefBox, StrBox, SliceBox};
54 | pub use bitvec::{BVec, BitVec};
55 | // pub use bitpack::{BPack, BitPack};
56 | pub use float::FloatEncoding;
57 |
58 | mod refbox;
59 | mod bitvec;
60 | // mod bitpack;
61 | mod float;
62 |
63 | #[cfg(feature = "rustc-serialize")]
64 | pub mod rustc_serialize;
65 | #[cfg(feature = "serde")]
66 | pub mod serde;
67 |
68 | /// A limit on the amount of bytes that can be read or written.
69 | ///
70 | /// Size limits are an incredibly important part of both encoding and decoding.
71 | ///
72 | /// In order to prevent DOS attacks on a decoder, it is important to limit the
73 | /// amount of bytes that a single encoded message can be; otherwise, if you
74 | /// are decoding bytes right off of a TCP stream for example, it would be
75 | /// possible for an attacker to flood your server with a 3TB vec, causing the
76 | /// decoder to run out of memory and crash your application!
77 | /// Because of this, you can provide a maximum-number-of-bytes that can be read
78 | /// during decoding, and the decoder will explicitly fail if it has to read
79 | /// any more than that.
80 | ///
81 | /// On the other side, you want to make sure that you aren't encoding a message
82 | /// that is larger than your decoder expects. By supplying a size limit to an
83 | /// encoding function, the encoder will verify that the structure can be encoded
84 | /// within that limit. This verification occurs before any bytes are written to
85 | /// the Writer, so recovering from an error is easy.
86 | #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
87 | pub enum SizeLimit {
88 | Infinite,
89 | Bounded(u64)
90 | }
91 |
--------------------------------------------------------------------------------
/src/refbox.rs:
--------------------------------------------------------------------------------
1 | use std::boxed::Box;
2 | use std::ops::Deref;
3 |
4 | #[cfg(feature = "rustc-serialize")]
5 | use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder};
6 |
7 | #[cfg(feature = "serde")]
8 | use serde_crate as serde;
9 |
10 | /// A struct for encoding nested reference types.
11 | ///
12 | /// Encoding large objects by reference is really handy. For example,
13 | /// `encode(&large_hashmap, ...)` encodes the large structure without having to
14 | /// own the hashmap. However, it is impossible to serialize a reference if that
15 | /// reference is inside of a struct.
16 | ///
17 | /// ```ignore rust
18 | /// // Not possible, rustc can not decode the reference.
19 | /// #[derive(RustcEncoding, RustcDecoding)]
20 | /// struct Message<'a> {
21 | /// big_map: &'a HashMap,
22 | /// message_type: String,
23 | /// }
24 | /// ```
25 | ///
26 | /// This is because on the decoding side, you can't create the Message struct
27 | /// because it needs to have a reference to a HashMap, which is impossible because
28 | /// during deserialization, all members need to be owned by the deserialized
29 | /// object.
30 | ///
31 | /// This is where RefBox comes in. During serialization, it serializs a reference,
32 | /// but during deserialization, it puts that sub-object into a box!
33 | ///
34 | /// ```ignore rust
35 | /// // This works!
36 | /// #[derive(RustcEncoding, RustcDecoding)]
37 | /// struct Message<'a> {
38 | /// big_map: RefBox<'a, HashMap>,
39 | /// message_type: String
40 | /// }
41 | /// ```
42 | ///
43 | /// Now we can write
44 | ///
45 | /// ```ignore rust
46 | /// let my_map = HashMap::new();
47 | /// let my_msg = Message {
48 | /// big_map: RefBox::new(&my_map),
49 | /// message_type: "foo".to_string()
50 | /// };
51 | ///
52 | /// let encoded = encode(&my_msg, ...).unwrap();
53 | /// let decoded: Message<'static> = decode(&encoded[]).unwrap();
54 | /// ```
55 | ///
56 | /// Notice that we managed to encode and decode a struct with a nested reference
57 | /// and that the decoded message has the lifetime `'static` which shows us
58 | /// that the message owns everything inside it completely.
59 | ///
60 | /// Please don't stick RefBox inside deep data structures. It is much better
61 | /// suited in the outermost layer of whatever it is that you are encoding.
62 | #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
63 | pub struct RefBox<'a, T: 'a> {
64 | inner: RefBoxInner<'a, T, Box>
65 | }
66 |
67 | /// Like a RefBox, but encoding from a `str` and decoedes to a `String`.
68 | #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
69 | pub struct StrBox<'a> {
70 | inner: RefBoxInner<'a, str, String>
71 | }
72 |
73 | /// Like a RefBox, but encodes from a `[T]` and encodes to a `Vec`.
74 | #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
75 | pub struct SliceBox<'a, T: 'a> {
76 | inner: RefBoxInner<'a, [T], Vec>
77 | }
78 |
79 | #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
80 | enum RefBoxInner<'a, A: 'a + ?Sized, B> {
81 | Ref(&'a A),
82 | Box(B)
83 | }
84 |
85 | impl<'a, T> Clone for RefBoxInner<'a, T, Box> where T: Clone {
86 | fn clone(&self) -> RefBoxInner<'a, T, Box> {
87 | match *self {
88 | RefBoxInner::Ref(reff) => RefBoxInner::Box(Box::new(reff.clone())),
89 | RefBoxInner::Box(ref boxed) => RefBoxInner::Box(boxed.clone())
90 | }
91 | }
92 | }
93 |
94 | impl<'a> Clone for RefBoxInner<'a, str, String> {
95 | fn clone(&self) -> RefBoxInner<'a, str, String> {
96 | match *self {
97 | RefBoxInner::Ref(reff) => RefBoxInner::Box(String::from(reff)),
98 | RefBoxInner::Box(ref boxed) => RefBoxInner::Box(boxed.clone())
99 | }
100 | }
101 | }
102 |
103 | impl<'a, T> Clone for RefBoxInner<'a, [T], Vec> where T: Clone {
104 | fn clone(&self) -> RefBoxInner<'a, [T], Vec> {
105 | match *self {
106 | RefBoxInner::Ref(reff) => RefBoxInner::Box(Vec::from(reff)),
107 | RefBoxInner::Box(ref boxed) => RefBoxInner::Box(boxed.clone())
108 | }
109 | }
110 | }
111 |
112 | impl <'a, T> RefBox<'a, T> {
113 | /// Creates a new RefBox that looks at a borrowed value.
114 | pub fn new(v: &'a T) -> RefBox<'a, T> {
115 | RefBox {
116 | inner: RefBoxInner::Ref(v)
117 | }
118 | }
119 | }
120 |
121 | impl RefBox<'static, T> {
122 | /// Takes the value out of this refbox.
123 | ///
124 | /// Fails if this refbox was not created out of a deserialization.
125 | ///
126 | /// Unless you are doing some really weird things with static references,
127 | /// this function will never fail.
128 | pub fn take(self) -> Box {
129 | match self.inner {
130 | RefBoxInner::Box(b) => b,
131 | _ => unreachable!()
132 | }
133 | }
134 |
135 | /// Tries to take the value out of this refbox.
136 | pub fn try_take(self) -> Result, RefBox<'static, T>> {
137 | match self.inner {
138 | RefBoxInner::Box(b) => Ok(b),
139 | o => Err(RefBox{ inner: o})
140 | }
141 | }
142 | }
143 |
144 | #[cfg(feature = "rustc-serialize")]
145 | impl <'a, T: Encodable> Encodable for RefBox<'a, T> {
146 | fn encode(&self, s: &mut S) -> Result<(), S::Error> {
147 | self.inner.encode(s)
148 | }
149 | }
150 |
151 | #[cfg(feature = "rustc-serialize")]
152 | impl Decodable for RefBox<'static, T> {
153 | fn decode(d: &mut D) -> Result, D::Error> {
154 | let inner = try!(Decodable::decode(d));
155 | Ok(RefBox{inner: inner})
156 | }
157 | }
158 |
159 | #[cfg(feature = "serde")]
160 | impl<'a, T> serde::Serialize for RefBox<'a, T>
161 | where T: serde::Serialize,
162 | {
163 | fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
164 | where S: serde::Serializer
165 | {
166 | serde::Serialize::serialize(&self.inner, serializer)
167 | }
168 | }
169 |
170 | #[cfg(feature = "serde")]
171 | impl<'a, T: serde::Deserialize> serde::Deserialize for RefBox<'a, T> {
172 | fn deserialize(deserializer: &mut D) -> Result
173 | where D: serde::Deserializer
174 | {
175 | let inner = try!(serde::Deserialize::deserialize(deserializer));
176 | Ok(RefBox{ inner: inner })
177 | }
178 | }
179 |
180 | impl<'a> StrBox<'a> {
181 | /// Creates a new StrBox that looks at a borrowed value.
182 | pub fn new(s: &'a str) -> StrBox<'a> {
183 | StrBox {
184 | inner: RefBoxInner::Ref(s)
185 | }
186 | }
187 |
188 | /// Extract a String from a StrBox.
189 | pub fn into_string(self) -> String {
190 | match self.inner {
191 | RefBoxInner::Ref(s) => String::from(s),
192 | RefBoxInner::Box(s) => s
193 | }
194 | }
195 |
196 | /// Convert to an Owned `SliceBox`.
197 | pub fn to_owned(self) -> StrBox<'static> {
198 | match self.inner {
199 | RefBoxInner::Ref(s) => StrBox::boxed(String::from(s)),
200 | RefBoxInner::Box(s) => StrBox::boxed(s)
201 | }
202 | }
203 | }
204 |
205 | impl<'a> AsRef for StrBox<'a> {
206 | fn as_ref(&self) -> &str {
207 | match self.inner {
208 | RefBoxInner::Ref(ref s) => s,
209 | RefBoxInner::Box(ref s) => s
210 | }
211 | }
212 | }
213 |
214 | impl StrBox<'static> {
215 | /// Creates a new StrBox made from an allocated String.
216 | pub fn boxed(s: String) -> StrBox<'static> {
217 | StrBox { inner: RefBoxInner::Box(s) }
218 | }
219 |
220 | /// Takes the value out of this refbox.
221 | ///
222 | /// Fails if this refbox was not created out of a deserialization.
223 | ///
224 | /// Unless you are doing some really weird things with static references,
225 | /// this function will never fail.
226 | pub fn take(self) -> String {
227 | match self.inner {
228 | RefBoxInner::Box(b) => b,
229 | RefBoxInner::Ref(b) => String::from(b)
230 | }
231 | }
232 |
233 | /// Tries to take the value out of this refbox.
234 | pub fn try_take(self) -> Result> {
235 | match self.inner {
236 | RefBoxInner::Box(b) => Ok(b),
237 | o => Err(StrBox{ inner: o})
238 | }
239 | }
240 | }
241 |
242 | #[cfg(feature = "rustc-serialize")]
243 | impl <'a> Encodable for StrBox<'a> {
244 | fn encode(&self, s: &mut S) -> Result<(), S::Error> {
245 | self.inner.encode(s)
246 | }
247 | }
248 |
249 | #[cfg(feature = "rustc-serialize")]
250 | impl Decodable for StrBox<'static> {
251 | fn decode(d: &mut D) -> Result, D::Error> {
252 | let inner: RefBoxInner<'static, str, String> = try!(Decodable::decode(d));
253 | Ok(StrBox{inner: inner})
254 | }
255 | }
256 |
257 | #[cfg(feature = "serde")]
258 | impl<'a> serde::Serialize for StrBox<'a> {
259 | fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
260 | where S: serde::Serializer
261 | {
262 | serde::Serialize::serialize(&self.inner, serializer)
263 | }
264 | }
265 |
266 | #[cfg(feature = "serde")]
267 | impl serde::Deserialize for StrBox<'static> {
268 | fn deserialize(deserializer: &mut D) -> Result
269 | where D: serde::Deserializer
270 | {
271 | let inner = try!(serde::Deserialize::deserialize(deserializer));
272 | Ok(StrBox{ inner: inner })
273 | }
274 | }
275 |
276 | //
277 | // SliceBox
278 | //
279 |
280 | impl <'a, T> SliceBox<'a, T> {
281 | /// Creates a new RefBox that looks at a borrowed value.
282 | pub fn new(v: &'a [T]) -> SliceBox<'a, T> {
283 | SliceBox {
284 | inner: RefBoxInner::Ref(v)
285 | }
286 | }
287 |
288 | /// Extract a `Vec` from a `SliceBox`.
289 | pub fn into_vec(self) -> Vec where T: Clone {
290 | match self.inner {
291 | RefBoxInner::Ref(s) => s.to_vec(),
292 | RefBoxInner::Box(s) => s
293 | }
294 | }
295 |
296 | /// Convert to an Owned `SliceBox`.
297 | pub fn to_owned(self) -> SliceBox<'static, T> where T: Clone {
298 | match self.inner {
299 | RefBoxInner::Ref(s) => SliceBox::boxed(s.to_vec()),
300 | RefBoxInner::Box(s) => SliceBox::boxed(s)
301 | }
302 | }
303 | }
304 |
305 | impl SliceBox<'static, T> {
306 | /// Creates a new SliceBox made from an allocated `Vec`.
307 | pub fn boxed(s: Vec) -> SliceBox<'static, T> {
308 | SliceBox { inner: RefBoxInner::Box(s) }
309 | }
310 |
311 | /// Takes the value out of this refbox.
312 | ///
313 | /// Fails if this refbox was not created out of a deserialization.
314 | ///
315 | /// Unless you are doing some really weird things with static references,
316 | /// this function will never fail.
317 | pub fn take(self) -> Vec {
318 | match self.inner {
319 | RefBoxInner::Box(b) => b,
320 | _ => unreachable!()
321 | }
322 | }
323 |
324 | /// Tries to take the value out of this refbox.
325 | pub fn try_take(self) -> Result, SliceBox<'static, T>> {
326 | match self.inner {
327 | RefBoxInner::Box(b) => Ok(b),
328 | o => Err(SliceBox{ inner: o})
329 | }
330 | }
331 | }
332 |
333 | #[cfg(feature = "rustc-serialize")]
334 | impl <'a, T: Encodable> Encodable for SliceBox<'a, T> {
335 | fn encode(&self, s: &mut S) -> Result<(), S::Error> {
336 | self.inner.encode(s)
337 | }
338 | }
339 |
340 | #[cfg(feature = "rustc-serialize")]
341 | impl Decodable for SliceBox<'static, T> {
342 | fn decode(d: &mut D) -> Result, D::Error> {
343 | let inner: RefBoxInner<'static, [T], Vec> = try!(Decodable::decode(d));
344 | Ok(SliceBox{inner: inner})
345 | }
346 | }
347 |
348 | #[cfg(feature = "serde")]
349 | impl<'a, T> serde::Serialize for SliceBox<'a, T>
350 | where T: serde::Serialize,
351 | {
352 | fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
353 | where S: serde::Serializer
354 | {
355 | serde::Serialize::serialize(&self.inner, serializer)
356 | }
357 | }
358 |
359 | #[cfg(feature = "serde")]
360 | impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> {
361 | fn deserialize(deserializer: &mut D) -> Result
362 | where D: serde::Deserializer
363 | {
364 | let inner = try!(serde::Deserialize::deserialize(deserializer));
365 | Ok(SliceBox{ inner: inner })
366 | }
367 | }
368 |
369 | #[cfg(feature = "rustc-serialize")]
370 | impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, B> {
371 | fn encode(&self, s: &mut S) -> Result<(), S::Error> {
372 | match self {
373 | &RefBoxInner::Ref(ref r) => r.encode(s),
374 | &RefBoxInner::Box(ref b) => b.encode(s)
375 | }
376 | }
377 | }
378 |
379 | #[cfg(feature = "serde")]
380 | impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B>
381 | where A: serde::Serialize,
382 | B: serde::Serialize,
383 | {
384 | fn serialize(&self, serializer: &mut S) -> Result<(), S::Error>
385 | where S: serde::Serializer
386 | {
387 | match self {
388 | &RefBoxInner::Ref(ref r) => serde::Serialize::serialize(r, serializer),
389 | &RefBoxInner::Box(ref b) => serde::Serialize::serialize(b, serializer),
390 | }
391 | }
392 | }
393 |
394 | #[cfg(feature = "rustc-serialize")]
395 | impl Decodable for RefBoxInner<'static, A, B> {
396 | fn decode(d: &mut D) -> Result, D::Error> {
397 | let decoded = try!(Decodable::decode(d));
398 | Ok(RefBoxInner::Box(decoded))
399 | }
400 | }
401 |
402 | #[cfg(feature = "serde")]
403 | impl<'a, A: ?Sized, B> serde::Deserialize for RefBoxInner<'a, A, B>
404 | where B: serde::Deserialize,
405 | {
406 | fn deserialize(deserializer: &mut D) -> Result
407 | where D: serde::Deserializer
408 | {
409 | let deserialized = try!(serde::Deserialize::deserialize(deserializer));
410 | Ok(RefBoxInner::Box(deserialized))
411 | }
412 | }
413 |
414 | impl <'a, T> Deref for RefBox<'a, T> {
415 | type Target = T;
416 |
417 | fn deref(&self) -> &T {
418 | match &self.inner {
419 | &RefBoxInner::Ref(ref t) => t,
420 | &RefBoxInner::Box(ref b) => b.deref()
421 | }
422 | }
423 | }
424 |
425 | impl <'a, T> Deref for SliceBox<'a, T> {
426 | type Target = [T];
427 |
428 | fn deref(&self) -> &[T] {
429 | match &self.inner {
430 | &RefBoxInner::Ref(ref t) => t,
431 | &RefBoxInner::Box(ref b) => b.deref()
432 | }
433 | }
434 | }
435 |
--------------------------------------------------------------------------------
/src/rustc_serialize/mod.rs:
--------------------------------------------------------------------------------
1 | //! A collection of serialization and deserialization functions
2 | //! that use the `rustc_serialize` crate for the encodable and decodable
3 | //! implementation.
4 |
5 | use rustc_serialize_crate::{Encodable, Decodable};
6 | use std::io::{Write, Read};
7 | use ::{SizeLimit, FloatEncoding};
8 |
9 | pub use self::writer::{SizeChecker, EncoderWriter, EncodingResult, EncodingError};
10 | pub use self::reader::{DecoderReader, DecodingResult, DecodingError, InvalidEncoding};
11 |
12 | mod reader;
13 | mod writer;
14 |
15 | /// Encodes an encodable object into a `Vec` of bytes.
16 | ///
17 | /// If the encoding would take more bytes than allowed by `size_limit`,
18 | /// an error is returned.
19 | pub fn encode(t: &T, size_limit: SizeLimit, float_enc: FloatEncoding) -> EncodingResult> {
20 | // Since we are putting values directly into a vector, we can do size
21 | // computation out here and pre-allocate a buffer of *exactly*
22 | // the right size.
23 | let mut w = if let SizeLimit::Bounded(l) = size_limit {
24 | let actual_size = encoded_size_bounded(t, l, float_enc);
25 | let actual_size = try!(actual_size.ok_or(EncodingError::SizeLimit));
26 | Vec::with_capacity(actual_size as usize)
27 | } else {
28 | vec![]
29 | };
30 |
31 | match encode_into(t, &mut w, SizeLimit::Infinite, float_enc) {
32 | Ok(()) => Ok(w),
33 | Err(e) => Err(e)
34 | }
35 | }
36 |
37 | /// Decodes a slice of bytes into an object.
38 | ///
39 | /// This method does not have a size-limit because if you already have the bytes
40 | /// in memory, then you don't gain anything by having a limiter.
41 | pub fn decode(b: &[u8], float_enc: FloatEncoding) -> DecodingResult {
42 | let mut b = b;
43 | decode_from(&mut b, SizeLimit::Infinite, float_enc)
44 | }
45 |
46 | /// Encodes an object directly into a `Writer`.
47 | ///
48 | /// If the encoding would take more bytes than allowed by `size_limit`, an error
49 | /// is returned and *no bytes* will be written into the `Writer`.
50 | ///
51 | /// If this returns an `EncodingError` (other than SizeLimit), assume that the
52 | /// writer is in an invalid state, as writing could bail out in the middle of
53 | /// encoding.
54 | pub fn encode_into(t: &T,
55 | w: &mut W,
56 | size_limit: SizeLimit,
57 | float_enc: FloatEncoding)
58 | -> EncodingResult<()> {
59 | match size_limit {
60 | SizeLimit::Infinite => (),
61 | SizeLimit::Bounded(x) => {
62 | let mut size_checker = SizeChecker::new(x, float_enc);
63 | t.encode(&mut size_checker)?;
64 | }
65 | }
66 |
67 | t.encode(&mut writer::EncoderWriter::new(w, float_enc))
68 | }
69 |
70 | /// Decoes an object directly from a `Buffer`ed Reader.
71 | ///
72 | /// If the provided `SizeLimit` is reached, the decode will bail immediately.
73 | /// A SizeLimit can help prevent an attacker from flooding your server with
74 | /// a neverending stream of values that runs your server out of memory.
75 | ///
76 | /// If this returns an `DecodingError`, assume that the buffer that you passed
77 | /// in is in an invalid state, as the error could be returned during any point
78 | /// in the reading.
79 | pub fn decode_from(r: &mut R, size_limit: SizeLimit, float_enc: FloatEncoding) -> DecodingResult {
80 | Decodable::decode(&mut reader::DecoderReader::new(r, size_limit, float_enc))
81 | }
82 |
83 |
84 | /// Returns the size that an object would be if encoded using bincode.
85 | ///
86 | /// This is used internally as part of the check for encode_into, but it can
87 | /// be useful for preallocating buffers if thats your style.
88 | pub fn encoded_size(t: &T, float_enc: FloatEncoding) -> u64 {
89 | use std::u64::MAX;
90 | let mut size_checker = SizeChecker::new(MAX, float_enc);
91 | t.encode(&mut size_checker).ok();
92 | size_checker.written
93 | }
94 |
95 | /// Given a maximum size limit, check how large an object would be if it
96 | /// were to be encoded.
97 | ///
98 | /// If it can be encoded in `max` or fewer bytes, that number will be returned
99 | /// inside `Some`. If it goes over bounds, then None is returned.
100 | pub fn encoded_size_bounded(t: &T, max: u64, float_enc: FloatEncoding) -> Option {
101 | let mut size_checker = SizeChecker::new(max, float_enc);
102 | t.encode(&mut size_checker).ok().map(|_| size_checker.written)
103 | }
104 |
--------------------------------------------------------------------------------
/src/rustc_serialize/reader.rs:
--------------------------------------------------------------------------------
1 | use std::io::Read;
2 | use std::io::Error as IoError;
3 | use std::error::Error;
4 | use std::fmt;
5 | use std::convert::From;
6 |
7 | use byteorder::ReadBytesExt;
8 | use num_traits;
9 | use rustc_serialize_crate::Decoder;
10 |
11 | use ::SizeLimit;
12 |
13 | use conv::*;
14 | use leb128;
15 |
16 | use float::*;
17 |
18 | #[derive(Eq, PartialEq, Clone, Debug)]
19 | pub struct InvalidEncoding {
20 | pub desc: &'static str,
21 | pub detail: Option,
22 | }
23 |
24 | impl fmt::Display for InvalidEncoding {
25 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
26 | match *self {
27 | InvalidEncoding { detail: None, desc } =>
28 | write!(fmt, "{}", desc),
29 | InvalidEncoding { detail: Some(ref detail), desc } =>
30 | write!(fmt, "{} ({})", desc, detail)
31 | }
32 | }
33 | }
34 |
35 | /// An error that can be produced during decoding.
36 | ///
37 | /// If decoding from a Buffer, assume that the buffer has been left
38 | /// in an invalid state.
39 | #[derive(Debug)]
40 | pub enum DecodingError {
41 | /// If the error stems from the reader that is being used
42 | /// during decoding, that error will be stored and returned here.
43 | IoError(IoError),
44 | /// If the bytes in the reader are not decodable because of an invalid
45 | /// encoding, this error will be returned. This error is only possible
46 | /// if a stream is corrupted. A stream produced from `encode` or `encode_into`
47 | /// should **never** produce an InvalidEncoding error.
48 | InvalidEncoding(InvalidEncoding),
49 | /// If decoding a message takes more than the provided size limit, this
50 | /// error is returned.
51 | SizeLimit
52 | }
53 |
54 | pub type DecodingResult = Result;
55 |
56 | fn wrap_io(err: IoError) -> DecodingError {
57 | DecodingError::IoError(err)
58 | }
59 |
60 | impl fmt::Display for DecodingError {
61 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
62 | match *self {
63 | DecodingError::IoError(ref ioerr) =>
64 | write!(fmt, "IoError: {}", ioerr),
65 | DecodingError::InvalidEncoding(ref ib) =>
66 | write!(fmt, "InvalidEncoding: {}", ib),
67 | DecodingError::SizeLimit =>
68 | write!(fmt, "SizeLimit")
69 | }
70 | }
71 | }
72 |
73 | impl Error for DecodingError {
74 | fn description(&self) -> &str {
75 | match *self {
76 | DecodingError::IoError(ref err) => Error::description(err),
77 | DecodingError::InvalidEncoding(ref ib) => ib.desc,
78 | DecodingError::SizeLimit => "the size limit for decoding has been reached"
79 | }
80 | }
81 |
82 | fn cause(&self) -> Option<&Error> {
83 | match *self {
84 | DecodingError::IoError(ref err) => err.cause(),
85 | DecodingError::InvalidEncoding(_) => None,
86 | DecodingError::SizeLimit => None
87 | }
88 | }
89 | }
90 |
91 | impl From for DecodingError {
92 | fn from(err: IoError) -> DecodingError {
93 | DecodingError::IoError(err)
94 | }
95 | }
96 |
97 | /// A Decoder that reads bytes from a buffer.
98 | ///
99 | /// This struct should rarely be used.
100 | /// In most cases, prefer the `decode_from` function.
101 | ///
102 | /// ```rust,ignore
103 | /// let dr = bincode::rustc_serialize::DecoderReader::new(&mut some_reader, SizeLimit::Infinite);
104 | /// let result: T = Decodable::decode(&mut dr);
105 | /// let bytes_read = dr.bytes_read();
106 | /// ```
107 | pub struct DecoderReader<'a, R: 'a> {
108 | reader: &'a mut R,
109 | size_limit: SizeLimit,
110 | read: u64,
111 | read_f32: FloatDecoder,
112 | read_f64: FloatDecoder,
113 | }
114 |
115 | impl<'a, R: Read> DecoderReader<'a, R> {
116 | pub fn new(r: &'a mut R, size_limit: SizeLimit, float_enc: FloatEncoding) -> DecoderReader<'a, R> {
117 | let (read_f32, read_f64) = float_decoder(float_enc);
118 | DecoderReader {
119 | reader: r,
120 | size_limit: size_limit,
121 | read: 0,
122 | read_f32: read_f32,
123 | read_f64: read_f64,
124 | }
125 | }
126 |
127 | /// Returns the number of bytes read from the contained Reader.
128 | pub fn bytes_read(&self) -> u64 {
129 | self.read
130 | }
131 |
132 | fn read_unsigned + misc::Saturated + num_traits::Unsigned>(&mut self) -> DecodingResult
133 | where RangeErrorKind: From<>::Err> {
134 | let r = leb128::read::unsigned(&mut self.reader); //.map(|(v, n)| (v as usize, n));
135 | self.map_leb128_result::(r)
136 | }
137 |
138 | fn read_signed + misc::Saturated + num_traits::Signed>(&mut self) -> DecodingResult
139 | where RangeErrorKind: From<>::Err> {
140 | let r = leb128::read::signed(&mut self.reader); //.map(|(v, n)| (v as isize, n));
141 | self.map_leb128_result::(r)
142 | }
143 |
144 | fn map_leb128_result + misc::Saturated, U: ValueFrom>(&mut self, r: Result<(U, usize), leb128::read::Error>) -> DecodingResult
145 | where RangeErrorKind: From<>::Err> {
146 | match r {
147 | Ok((v, bytes_read)) => {
148 | self.read_bytes(bytes_read as u64)?;
149 | // Ok(v.value_into().unwrap_or_saturate())
150 | match v.value_into() {
151 | Ok(v) => Ok(v),
152 | Err(_) => Err(DecodingError::SizeLimit)
153 | }
154 | }
155 | Err(e) => Err(match e {
156 | leb128::read::Error::IoError(e) => DecodingError::IoError(e),
157 | leb128::read::Error::Overflow => DecodingError::SizeLimit
158 | })
159 | }
160 | }
161 | }
162 |
163 | impl <'a, A> DecoderReader<'a, A> {
164 | #[inline]
165 | fn read_bytes(&mut self, count: u64) -> Result<(), DecodingError> {
166 | self.read = match self.read.checked_add(count) {
167 | Some(read) => read,
168 | None => return Err(DecodingError::SizeLimit),
169 | };
170 | match self.size_limit {
171 | SizeLimit::Infinite => Ok(()),
172 | SizeLimit::Bounded(x) if self.read <= x => Ok(()),
173 | SizeLimit::Bounded(_) => Err(DecodingError::SizeLimit)
174 | }
175 | }
176 |
177 | /*fn read_type(&mut self) -> Result<(), DecodingError> {
178 | use std::mem::size_of;
179 | self.read_bytes(size_of::() as u64)
180 | }*/
181 | }
182 |
183 | impl<'a, R: Read> Decoder for DecoderReader<'a, R> {
184 | type Error = DecodingError;
185 |
186 | fn read_nil(&mut self) -> DecodingResult<()> {
187 | Ok(())
188 | }
189 | fn read_usize(&mut self) -> DecodingResult {
190 | self.read_unsigned::<_>()
191 | }
192 | fn read_u64(&mut self) -> DecodingResult {
193 | self.read_unsigned::<_>()
194 | }
195 | fn read_u32(&mut self) -> DecodingResult {
196 | self.read_unsigned::<_>()
197 | }
198 | fn read_u16(&mut self) -> DecodingResult {
199 | self.read_unsigned::<_>()
200 | }
201 | fn read_u8(&mut self) -> DecodingResult {
202 | self.read_bytes(1)?;
203 | self.reader.read_u8().map_err(wrap_io)
204 | }
205 | fn read_isize(&mut self) -> DecodingResult {
206 | self.read_signed::<_>()
207 | }
208 | fn read_i64(&mut self) -> DecodingResult {
209 | self.read_signed::<_>()
210 | }
211 | fn read_i32(&mut self) -> DecodingResult {
212 | self.read_signed::<_>()
213 | }
214 | fn read_i16(&mut self) -> DecodingResult {
215 | self.read_signed::<_>()
216 | }
217 | fn read_i8(&mut self) -> DecodingResult {
218 | self.read_bytes(1)?;
219 | self.reader.read_i8().map_err(wrap_io)
220 | }
221 | fn read_bool(&mut self) -> DecodingResult {
222 | let x = self.read_i8()?;
223 | match x {
224 | 1 => Ok(true),
225 | 0 => Ok(false),
226 | _ => Err(DecodingError::InvalidEncoding(InvalidEncoding{
227 | desc: "invalid u8 when decoding bool",
228 | detail: Some(format!("Expected 0 or 1, got {}", x))
229 | })),
230 | }
231 | }
232 | fn read_f64(&mut self) -> DecodingResult {
233 | // self.reader.read_f64::().map_err(wrap_io)
234 | (self.read_f64)(&mut self.reader).map_err(wrap_io)
235 | }
236 | fn read_f32(&mut self) -> DecodingResult {
237 | // self.reader.read_f32::().map_err(wrap_io)
238 | (self.read_f32)(&mut self.reader).map_err(wrap_io)
239 | }
240 | fn read_char(&mut self) -> DecodingResult {
241 | use std::str;
242 |
243 | let error = DecodingError::InvalidEncoding(InvalidEncoding {
244 | desc: "Invalid char encoding",
245 | detail: None
246 | });
247 |
248 | let mut buf = [0];
249 |
250 | let _ = try!(self.reader.read(&mut buf[..]));
251 | let first_byte = buf[0];
252 | let width = utf8_char_width(first_byte);
253 | if width == 1 { return Ok(first_byte as char) }
254 | if width == 0 { return Err(error)}
255 |
256 | let mut buf = [first_byte, 0, 0, 0];
257 | {
258 | let mut start = 1;
259 | while start < width {
260 | match try!(self.reader.read(&mut buf[start .. width])) {
261 | n if n == width - start => break,
262 | n if n < width - start => { start += n; }
263 | _ => return Err(error)
264 | }
265 | }
266 | }
267 |
268 | let res = try!(match str::from_utf8(&buf[..width]).ok() {
269 | Some(s) => Ok(s.chars().next().unwrap()),
270 | None => Err(error)
271 | });
272 |
273 | try!(self.read_bytes(res.len_utf8() as u64));
274 | Ok(res)
275 | }
276 |
277 | fn read_str(&mut self) -> DecodingResult {
278 | let len = self.read_usize()?;
279 |
280 | let mut buff = Vec::new();
281 | try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buff));
282 | match String::from_utf8(buff) {
283 | Ok(s) => Ok(s),
284 | Err(err) => Err(DecodingError::InvalidEncoding(InvalidEncoding {
285 | desc: "error while decoding utf8 string",
286 | detail: Some(format!("Decoding error: {}", err))
287 | })),
288 | }
289 | }
290 | fn read_enum(&mut self, _: &str, f: F) -> DecodingResult
291 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
292 | {
293 | f(self)
294 | }
295 | fn read_enum_variant(&mut self, names: &[&str], mut f: F) -> DecodingResult
296 | where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult
297 | {
298 | let id = self.read_unsigned::()?;
299 | if id >= names.len() {
300 | Err(DecodingError::InvalidEncoding(InvalidEncoding {
301 | desc: "out of bounds tag when reading enum variant",
302 | detail: Some(format!("Expected tag < {}, got {}", names.len(), id))
303 | }))
304 | } else {
305 | f(self, id)
306 | }
307 | }
308 | fn read_enum_variant_arg(&mut self, _: usize, f: F) -> DecodingResult
309 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
310 | {
311 | f(self)
312 | }
313 | fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> DecodingResult
314 | where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult
315 | {
316 | self.read_enum_variant(names, f)
317 | }
318 | fn read_enum_struct_variant_field(&mut self,
319 | _: &str,
320 | f_idx: usize,
321 | f: F)
322 | -> DecodingResult
323 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
324 | {
325 | self.read_enum_variant_arg(f_idx, f)
326 | }
327 | fn read_struct(&mut self, _: &str, _: usize, f: F) -> DecodingResult
328 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
329 | {
330 | f(self)
331 | }
332 | fn read_struct_field(&mut self, _: &str, _: usize, f: F) -> DecodingResult
333 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
334 | {
335 | f(self)
336 | }
337 | fn read_tuple(&mut self, _: usize, f: F) -> DecodingResult
338 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
339 | {
340 | f(self)
341 | }
342 | fn read_tuple_arg(&mut self, _: usize, f: F) -> DecodingResult
343 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
344 | {
345 | f(self)
346 | }
347 | fn read_tuple_struct(&mut self, _: &str, len: usize, f: F) -> DecodingResult
348 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
349 | {
350 | self.read_tuple(len, f)
351 | }
352 | fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) -> DecodingResult
353 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
354 | {
355 | self.read_tuple_arg(a_idx, f)
356 | }
357 | fn read_option(&mut self, mut f: F) -> DecodingResult
358 | where F: FnMut(&mut DecoderReader<'a, R>, bool) -> DecodingResult
359 | {
360 | let x = self.read_u8()?;
361 | match x {
362 | 1 => f(self, true),
363 | 0 => f(self, false),
364 | _ => Err(DecodingError::InvalidEncoding(InvalidEncoding {
365 | desc: "invalid tag when decoding Option",
366 | detail: Some(format!("Expected 0 or 1, got {}", x))
367 | })),
368 | }
369 | }
370 | fn read_seq(&mut self, f: F) -> DecodingResult
371 | where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult
372 | {
373 | let len = try!(self.read_usize());
374 | f(self, len)
375 | }
376 | fn read_seq_elt(&mut self, _: usize, f: F) -> DecodingResult
377 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
378 | {
379 | f(self)
380 | }
381 | fn read_map(&mut self, f: F) -> DecodingResult
382 | where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult
383 | {
384 | let len = try!(self.read_usize());
385 | f(self, len)
386 | }
387 | fn read_map_elt_key(&mut self, _: usize, f: F) -> DecodingResult
388 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
389 | {
390 | f(self)
391 | }
392 | fn read_map_elt_val(&mut self, _: usize, f: F) -> DecodingResult
393 | where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult
394 | {
395 | f(self)
396 | }
397 | fn error(&mut self, err: &str) -> DecodingError {
398 | DecodingError::InvalidEncoding(InvalidEncoding {
399 | desc: "user-induced error",
400 | detail: Some(err.to_string()),
401 | })
402 | }
403 | }
404 |
405 | static UTF8_CHAR_WIDTH: [u8; 256] = [
406 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
407 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
408 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
409 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
410 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
411 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
412 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
413 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
414 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
415 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
416 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
417 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
418 | 0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
419 | 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
420 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
421 | 4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
422 | ];
423 |
424 | #[inline(always)]
425 | fn utf8_char_width(b: u8) -> usize {
426 | UTF8_CHAR_WIDTH[b as usize] as usize
427 | }
428 |
--------------------------------------------------------------------------------
/src/rustc_serialize/writer.rs:
--------------------------------------------------------------------------------
1 | use std::io::Write;
2 | use std::io::Error as IoError;
3 | use std::error::Error;
4 | use std::fmt;
5 |
6 | use rustc_serialize_crate::Encoder;
7 |
8 | use byteorder::WriteBytesExt;
9 |
10 | use leb128;
11 |
12 | use float::*;
13 |
14 | pub type EncodingResult = Result;
15 |
16 |
17 | /// An error that can be produced during encoding.
18 | #[derive(Debug)]
19 | pub enum EncodingError {
20 | /// An error originating from the underlying `Writer`.
21 | IoError(IoError),
22 | /// An object could not be encoded with the given size limit.
23 | ///
24 | /// This error is returned before any bytes are written to the
25 | /// output `Writer`.
26 | SizeLimit,
27 | }
28 |
29 | /// An Encoder that encodes values directly into a Writer.
30 | ///
31 | /// This struct should not be used often.
32 | /// For most cases, prefer the `encode_into` function.
33 | pub struct EncoderWriter<'a, W: 'a> {
34 | writer: &'a mut W,
35 | write_f32: FloatEncoder,
36 | write_f64: FloatEncoder,
37 | }
38 |
39 | pub struct SizeChecker {
40 | pub size_limit: u64,
41 | pub written: u64,
42 | float_size_f32: usize,
43 | float_size_f64: usize,
44 | }
45 |
46 | fn wrap_io(err: IoError) -> EncodingError {
47 | EncodingError::IoError(err)
48 | }
49 |
50 | impl fmt::Display for EncodingError {
51 | fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
52 | match *self {
53 | EncodingError::IoError(ref err) => write!(f, "IoError: {}", err),
54 | EncodingError::SizeLimit => write!(f, "SizeLimit")
55 | }
56 | }
57 | }
58 |
59 | impl Error for EncodingError {
60 | fn description(&self) -> &str {
61 | match *self {
62 | EncodingError::IoError(ref err) => Error::description(err),
63 | EncodingError::SizeLimit => "the size limit for decoding has been reached"
64 | }
65 | }
66 |
67 | fn cause(&self) -> Option<&Error> {
68 | match *self {
69 | EncodingError::IoError(ref err) => err.cause(),
70 | EncodingError::SizeLimit => None
71 | }
72 | }
73 | }
74 |
75 | impl <'a, W: Write> EncoderWriter<'a, W> {
76 | pub fn new(w: &'a mut W, float_enc: FloatEncoding) -> EncoderWriter<'a, W> {
77 | let (write_f32, write_f64) = float_encoder(float_enc);
78 | EncoderWriter {
79 | writer: w,
80 | write_f32: write_f32,
81 | write_f64: write_f64,
82 | }
83 | }
84 |
85 | fn write_unsigned>(&mut self, v: T) -> EncodingResult<()> {
86 | leb128::write::unsigned(&mut self.writer, v.into()).map(|_| ()).map_err(wrap_io)
87 | }
88 |
89 | fn write_signed>(&mut self, v: T) -> EncodingResult<()> {
90 | leb128::write::signed(&mut self.writer, v.into()).map(|_| ()).map_err(wrap_io)
91 | }
92 | }
93 |
94 | impl SizeChecker {
95 | pub fn new(limit: u64, float_enc: FloatEncoding) -> SizeChecker {
96 | let (float_size_f32, float_size_f64) = float_sizes(float_enc);
97 | SizeChecker {
98 | size_limit: limit,
99 | written: 0,
100 | float_size_f32: float_size_f32,
101 | float_size_f64: float_size_f64,
102 | }
103 | }
104 |
105 | fn add_raw(&mut self, size: usize) -> EncodingResult<()> {
106 | self.written += size as u64;
107 | if self.written <= self.size_limit {
108 | Ok(())
109 | } else {
110 | Err(EncodingError::SizeLimit)
111 | }
112 | }
113 |
114 | /*fn add_value(&mut self, _: T) -> EncodingResult<()> {
115 | use std::mem::size_of;
116 | self.add_raw(size_of::())
117 | }*/
118 |
119 | fn add_value_unsigned>(&mut self, t: T) -> EncodingResult<()> {
120 | let mut v: Vec = vec![];
121 | match leb128::write::unsigned(&mut v, t.into()) {
122 | Ok(n) => self.add_raw(n),
123 | Err(e) => Err(wrap_io(e))
124 | }
125 | }
126 |
127 | fn add_value_signed>(&mut self, t: T) -> EncodingResult<()> {
128 | let mut v: Vec = vec![];
129 | match leb128::write::signed(&mut v, t.into()) {
130 | Ok(n) => self.add_raw(n),
131 | Err(e) => Err(wrap_io(e))
132 | }
133 | }
134 | }
135 |
136 | impl<'a, W: Write> Encoder for EncoderWriter<'a, W> {
137 | type Error = EncodingError;
138 |
139 | fn emit_nil(&mut self) -> EncodingResult<()> {
140 | Ok(())
141 | }
142 | fn emit_usize(&mut self, v: usize) -> EncodingResult<()> {
143 | self.write_unsigned(v as u64)
144 | }
145 | fn emit_u64(&mut self, v: u64) -> EncodingResult<()> {
146 | self.write_unsigned(v)
147 | }
148 | fn emit_u32(&mut self, v: u32) -> EncodingResult<()> {
149 | self.write_unsigned(v)
150 | }
151 | fn emit_u16(&mut self, v: u16) -> EncodingResult<()> {
152 | self.write_unsigned(v)
153 | }
154 | fn emit_u8(&mut self, v: u8) -> EncodingResult<()> {
155 | self.writer.write_u8(v).map_err(wrap_io)
156 | }
157 | fn emit_isize(&mut self, v: isize) -> EncodingResult<()> {
158 | self.write_signed(v as i64)
159 | }
160 | fn emit_i64(&mut self, v: i64) -> EncodingResult<()> {
161 | self.write_signed(v)
162 | }
163 | fn emit_i32(&mut self, v: i32) -> EncodingResult<()> {
164 | self.write_signed(v)
165 | }
166 | fn emit_i16(&mut self, v: i16) -> EncodingResult<()> {
167 | self.write_signed(v)
168 | }
169 | fn emit_i8(&mut self, v: i8) -> EncodingResult<()> {
170 | self.writer.write_i8(v).map_err(wrap_io)
171 | }
172 | fn emit_bool(&mut self, v: bool) -> EncodingResult<()> {
173 | self.writer.write_u8(if v {1} else {0}).map_err(wrap_io)
174 | }
175 | fn emit_f64(&mut self, v: f64) -> EncodingResult<()> {
176 | //self.writer.write_f64::(v).map_err(wrap_io)
177 | (self.write_f64)(&mut self.writer, v).map_err(wrap_io)
178 | }
179 | fn emit_f32(&mut self, v: f32) -> EncodingResult<()> {
180 | //self.writer.write_f32::(v).map_err(wrap_io)
181 | (self.write_f32)(&mut self.writer, v).map_err(wrap_io)
182 | }
183 | fn emit_char(&mut self, v: char) -> EncodingResult<()> {
184 | // TODO: change this back once unicode works
185 | //let mut cbuf = [0; 4];
186 | //let sz = v.encode_utf8(&mut cbuf[..]).unwrap_or(0);
187 | //let ptr = &cbuf[..sz];
188 | //self.writer.write_all(ptr).map_err(EncodingError::IoError)
189 |
190 | let mut inter = String::with_capacity(1);
191 | inter.push(v);
192 | self.writer.write_all(inter.as_bytes()).map_err(EncodingError::IoError)
193 | }
194 | fn emit_str(&mut self, v: &str) -> EncodingResult<()> {
195 | try!(self.emit_usize(v.len()));
196 | self.writer.write_all(v.as_bytes()).map_err(EncodingError::IoError)
197 | }
198 | fn emit_enum(&mut self, __: &str, f: F) -> EncodingResult<()>
199 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
200 | {
201 | f(self)
202 | }
203 | fn emit_enum_variant(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()>
204 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
205 | {
206 | try!(self.write_unsigned(v_id as u64));
207 | f(self)
208 | }
209 | fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodingResult<()>
210 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
211 | {
212 | f(self)
213 | }
214 | fn emit_enum_struct_variant(&mut self,
215 | _: &str,
216 | _: usize,
217 | _: usize,
218 | f: F)
219 | -> EncodingResult<()>
220 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
221 | {
222 | f(self)
223 | }
224 | fn emit_enum_struct_variant_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
225 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
226 | {
227 | f(self)
228 | }
229 | fn emit_struct(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
230 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
231 | {
232 | f(self)
233 | }
234 | fn emit_struct_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
235 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
236 | {
237 | f(self)
238 | }
239 | fn emit_tuple(&mut self, _: usize, f: F) -> EncodingResult<()>
240 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
241 | {
242 | f(self)
243 | }
244 | fn emit_tuple_arg(&mut self, _: usize, f: F) -> EncodingResult<()>
245 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
246 | {
247 | f(self)
248 | }
249 | fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodingResult<()>
250 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
251 | {
252 | self.emit_tuple(len, f)
253 | }
254 | fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) -> EncodingResult<()>
255 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
256 | {
257 | self.emit_tuple_arg(f_idx, f)
258 | }
259 | fn emit_option(&mut self, f: F) -> EncodingResult<()>
260 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
261 | {
262 | f(self)
263 | }
264 | fn emit_option_none(&mut self) -> EncodingResult<()> {
265 | self.writer.write_u8(0).map_err(wrap_io)
266 | }
267 | fn emit_option_some(&mut self, f: F) -> EncodingResult<()>
268 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
269 | {
270 | try!(self.writer.write_u8(1).map_err(wrap_io));
271 | f(self)
272 | }
273 | fn emit_seq(&mut self, len: usize, f: F) -> EncodingResult<()>
274 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
275 | {
276 | try!(self.emit_usize(len));
277 | f(self)
278 | }
279 | fn emit_seq_elt(&mut self, _: usize, f: F) -> EncodingResult<()>
280 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
281 | {
282 | f(self)
283 | }
284 | fn emit_map(&mut self, len: usize, f: F) -> EncodingResult<()>
285 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
286 | {
287 | try!(self.emit_usize(len));
288 | f(self)
289 | }
290 | fn emit_map_elt_key(&mut self, _: usize, f: F) -> EncodingResult<()>
291 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
292 | {
293 | f(self)
294 | }
295 | fn emit_map_elt_val(&mut self, _: usize, f: F) -> EncodingResult<()>
296 | where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
297 | {
298 | f(self)
299 | }
300 |
301 | }
302 |
303 | impl Encoder for SizeChecker {
304 | type Error = EncodingError;
305 |
306 | fn emit_nil(&mut self) -> EncodingResult<()> {
307 | Ok(())
308 | }
309 | fn emit_usize(&mut self, v: usize) -> EncodingResult<()> {
310 | self.add_value_unsigned(v as u64)
311 | }
312 | fn emit_u64(&mut self, v: u64) -> EncodingResult<()> {
313 | self.add_value_unsigned(v)
314 | }
315 | fn emit_u32(&mut self, v: u32) -> EncodingResult<()> {
316 | self.add_value_unsigned(v)
317 | }
318 | fn emit_u16(&mut self, v: u16) -> EncodingResult<()> {
319 | self.add_value_unsigned(v)
320 | }
321 | fn emit_u8(&mut self, _: u8) -> EncodingResult<()> {
322 | self.add_value_unsigned(0 as u8)
323 | }
324 | fn emit_isize(&mut self, v: isize) -> EncodingResult<()> {
325 | self.add_value_signed(v as i64)
326 | }
327 | fn emit_i64(&mut self, v: i64) -> EncodingResult<()> {
328 | self.add_value_signed(v)
329 | }
330 | fn emit_i32(&mut self, v: i32) -> EncodingResult<()> {
331 | self.add_value_signed(v)
332 | }
333 | fn emit_i16(&mut self, v: i16) -> EncodingResult<()> {
334 | self.add_value_signed(v)
335 | }
336 | fn emit_i8(&mut self, v: i8) -> EncodingResult<()> {
337 | self.add_value_signed(v)
338 | }
339 | fn emit_bool(&mut self, _: bool) -> EncodingResult<()> {
340 | self.add_value_unsigned(0 as u8)
341 | }
342 | fn emit_f64(&mut self, _: f64) -> EncodingResult<()> {
343 | let bytes = self.float_size_f64;
344 | self.add_raw(bytes)
345 | }
346 | fn emit_f32(&mut self, _: f32) -> EncodingResult<()> {
347 | let bytes = self.float_size_f32;
348 | self.add_raw(bytes)
349 | }
350 | fn emit_char(&mut self, v: char) -> EncodingResult<()> {
351 | self.add_raw(v.len_utf8())
352 | }
353 | fn emit_str(&mut self, v: &str) -> EncodingResult<()> {
354 | self.add_value_unsigned(v.len() as u64)?;
355 | self.add_raw(v.len())
356 | }
357 | fn emit_enum(&mut self, __: &str, f: F) -> EncodingResult<()>
358 | where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
359 | {
360 | f(self)
361 | }
362 | fn emit_enum_variant(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()>
363 | where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
364 | {
365 | self.add_value_unsigned(v_id as u32)?;
366 | f(self)
367 | }
368 | fn emit_enum_variant_arg(&mut self, _: usize, f: F) -> EncodingResult<()>
369 | where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
370 | {
371 | f(self)
372 | }
373 | fn emit_enum_struct_variant(&mut self,
374 | _: &str,
375 | _: usize,
376 | _: usize,
377 | f: F)
378 | -> EncodingResult<()>
379 | where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
380 | {
381 | f(self)
382 | }
383 | fn emit_enum_struct_variant_field(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
384 | where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
385 | {
386 | f(self)
387 | }
388 | fn emit_struct(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
389 | where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
390 | {
391 | f(self)
392 | }
393 | fn emit_struct_field