Bug 1441588 - P2: Vendor rust crates. r=rillian

Pull updated cubeb-core 0.4.3
Remove bincode 0.8

MozReview-Commit-ID: GfGCBU2DWmN

--HG--
extra : rebase_source : 46b12f186d433c616d2e3d2d75b5bc6b1630b58f
This commit is contained in:
Dan Glastonbury 2018-03-03 14:32:06 +10:00
parent 7ec980ee2f
commit c2e44b92b4
21 changed files with 24 additions and 2322 deletions

25
Cargo.lock generated
View File

@ -52,7 +52,7 @@ dependencies = [
name = "audioipc"
version = "0.2.1"
dependencies = [
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -86,7 +86,7 @@ dependencies = [
[[package]]
name = "audioipc-server"
version = "0.2.1"
version = "0.2.2"
dependencies = [
"audioipc 0.2.1",
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -115,16 +115,6 @@ name = "binary-space-partition"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bincode"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bincode"
version = "0.9.1"
@ -429,7 +419,7 @@ name = "cubeb"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cubeb-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb-core 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -437,12 +427,12 @@ name = "cubeb-backend"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cubeb-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb-core 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cubeb-core"
version = "0.4.2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -758,7 +748,7 @@ name = "gkrust-shared"
version = "0.1.0"
dependencies = [
"audioipc-client 0.3.0",
"audioipc-server 0.2.1",
"audioipc-server 0.2.2",
"cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb-pulse 0.1.1",
"cubeb-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2238,7 +2228,6 @@ dependencies = [
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
"checksum bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3fb369af639822830328794eba2501b3479652fcd021b2aeb1ed4984202afd"
"checksum bindgen 0.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1657d607dd7a8e10b3181149f60f3b27ea0eac81058c09a1c791b8f6ead91f19"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
@ -2275,7 +2264,7 @@ dependencies = [
"checksum cstr-macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9f316203d1ea36f4f18316822806f6999aa3dc5ed1adf51e35b77e3b3933d78"
"checksum cubeb 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed237804b9799d1c29089e6cab3f4b7160186179981a61865feff13d55a902f8"
"checksum cubeb-backend 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f6d8f189a1cf9cce9aec45eb0aeb1d221514d788b89a1cd6bc2b76110ee4d81"
"checksum cubeb-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ac5bb9e9d8747ae2c0884c970852c158315d809e33ce7c6a7b42b80b6a376aa"
"checksum cubeb-core 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6558e6b99511df1b4e7ce219b26527b0cb0f6f56df2fd5877aa9473b7c7eafb"
"checksum cubeb-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fab28c0e152330f74bcbec1572c374397458957d5ad50605879352ec562f41aa"
"checksum darling 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3effd06d4057f275cb7858889f4952920bab78dd8ff0f6e7dfe0c8d2e67ed89"
"checksum darling_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "167dd3e235c2f1da16a635c282630452cdf49191eb05711de1bcd1d3d5068c00"

View File

@ -1 +0,0 @@
{"files":{".travis.yml":"f705a11b487bf71c41ebd8223cc1f3cbde0dfdfeea96a100af55e06e93397a1b","Cargo.toml":"b3ef32df664d22cfe4526f0022c8789e8976970b9e0982e1dd52f4f811134515","LICENSE.md":"90d7e062634054e6866d3c81e6a2b3058a840e6af733e98e80bdfe1a7dec6912","changelist.org":"936b58455e1c221539b73b5250302dcd96baa04a5d8536199d3351142addad57","examples/basic.rs":"ef6ab76936c8322b9f89fe8308311339c0bf7b413c5f88b5314b0035d49917a3","logo.png":"ebc5305aae938c1f834cf35302faa8be0f1b7b8c3c3beef5cf6b2f68b9628c35","readme.dev.md":"43bad3bcc13a5c057344d3ba7f64bd2b313f8c133d6afa068108df73e8e8facd","readme.md":"ca48b4a712089d792d449ef6e0e399efaf227dbcfcb141540684a16a2763583b","src/de/mod.rs":"8651e00130bd062e2305dcce8b68d777fff9877688e776b239778e18046dddaf","src/de/read.rs":"5abca51c6f0d93cc144914ed30bf2cfd0074ced09a0de8c3983997aaa471562d","src/internal.rs":"d9448e8467caf4cf24703626dab9e0d9420e98419e323ad7e611e4aeab525e4a","src/lib.rs":"998b85e103f8f5480ffeef43bd8430a66c061011055a053377f37dce32bf9088","src/ser/mod.rs":"0eeb467eeb8189fb935e4996cd45d1f292c401f92b00793907bd428f1bde421d","tests/test.rs":"26598b882a691caa5301a569e56e31567bfba5ffeab6f0ca67ebd95bfae679b0"},"package":"e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"}

View File

@ -1,5 +0,0 @@
language: rust
rust:
- stable
- beta
- nightly

View File

@ -1,20 +0,0 @@
[package]
name = "bincode"
version = "0.8.0"
authors = ["Ty Overby <ty@pre-alpha.com>", "Francesco Mazzoli <f@mazzo.li>", "David Tolnay <dtolnay@gmail.com>", "Daniel Griffen"]
repository = "https://github.com/TyOverby/bincode"
documentation = "https://docs.rs/bincode"
keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
license = "MIT"
description = "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!"
[dependencies]
byteorder = "1.0.0"
num-traits = "0.1.32"
serde = "1.*.*"
[dev-dependencies]
serde_bytes = "0.10.*"
serde_derive = "1.*.*"

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 Ty Overby
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,27 +0,0 @@
* 1.0.0
** Removed depricated rustc-serialize support
Rustc-serialize was a stopgap until projects like Serde were able to catch up.
With macros stabilization on its way, we are able to switch to serde without any
big user-friendliness issues. Major congratulations to Serde for coming this far!
** Moved Refbox, Strbox and Slicebox into a "refbox" module
Refbox, Strbox and Slicebox are still an integral piece of bincode, but since
they are mainly used by power-users, this move will make the crate API more organized
and easier for new users to understand.
** Upgraded to Serde 0.9.*
Serde 0.9.* gives us a better API surface area and allows use of procedural macros for
deriving serialize and deserialize implemenetations.
** Moved serde functions into global module
Since serde is the only supported serialization mechanism, it makes sense to have these
functions available at the top level.
** Added the ability to chose your own endian encoding.
This functionality is located in the endian_choice module.
** Changed SizeLimit to be a trait instead of an enum
Mostly for performance reasons.
** Removed RefBox / StrBox / SliceBox
Since rustc-serialize support was phased out, you can use `Cow<T>` with serde.

View File

@ -1,27 +0,0 @@
#[macro_use]
extern crate serde_derive;
extern crate bincode;
use bincode::{serialize, deserialize, Infinite};
#[derive(Serialize, Deserialize, PartialEq)]
struct Entity {
x: f32,
y: f32,
}
#[derive(Serialize, Deserialize, PartialEq)]
struct World(Vec<Entity>);
fn main() {
let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);
let encoded: Vec<u8> = serialize(&world, Infinite).unwrap();
// 8 bytes for the length of the vector, 4 bytes per float.
assert_eq!(encoded.len(), 8 + 4 * 4);
let decoded: World = deserialize(&encoded[..]).unwrap();
assert!(world == decoded);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

View File

@ -1,39 +0,0 @@
# Bincode
<img align="right" src="./logo.png" />
[![Build Status](https://travis-ci.org/TyOverby/bincode.svg)](https://travis-ci.org/TyOverby/bincode)
[![](http://meritbadge.herokuapp.com/bincode)](https://crates.io/crates/bincode)
A compact encoder / decoder pair that uses an binary zero-fluff encoding scheme.
The size of the encoded object will be the same or smaller than the size that
the object takes up in memory in a running Rust program.
In addition to exposing two simple funcitons that encode to Vec<u8> and decode
from Vec<u8>, binary-encode exposes a Reader/Writer API that makes it work
perfectly with other stream-based apis such as rust files, network streams,
and the [flate2-rs](https://github.com/alexcrichton/flate2-rs) compression
library.
[Api Documentation](http://tyoverby.github.io/bincode/bincode/)
## Example
^code(./examples/basic.rs)
## Details
The encoding (and thus decoding) proceeds unsurprisingly -- primitive
types are encoded according to the underlying `Writer`, tuples and
structs are encoded by encoding their fields one-by-one, and enums are
encoded by first writing out the tag representing the variant and
then the contents.
However, there are some implementation details to be aware of:
* `isize`/`usize` are encoded as `i64`/`u64`, for portability.
* enums variants are encoded as a `u32` instead that as a `uint`.
`u32` is enough for all practical uses.
* `str` is encoded as `(u64, &[u8])`, where the `u64` is the number of
bytes contained in the encoded string.

View File

@ -1,73 +0,0 @@
# Bincode
<img align="right" src="./logo.png" />
[![Build Status](https://travis-ci.org/TyOverby/bincode.svg)](https://travis-ci.org/TyOverby/bincode)
[![](http://meritbadge.herokuapp.com/bincode)](https://crates.io/crates/bincode)
[![](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)
A compact encoder / decoder pair that uses a binary zero-fluff encoding scheme.
The size of the encoded object will be the same or smaller than the size that
the object takes up in memory in a running Rust program.
In addition to exposing two simple functions that encode to Vec<u8> and decode
from Vec<u8>, binary-encode exposes a Reader/Writer API that makes it work
perfectly with other stream-based apis such as rust files, network streams,
and the [flate2-rs](https://github.com/alexcrichton/flate2-rs) compression
library.
## [Api Documentation](http://tyoverby.github.io/bincode/bincode/)
## Bincode in the wild
* [google/tarpc](https://github.com/google/tarpc): Bincode is used to serialize and deserialize networked RPC messages.
* [servo/webrender](https://github.com/servo/webrender): Bincode records webrender API calls for record/replay-style graphics debugging.
* [servo/ipc-channel](https://github.com/servo/ipc-channel): Ipc-Channel uses Bincode to send structs between processes using a channel-like API.
## Example
```rust
#[macro_use]
extern crate serde_derive;
extern crate bincode;
use bincode::{serialize, deserialize, Infinite};
#[derive(Serialize, Deserialize, PartialEq)]
struct Entity {
x: f32,
y: f32,
}
#[derive(Serialize, Deserialize, PartialEq)]
struct World(Vec<Entity>);
fn main() {
let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);
let encoded: Vec<u8> = serialize(&world, Infinite).unwrap();
// 8 bytes for the length of the vector, 4 bytes per float.
assert_eq!(encoded.len(), 8 + 4 * 4);
let decoded: World = deserialize(&encoded[..]).unwrap();
assert!(world == decoded);
}
```
## Details
The encoding (and thus decoding) proceeds unsurprisingly -- primitive
types are encoded according to the underlying `Writer`, tuples and
structs are encoded by encoding their fields one-by-one, and enums are
encoded by first writing out the tag representing the variant and
then the contents.
However, there are some implementation details to be aware of:
* `isize`/`usize` are encoded as `i64`/`u64`, for portability.
* enums variants are encoded as a `u32` instead of a `uint`.
`u32` is enough for all practical uses.
* `str` is encoded as `(u64, &[u8])`, where the `u64` is the number of
bytes contained in the encoded string.

View File

@ -1,416 +0,0 @@
use std::io::Read;
use std::marker::PhantomData;
use byteorder::{ReadBytesExt, ByteOrder};
use serde_crate as serde;
use serde_crate::de::IntoDeserializer;
use serde_crate::de::Error as DeError;
use ::SizeLimit;
use super::{Result, Error, ErrorKind};
use self::read::BincodeRead;
pub mod read;
/// A Deserializer that reads bytes from a buffer.
///
/// This struct should rarely be used.
/// In most cases, prefer the `decode_from` function.
///
/// The ByteOrder that is chosen will impact the endianness that
/// is used to read integers out of the reader.
///
/// ```rust,ignore
/// let d = Deserializer::new(&mut some_reader, SizeLimit::new());
/// serde::Deserialize::deserialize(&mut deserializer);
/// let bytes_read = d.bytes_read();
/// ```
pub struct Deserializer<R, S: SizeLimit, E: ByteOrder> {
reader: R,
size_limit: S,
_phantom: PhantomData<E>,
}
impl<'de, R: BincodeRead<'de>, E: ByteOrder, S: SizeLimit> Deserializer<R, S, E> {
/// Creates a new Deserializer with a given `Read`er and a size_limit.
pub fn new(r: R, size_limit: S) -> Deserializer<R, S, E> {
Deserializer {
reader: r,
size_limit: size_limit,
_phantom: PhantomData
}
}
fn read_bytes(&mut self, count: u64) -> Result<()> {
self.size_limit.add(count)
}
fn read_type<T>(&mut self) -> Result<()> {
use std::mem::size_of;
self.read_bytes(size_of::<T>() as u64)
}
fn read_vec(&mut self) -> Result<Vec<u8>> {
let len: usize = try!(serde::Deserialize::deserialize(&mut *self));
self.read_bytes(len as u64)?;
self.reader.get_byte_buffer(len)
}
fn read_string(&mut self) -> Result<String> {
String::from_utf8(try!(self.read_vec())).map_err(|err|
ErrorKind::InvalidEncoding{
desc: "error while decoding utf8 string",
detail: Some(format!("Deserialize error: {}", err))
}.into())
}
}
macro_rules! impl_nums {
($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
#[inline]
fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
try!(self.read_type::<$ty>());
let value = try!(self.reader.$reader_method::<E>());
visitor.$visitor_method(value)
}
}
}
impl<'de, 'a, R, S, E> serde::Deserializer<'de> for &'a mut Deserializer<R, S, E>
where R: BincodeRead<'de>, S: SizeLimit, E: ByteOrder {
type Error = Error;
#[inline]
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let message = "bincode does not support Deserializer::deserialize";
Err(Error::custom(message))
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let value: u8 = try!(serde::Deserialize::deserialize(self));
match value {
1 => visitor.visit_bool(true),
0 => visitor.visit_bool(false),
value => {
Err(ErrorKind::InvalidEncoding{
desc: "invalid u8 when decoding bool",
detail: Some(format!("Expected 0 or 1, got {}", value))
}.into())
}
}
}
impl_nums!(u16, deserialize_u16, visit_u16, read_u16);
impl_nums!(u32, deserialize_u32, visit_u32, read_u32);
impl_nums!(u64, deserialize_u64, visit_u64, read_u64);
impl_nums!(i16, deserialize_i16, visit_i16, read_i16);
impl_nums!(i32, deserialize_i32, visit_i32, read_i32);
impl_nums!(i64, deserialize_i64, visit_i64, read_i64);
impl_nums!(f32, deserialize_f32, visit_f32, read_f32);
impl_nums!(f64, deserialize_f64, visit_f64, read_f64);
#[inline]
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
try!(self.read_type::<u8>());
visitor.visit_u8(try!(self.reader.read_u8()))
}
#[inline]
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
try!(self.read_type::<i8>());
visitor.visit_i8(try!(self.reader.read_i8()))
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
visitor.visit_unit()
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
use std::str;
let error = || {
ErrorKind::InvalidEncoding{
desc: "Invalid char encoding",
detail: None,
}.into()
};
let mut buf = [0u8; 4];
// Look at the first byte to see how many bytes must be read
let _ = try!(self.reader.read_exact(&mut buf[..1]));
let width = utf8_char_width(buf[0]);
if width == 1 { return visitor.visit_char(buf[0] as char) }
if width == 0 { return Err(error())}
if self.reader.read_exact(&mut buf[1..width]).is_err() {
return Err(error());
}
let res = try!(str::from_utf8(&buf[..width]).ok().and_then(|s| s.chars().next()).ok_or(error()));
visitor.visit_char(res)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let len: usize = try!(serde::Deserialize::deserialize(&mut *self));
try!(self.read_bytes(len as u64));
self.reader.forward_read_str(len, visitor)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
visitor.visit_string(try!(self.read_string()))
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let len: usize = try!(serde::Deserialize::deserialize(&mut *self));
try!(self.read_bytes(len as u64));
self.reader.forward_read_bytes(len, visitor)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
visitor.visit_byte_buf(try!(self.read_vec()))
}
fn deserialize_enum<V>(self,
_enum: &'static str,
_variants: &'static [&'static str],
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
impl<'de, 'a, R: 'a, S, E> serde::de::EnumAccess<'de> for &'a mut Deserializer<R, S, E>
where R: BincodeRead<'de>, S: SizeLimit, E: ByteOrder {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where V: serde::de::DeserializeSeed<'de>,
{
let idx: u32 = try!(serde::de::Deserialize::deserialize(&mut *self));
let val: Result<_> = seed.deserialize(idx.into_deserializer());
Ok((try!(val), self))
}
}
visitor.visit_enum(self)
}
fn deserialize_tuple<V>(self,
len: usize,
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
struct Access<'a, R: Read + 'a, S: SizeLimit + 'a, E: ByteOrder + 'a> {
deserializer: &'a mut Deserializer<R, S, E>,
len: usize,
}
impl<'de, 'a, 'b: 'a, R: BincodeRead<'de>+ 'b, S: SizeLimit, E: ByteOrder> serde::de::SeqAccess<'de> for Access<'a, R, S, E> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where T: serde::de::DeserializeSeed<'de>,
{
if self.len > 0 {
self.len -= 1;
let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer));
Ok(Some(value))
} else {
Ok(None)
}
}
fn size_hint(&self) -> Option<usize> {
Some(self.len)
}
}
visitor.visit_seq(Access { deserializer: self, len: len })
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let value: u8 = try!(serde::de::Deserialize::deserialize(&mut *self));
match value {
0 => visitor.visit_none(),
1 => visitor.visit_some(&mut *self),
_ => Err(ErrorKind::InvalidEncoding{
desc: "invalid tag when decoding Option",
detail: Some(format!("Expected 0 or 1, got {}", value))
}.into()),
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let len = try!(serde::Deserialize::deserialize(&mut *self));
self.deserialize_tuple(len, visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
struct Access<'a, R: Read + 'a, S: SizeLimit + 'a, E: ByteOrder + 'a> {
deserializer: &'a mut Deserializer<R, S, E>,
len: usize,
}
impl<'de, 'a, 'b: 'a, R: BincodeRead<'de> + 'b, S: SizeLimit, E: ByteOrder> serde::de::MapAccess<'de> for Access<'a, R, S, E> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where K: serde::de::DeserializeSeed<'de>,
{
if self.len > 0 {
self.len -= 1;
let key = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer));
Ok(Some(key))
} else {
Ok(None)
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where V: serde::de::DeserializeSeed<'de>,
{
let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer));
Ok(value)
}
fn size_hint(&self) -> Option<usize> {
Some(self.len)
}
}
let len = try!(serde::Deserialize::deserialize(&mut *self));
visitor.visit_map(Access { deserializer: self, len: len })
}
fn deserialize_struct<V>(self,
_name: &str,
fields: &'static [&'static str],
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
self.deserialize_tuple(fields.len(), visitor)
}
fn deserialize_identifier<V>(self,
_visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let message = "bincode does not support Deserializer::deserialize_identifier";
Err(Error::custom(message))
}
fn deserialize_newtype_struct<V>(self,
_name: &str,
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_unit_struct<V>(self,
_name: &'static str,
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
visitor.visit_unit()
}
fn deserialize_tuple_struct<V>(self,
_name: &'static str,
len: usize,
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
self.deserialize_tuple(len, visitor)
}
fn deserialize_ignored_any<V>(self,
_visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
let message = "bincode does not support Deserializer::deserialize_ignored_any";
Err(Error::custom(message))
}
}
impl<'de, 'a, R, S, E> serde::de::VariantAccess<'de> for &'a mut Deserializer<R, S, E>
where R: BincodeRead<'de>, S: SizeLimit, E: ByteOrder {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where T: serde::de::DeserializeSeed<'de>,
{
serde::de::DeserializeSeed::deserialize(seed, self)
}
fn tuple_variant<V>(self,
len: usize,
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
serde::de::Deserializer::deserialize_tuple(self, len, visitor)
}
fn struct_variant<V>(self,
fields: &'static [&'static str],
visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>,
{
serde::de::Deserializer::deserialize_tuple(self, fields.len(), visitor)
}
}
static UTF8_CHAR_WIDTH: [u8; 256] = [
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
];
fn utf8_char_width(b: u8) -> usize {
UTF8_CHAR_WIDTH[b as usize] as usize
}

View File

@ -1,151 +0,0 @@
use std::io::{Read as IoRead, Result as IoResult, Error as IoError, ErrorKind as IoErrorKind};
use ::Result;
use serde_crate as serde;
/// A byte-oriented reading trait that is specialized for
/// slices and generic readers.
pub trait BincodeRead<'storage>: IoRead {
#[doc(hidden)]
fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'storage>;
#[doc(hidden)]
fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>>;
#[doc(hidden)]
fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'storage>;
}
/// A BincodeRead implementation for byte slices
pub struct SliceReader<'storage> {
slice: &'storage [u8]
}
/// A BincodeRead implementation for io::Readers
pub struct IoReadReader<R> {
reader: R,
temp_buffer: Vec<u8>,
}
impl <'storage> SliceReader<'storage> {
/// Constructs a slice reader
pub fn new(bytes: &'storage [u8]) -> SliceReader<'storage> {
SliceReader {
slice: bytes,
}
}
}
impl <R> IoReadReader<R> {
/// Constructs an IoReadReader
pub fn new(r: R) -> IoReadReader<R> {
IoReadReader {
reader: r,
temp_buffer: vec![],
}
}
}
impl <'storage> IoRead for SliceReader<'storage> {
fn read(&mut self, out: & mut [u8]) -> IoResult<usize> {
(&mut self.slice).read(out)
}
}
impl <R: IoRead> IoRead for IoReadReader<R> {
fn read(&mut self, out: & mut [u8]) -> IoResult<usize> {
self.reader.read(out)
}
}
impl <'storage> SliceReader<'storage> {
fn unexpected_eof() -> Box<::ErrorKind> {
return Box::new(::ErrorKind::IoError(IoError::new(IoErrorKind::UnexpectedEof, "")));
}
}
impl <'storage> BincodeRead<'storage> for SliceReader<'storage> {
fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'storage> {
use ::ErrorKind;
if length > self.slice.len() {
return Err(SliceReader::unexpected_eof());
}
let string = match ::std::str::from_utf8(&self.slice[..length]) {
Ok(s) => s,
Err(_) => return Err(Box::new(ErrorKind::InvalidEncoding {
desc: "string was not valid utf8",
detail: None,
})),
};
let r = visitor.visit_borrowed_str(string);
self.slice = &self.slice[length..];
r
}
fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> {
if length > self.slice.len() {
return Err(SliceReader::unexpected_eof());
}
let r = &self.slice[..length];
self.slice = &self.slice[length..];
Ok(r.to_vec())
}
fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'storage> {
if length > self.slice.len() {
return Err(SliceReader::unexpected_eof());
}
let r = visitor.visit_borrowed_bytes(&self.slice[..length]);
self.slice = &self.slice[length..];
r
}
}
impl <R> IoReadReader<R> where R: IoRead {
fn fill_buffer(&mut self, length: usize) -> Result<()> {
let current_length = self.temp_buffer.len();
if length > current_length{
self.temp_buffer.reserve_exact(length - current_length);
unsafe { self.temp_buffer.set_len(length); }
}
self.reader.read_exact(&mut self.temp_buffer[..length])?;
Ok(())
}
}
impl <R> BincodeRead<'static> for IoReadReader<R> where R: IoRead {
fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'static> {
self.fill_buffer(length)?;
let string = match ::std::str::from_utf8(&self.temp_buffer[..length]) {
Ok(s) => s,
Err(_) => return Err(Box::new(::ErrorKind::InvalidEncoding {
desc: "string was not valid utf8",
detail: None,
})),
};
let r = visitor.visit_str(string);
r
}
fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> {
self.fill_buffer(length)?;
Ok(self.temp_buffer[..length].to_vec())
}
fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'static> {
self.fill_buffer(length)?;
let r = visitor.visit_bytes(&self.temp_buffer[..length]);
r
}
}

View File

@ -1,240 +0,0 @@
//! A collection of serialization and deserialization functions
//! that use the `serde` crate for the serializable and deserializable
//! implementation.
use std::io::{Write, Read};
use std::io::Error as IoError;
use std::{error, fmt, result};
use ::SizeLimit;
use byteorder::{ByteOrder};
pub use super::de::{
Deserializer,
};
pub use super::ser::{
Serializer,
};
use super::ser::SizeChecker;
use serde_crate as serde;
/// The result of a serialization or deserialization operation.
pub type Result<T> = result::Result<T, Error>;
/// An error that can be produced during (de)serializing.
///
/// If decoding from a Buffer, assume that the buffer has been left
/// in an invalid state.
pub type Error = Box<ErrorKind>;
/// The kind of error that can be produced during a serialization or deserialization.
#[derive(Debug)]
pub enum ErrorKind {
/// If the error stems from the reader/writer that is being used
/// during (de)serialization, that error will be stored and returned here.
IoError(IoError),
/// If the bytes in the reader are not decodable because of an invalid
/// encoding, this error will be returned. This error is only possible
/// if a stream is corrupted. A stream produced from `encode` or `encode_into`
/// should **never** produce an InvalidEncoding error.
InvalidEncoding {
#[allow(missing_docs)]
desc: &'static str,
#[allow(missing_docs)]
detail: Option<String>
},
/// If (de)serializing a message takes more than the provided size limit, this
/// error is returned.
SizeLimit,
/// Bincode can not encode sequences of unknown length (like iterators).
SequenceMustHaveLength,
/// A custom error message from Serde.
Custom(String)
}
impl error::Error for ErrorKind {
fn description(&self) -> &str {
match *self {
ErrorKind::IoError(ref err) => error::Error::description(err),
ErrorKind::InvalidEncoding{desc, ..} => desc,
ErrorKind::SequenceMustHaveLength => "bincode can't encode infinite sequences",
ErrorKind::SizeLimit => "the size limit for decoding has been reached",
ErrorKind::Custom(ref msg) => msg,
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
ErrorKind::IoError(ref err) => err.cause(),
ErrorKind::InvalidEncoding{..} => None,
ErrorKind::SequenceMustHaveLength => None,
ErrorKind::SizeLimit => None,
ErrorKind::Custom(_) => None,
}
}
}
impl From<IoError> for Error {
fn from(err: IoError) -> Error {
ErrorKind::IoError(err).into()
}
}
impl fmt::Display for ErrorKind {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
ErrorKind::IoError(ref ioerr) =>
write!(fmt, "IoError: {}", ioerr),
ErrorKind::InvalidEncoding{desc, detail: None}=>
write!(fmt, "InvalidEncoding: {}", desc),
ErrorKind::InvalidEncoding{desc, detail: Some(ref detail)}=>
write!(fmt, "InvalidEncoding: {} ({})", desc, detail),
ErrorKind::SequenceMustHaveLength =>
write!(fmt, "Bincode can only encode sequences and maps that have a knowable size ahead of time."),
ErrorKind::SizeLimit =>
write!(fmt, "SizeLimit"),
ErrorKind::Custom(ref s) =>
s.fmt(fmt),
}
}
}
impl serde::de::Error for Error {
fn custom<T: fmt::Display>(desc: T) -> Error {
ErrorKind::Custom(desc.to_string()).into()
}
}
impl serde::ser::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Self {
ErrorKind::Custom(msg.to_string()).into()
}
}
/// Serializes an object directly into a `Writer`.
///
/// If the serialization would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `Error` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// serializing.
pub fn serialize_into<W: ?Sized, T: ?Sized, S, E>(writer: &mut W, value: &T, size_limit: S) -> Result<()>
where W: Write, T: serde::Serialize, S: SizeLimit, E: ByteOrder
{
if let Some(limit) = size_limit.limit() {
try!(serialized_size_bounded(value, limit).ok_or(ErrorKind::SizeLimit));
}
let mut serializer = Serializer::<_, E>::new(writer);
serde::Serialize::serialize(value, &mut serializer)
}
/// Serializes a serializable object into a `Vec` of bytes.
///
/// If the serialization would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn serialize<T: ?Sized, S, E>(value: &T, size_limit: S) -> Result<Vec<u8>>
where T: serde::Serialize, S: SizeLimit, E: ByteOrder
{
let mut writer = match size_limit.limit() {
Some(size_limit) => {
let actual_size = try!(serialized_size_bounded(value, size_limit).ok_or(ErrorKind::SizeLimit));
Vec::with_capacity(actual_size as usize)
}
None => {
let size = serialized_size(value) as usize;
Vec::with_capacity(size)
}
};
try!(serialize_into::<_, _, _, E>(&mut writer, value, super::Infinite));
Ok(writer)
}
struct CountSize {
total: u64,
limit: Option<u64>,
}
impl SizeLimit for CountSize {
fn add(&mut self, c: u64) -> Result<()> {
self.total += c;
if let Some(limit) = self.limit {
if self.total > limit {
return Err(Box::new(ErrorKind::SizeLimit))
}
}
Ok(())
}
fn limit(&self) -> Option<u64> {
unreachable!();
}
}
/// Returns the size that an object would be if serialized using bincode.
///
/// This is used internally as part of the check for encode_into, but it can
/// be useful for preallocating buffers if thats your style.
pub fn serialized_size<T: ?Sized>(value: &T) -> u64
where T: serde::Serialize
{
let mut size_counter = SizeChecker {
size_limit: CountSize { total: 0, limit: None }
};
value.serialize(&mut size_counter).ok();
size_counter.size_limit.total
}
/// Given a maximum size limit, check how large an object would be if it
/// were to be serialized.
///
/// If it can be serialized in `max` or fewer bytes, that number will be returned
/// inside `Some`. If it goes over bounds, then None is returned.
pub fn serialized_size_bounded<T: ?Sized>(value: &T, max: u64) -> Option<u64>
where T: serde::Serialize
{
let mut size_counter = SizeChecker {
size_limit: CountSize { total: 0, limit: Some(max) }
};
match value.serialize(&mut size_counter) {
Ok(_) => Some(size_counter.size_limit.total),
Err(_) => None,
}
}
/// Deserializes an object directly from a `Buffer`ed Reader.
///
/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `Error`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn deserialize_from<R: ?Sized, T, S, E>(reader: &mut R, size_limit: S) -> Result<T>
where R: Read, T: serde::de::DeserializeOwned, S: SizeLimit, E: ByteOrder
{
let reader = ::de::read::IoReadReader::new(reader);
let mut deserializer = Deserializer::<_, S, E>::new(reader, size_limit);
serde::Deserialize::deserialize(&mut deserializer)
}
/// Deserializes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn deserialize<'a, T, E: ByteOrder>(bytes: &'a [u8]) -> Result<T>
where T: serde::de::Deserialize<'a>,
{
let reader = ::de::read::SliceReader::new(bytes);
let mut deserializer = Deserializer::<_, _, E>::new(reader, super::Infinite);
serde::Deserialize::deserialize(&mut deserializer)
}

View File

@ -1,167 +0,0 @@
#![deny(missing_docs)]
//! `bincode` is a crate for encoding and decoding using a tiny binary
//! serialization strategy.
//!
//! There are simple functions for encoding to `Vec<u8>` and decoding from
//! `&[u8]`, but the meat of the library is the `encode_into` and `decode_from`
//! functions which respectively allow encoding into a `std::io::Writer`
//! and decoding from a `std::io::Buffer`.
//!
//! ## Modules
//! Until "default type parameters" lands, we have an extra module called `endian_choice`
//! that duplicates all of the core bincode functionality but with the option to choose
//! which endianness the integers are encoded using.
//!
//! The default endianness is little.
//!
//! ### Using Basic Functions
//!
//! ```rust
//! extern crate bincode;
//! use bincode::{serialize, deserialize, Bounded};
//! fn main() {
//! // The object that we will serialize.
//! let target = Some("hello world".to_string());
//! // The maximum size of the encoded message.
//! let limit = Bounded(20);
//!
//! let encoded: Vec<u8> = serialize(&target, limit).unwrap();
//! let decoded: Option<String> = deserialize(&encoded[..]).unwrap();
//! assert_eq!(target, decoded);
//! }
//! ```
#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
extern crate byteorder;
extern crate num_traits;
extern crate serde as serde_crate;
mod ser;
mod de;
pub mod internal;
pub mod read_types {
//! The types that the deserializer uses for optimizations
pub use ::de::read::{SliceReader, BincodeRead, IoReadReader};
}
use std::io::{Read, Write};
pub use internal::{ErrorKind, Error, Result, serialized_size, serialized_size_bounded};
/// A Deserializer that uses LittleEndian byteorder
pub type Deserializer<W, S> = internal::Deserializer<W, S, byteorder::LittleEndian>;
/// A Serializer that uses LittleEndian byteorder
pub type Serializer<W> = internal::Serializer<W, byteorder::LittleEndian>;
/// Deserializes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn deserialize<'a, T>(bytes: &'a [u8]) -> internal::Result<T>
where T: serde_crate::de::Deserialize<'a>,
{
internal::deserialize::<_, byteorder::LittleEndian>(bytes)
}
/// Deserializes an object directly from a `Buffer`ed Reader.
///
/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `Error`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn deserialize_from<R: ?Sized, T, S>(reader: &mut R, size_limit: S) -> internal::Result<T>
where R: Read, T: serde_crate::de::DeserializeOwned, S: SizeLimit
{
internal::deserialize_from::<_, _, _, byteorder::LittleEndian>(reader, size_limit)
}
/// Serializes an object directly into a `Writer`.
///
/// If the serialization would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `Error` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// serializing.
pub fn serialize_into<W: ?Sized, T: ?Sized, S>(writer: &mut W, value: &T, size_limit: S) -> internal::Result<()>
where W: Write, T: serde_crate::Serialize, S: SizeLimit
{
internal::serialize_into::<_, _, _, byteorder::LittleEndian>(writer, value, size_limit)
}
/// Serializes a serializable object into a `Vec` of bytes.
///
/// If the serialization would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn serialize<T: ?Sized, S>(value: &T, size_limit: S) -> internal::Result<Vec<u8>>
where T: serde_crate::Serialize, S: SizeLimit
{
internal::serialize::<_, _, byteorder::LittleEndian>(value, size_limit)
}
/// A limit on the amount of bytes that can be read or written.
///
/// Size limits are an incredibly important part of both encoding and decoding.
///
/// In order to prevent DOS attacks on a decoder, it is important to limit the
/// amount of bytes that a single encoded message can be; otherwise, if you
/// are decoding bytes right off of a TCP stream for example, it would be
/// possible for an attacker to flood your server with a 3TB vec, causing the
/// decoder to run out of memory and crash your application!
/// Because of this, you can provide a maximum-number-of-bytes that can be read
/// during decoding, and the decoder will explicitly fail if it has to read
/// any more than that.
///
/// On the other side, you want to make sure that you aren't encoding a message
/// that is larger than your decoder expects. By supplying a size limit to an
/// encoding function, the encoder will verify that the structure can be encoded
/// within that limit. This verification occurs before any bytes are written to
/// the Writer, so recovering from an error is easy.
pub trait SizeLimit {
/// Tells the SizeLimit that a certain number of bytes has been
/// read or written. Returns Err if the limit has been exceeded.
fn add(&mut self, n: u64) -> Result<()>;
/// Returns the hard limit (if one exists)
fn limit(&self) -> Option<u64>;
}
/// A SizeLimit that restricts serialized or deserialized messages from
/// exceeding a certain byte length.
#[derive(Copy, Clone)]
pub struct Bounded(pub u64);
/// A SizeLimit without a limit!
/// Use this if you don't care about the size of encoded or decoded messages.
#[derive(Copy, Clone)]
pub struct Infinite;
impl SizeLimit for Bounded {
#[inline(always)]
fn add(&mut self, n: u64) -> Result<()> {
if self.0 >= n {
self.0 -= n;
Ok(())
} else {
Err(Box::new(ErrorKind::SizeLimit))
}
}
#[inline(always)]
fn limit(&self) -> Option<u64> { Some(self.0) }
}
impl SizeLimit for Infinite {
#[inline(always)]
fn add(&mut self, _: u64) -> Result<()> { Ok (()) }
#[inline(always)]
fn limit(&self) -> Option<u64> { None }
}

View File

@ -1,687 +0,0 @@
use std::io::Write;
use std::u32;
use std::marker::PhantomData;
use serde_crate as serde;
use byteorder::{WriteBytesExt, ByteOrder};
use super::{Result, Error, ErrorKind};
use super::SizeLimit;
/// An Serializer that encodes values directly into a Writer.
///
/// The specified byte-order will impact the endianness that is
/// used during the encoding.
///
/// This struct should not be used often.
/// For most cases, prefer the `encode_into` function.
pub struct Serializer<W, E: ByteOrder> {
writer: W,
_phantom: PhantomData<E>,
}
impl<W: Write, E: ByteOrder> Serializer<W, E> {
/// Creates a new Serializer with the given `Write`r.
pub fn new(w: W) -> Serializer<W, E> {
Serializer {
writer: w,
_phantom: PhantomData,
}
}
}
impl<'a, W: Write, E: ByteOrder> serde::Serializer for &'a mut Serializer<W, E> {
type Ok = ();
type Error = Error;
type SerializeSeq = Compound<'a, W, E>;
type SerializeTuple = Compound<'a, W, E>;
type SerializeTupleStruct = Compound<'a, W, E>;
type SerializeTupleVariant = Compound<'a, W, E>;
type SerializeMap = Compound<'a, W, E>;
type SerializeStruct = Compound<'a, W, E>;
type SerializeStructVariant = Compound<'a, W, E>;
fn serialize_unit(self) -> Result<()> { Ok(()) }
fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Ok(()) }
fn serialize_bool(self, v: bool) -> Result<()> {
self.writer.write_u8(if v {1} else {0}).map_err(Into::into)
}
fn serialize_u8(self, v: u8) -> Result<()> {
self.writer.write_u8(v).map_err(Into::into)
}
fn serialize_u16(self, v: u16) -> Result<()> {
self.writer.write_u16::<E>(v).map_err(Into::into)
}
fn serialize_u32(self, v: u32) -> Result<()> {
self.writer.write_u32::<E>(v).map_err(Into::into)
}
fn serialize_u64(self, v: u64) -> Result<()> {
self.writer.write_u64::<E>(v).map_err(Into::into)
}
fn serialize_i8(self, v: i8) -> Result<()> {
self.writer.write_i8(v).map_err(Into::into)
}
fn serialize_i16(self, v: i16) -> Result<()> {
self.writer.write_i16::<E>(v).map_err(Into::into)
}
fn serialize_i32(self, v: i32) -> Result<()> {
self.writer.write_i32::<E>(v).map_err(Into::into)
}
fn serialize_i64(self, v: i64) -> Result<()> {
self.writer.write_i64::<E>(v).map_err(Into::into)
}
fn serialize_f32(self, v: f32) -> Result<()> {
self.writer.write_f32::<E>(v).map_err(Into::into)
}
fn serialize_f64(self, v: f64) -> Result<()> {
self.writer.write_f64::<E>(v).map_err(Into::into)
}
fn serialize_str(self, v: &str) -> Result<()> {
try!(self.serialize_u64(v.len() as u64));
self.writer.write_all(v.as_bytes()).map_err(Into::into)
}
fn serialize_char(self, c: char) -> Result<()> {
self.writer.write_all(encode_utf8(c).as_slice()).map_err(Into::into)
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
try!(self.serialize_u64(v.len() as u64));
self.writer.write_all(v).map_err(Into::into)
}
fn serialize_none(self) -> Result<()> {
self.writer.write_u8(0).map_err(Into::into)
}
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<()>
where T: serde::Serialize,
{
try!(self.writer.write_u8(1));
v.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength));
try!(self.serialize_u64(len as u64));
Ok(Compound {ser: self})
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Ok(Compound {ser: self})
}
fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct> {
Ok(Compound {ser: self})
}
fn serialize_tuple_variant(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize) -> Result<Self::SerializeTupleVariant>
{
try!(self.serialize_u32(variant_index));
Ok(Compound {ser: self})
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength));
try!(self.serialize_u64(len as u64));
Ok(Compound {ser: self})
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
Ok(Compound {ser: self})
}
fn serialize_struct_variant(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize) -> Result<Self::SerializeStructVariant>
{
try!(self.serialize_u32(variant_index));
Ok(Compound {ser: self})
}
fn serialize_newtype_struct<T: ?Sized>(self,
_name: &'static str,
value: &T) -> Result<()>
where T: serde::ser::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized>(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
value: &T) -> Result<()>
where T: serde::ser::Serialize,
{
try!(self.serialize_u32(variant_index));
value.serialize(self)
}
fn serialize_unit_variant(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str) -> Result<()> {
self.serialize_u32(variant_index)
}
}
pub struct SizeChecker<S: SizeLimit> {
pub size_limit: S,
}
impl <S: SizeLimit> SizeChecker<S> {
pub fn new(size_limit: S) -> SizeChecker<S> {
SizeChecker {
size_limit: size_limit
}
}
fn add_raw(&mut self, size: u64) -> Result<()> {
self.size_limit.add(size)
}
fn add_value<T>(&mut self, t: T) -> Result<()> {
use std::mem::size_of_val;
self.add_raw(size_of_val(&t) as u64)
}
}
impl<'a, S: SizeLimit> serde::Serializer for &'a mut SizeChecker<S> {
type Ok = ();
type Error = Error;
type SerializeSeq = SizeCompound<'a, S>;
type SerializeTuple = SizeCompound<'a, S>;
type SerializeTupleStruct = SizeCompound<'a, S>;
type SerializeTupleVariant = SizeCompound<'a, S>;
type SerializeMap = SizeCompound<'a, S>;
type SerializeStruct = SizeCompound<'a, S>;
type SerializeStructVariant = SizeCompound<'a, S>;
fn serialize_unit(self) -> Result<()> { Ok(()) }
fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Ok(()) }
fn serialize_bool(self, _: bool) -> Result<()> {
self.add_value(0 as u8)
}
fn serialize_u8(self, v: u8) -> Result<()> {
self.add_value(v)
}
fn serialize_u16(self, v: u16) -> Result<()> {
self.add_value(v)
}
fn serialize_u32(self, v: u32) -> Result<()> {
self.add_value(v)
}
fn serialize_u64(self, v: u64) -> Result<()> {
self.add_value(v)
}
fn serialize_i8(self, v: i8) -> Result<()> {
self.add_value(v)
}
fn serialize_i16(self, v: i16) -> Result<()> {
self.add_value(v)
}
fn serialize_i32(self, v: i32) -> Result<()> {
self.add_value(v)
}
fn serialize_i64(self, v: i64) -> Result<()> {
self.add_value(v)
}
fn serialize_f32(self, v: f32) -> Result<()> {
self.add_value(v)
}
fn serialize_f64(self, v: f64) -> Result<()> {
self.add_value(v)
}
fn serialize_str(self, v: &str) -> Result<()> {
try!(self.add_value(0 as u64));
self.add_raw(v.len() as u64)
}
fn serialize_char(self, c: char) -> Result<()> {
self.add_raw(encode_utf8(c).as_slice().len() as u64)
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
try!(self.add_value(0 as u64));
self.add_raw(v.len() as u64)
}
fn serialize_none(self) -> Result<()> {
self.add_value(0 as u8)
}
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<()>
where T: serde::Serialize,
{
try!(self.add_value(1 as u8));
v.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength));
try!(self.serialize_u64(len as u64));
Ok(SizeCompound {ser: self})
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Ok(SizeCompound {ser: self})
}
fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct> {
Ok(SizeCompound {ser: self})
}
fn serialize_tuple_variant(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize) -> Result<Self::SerializeTupleVariant>
{
try!(self.add_value(variant_index));
Ok(SizeCompound {ser: self})
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap>
{
let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength));
try!(self.serialize_u64(len as u64));
Ok(SizeCompound {ser: self})
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
Ok(SizeCompound {ser: self})
}
fn serialize_struct_variant(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize) -> Result<Self::SerializeStructVariant>
{
try!(self.add_value(variant_index));
Ok(SizeCompound {ser: self})
}
fn serialize_newtype_struct<V: serde::Serialize + ?Sized>(self, _name: &'static str, v: &V) -> Result<()> {
v.serialize(self)
}
fn serialize_unit_variant(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str) -> Result<()> {
self.add_value(variant_index)
}
fn serialize_newtype_variant<V: serde::Serialize + ?Sized>(self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
value: &V) -> Result<()>
{
try!(self.add_value(variant_index));
value.serialize(self)
}
}
#[doc(hidden)]
pub struct Compound<'a, W: 'a, E: ByteOrder + 'a> {
ser: &'a mut Serializer<W, E>,
}
impl<'a, W, E> serde::ser::SerializeSeq for Compound<'a, W, E>
where W: Write, E: ByteOrder
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> serde::ser::SerializeTuple for Compound<'a, W, E>
where W: Write, E: ByteOrder
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> serde::ser::SerializeTupleStruct for Compound<'a, W, E>
where W: Write, E: ByteOrder
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> serde::ser::SerializeTupleVariant for Compound<'a, W, E>
where W: Write, E: ByteOrder
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> serde::ser::SerializeMap for Compound<'a, W, E>
where W: Write, E: ByteOrder
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_key<K: ?Sized>(&mut self, value: &K) -> Result<()>
where K: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn serialize_value<V: ?Sized>(&mut self, value: &V) -> Result<()>
where V: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> serde::ser::SerializeStruct for Compound<'a, W, E>
where W: Write, E: ByteOrder
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> serde::ser::SerializeStructVariant for Compound<'a, W, E>
where W: Write, E: ByteOrder
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
#[doc(hidden)]
pub struct SizeCompound<'a, S: SizeLimit + 'a> {
ser: &'a mut SizeChecker<S>,
}
impl<'a, S: SizeLimit> serde::ser::SerializeSeq for SizeCompound<'a, S>
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, S: SizeLimit> serde::ser::SerializeTuple for SizeCompound<'a, S>
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, S: SizeLimit> serde::ser::SerializeTupleStruct for SizeCompound<'a, S>
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, S: SizeLimit> serde::ser::SerializeTupleVariant for SizeCompound<'a, S>
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, S: SizeLimit + 'a> serde::ser::SerializeMap for SizeCompound<'a, S>
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_key<K: ?Sized>(&mut self, value: &K) -> Result<()>
where K: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn serialize_value<V: ?Sized>(&mut self, value: &V) -> Result<()>
where V: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, S: SizeLimit> serde::ser::SerializeStruct for SizeCompound<'a, S>
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, S: SizeLimit> serde::ser::SerializeStructVariant for SizeCompound<'a, S>
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
where T: serde::ser::Serialize
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
const TAG_CONT: u8 = 0b1000_0000;
const TAG_TWO_B: u8 = 0b1100_0000;
const TAG_THREE_B: u8 = 0b1110_0000;
const TAG_FOUR_B: u8 = 0b1111_0000;
const MAX_ONE_B: u32 = 0x80;
const MAX_TWO_B: u32 = 0x800;
const MAX_THREE_B: u32 = 0x10000;
fn encode_utf8(c: char) -> EncodeUtf8 {
let code = c as u32;
let mut buf = [0; 4];
let pos = if code < MAX_ONE_B {
buf[3] = code as u8;
3
} else if code < MAX_TWO_B {
buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
2
} else if code < MAX_THREE_B {
buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
1
} else {
buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
0
};
EncodeUtf8 { buf: buf, pos: pos }
}
struct EncodeUtf8 {
buf: [u8; 4],
pos: usize,
}
impl EncodeUtf8 {
fn as_slice(&self) -> &[u8] {
&self.buf[self.pos..]
}
}

View File

@ -1,419 +0,0 @@
#[macro_use]
extern crate serde_derive;
extern crate bincode;
extern crate serde;
extern crate serde_bytes;
extern crate byteorder;
use std::fmt::Debug;
use std::collections::HashMap;
use std::borrow::Cow;
use bincode::{Infinite, Bounded};
use bincode::{serialized_size, ErrorKind, Result};
use bincode::internal::{serialize, deserialize, deserialize_from};
use bincode::serialize as serialize_little;
use bincode::deserialize as deserialize_little;
use bincode::deserialize_from as deserialize_from_little;
fn the_same<V>(element: V)
where V: serde::Serialize+serde::de::DeserializeOwned+PartialEq+Debug+'static
{
let size = serialized_size(&element);
{
let encoded = serialize_little(&element, Infinite).unwrap();
let decoded = deserialize_little(&encoded[..]).unwrap();
assert_eq!(element, decoded);
assert_eq!(size, encoded.len() as u64);
}
{
let encoded = serialize::<_, _, byteorder::BigEndian>(&element, Infinite).unwrap();
let decoded = deserialize::<_, byteorder::BigEndian>(&encoded[..]).unwrap();
let decoded_reader = deserialize_from::<_, _, _, byteorder::BigEndian>(&mut &encoded[..], Infinite).unwrap();
assert_eq!(element, decoded);
assert_eq!(element, decoded_reader);
assert_eq!(size, encoded.len() as u64);
}
}
#[test]
fn test_numbers() {
// unsigned positive
the_same(5u8);
the_same(5u16);
the_same(5u32);
the_same(5u64);
the_same(5usize);
// signed positive
the_same(5i8);
the_same(5i16);
the_same(5i32);
the_same(5i64);
the_same(5isize);
// signed negative
the_same(-5i8);
the_same(-5i16);
the_same(-5i32);
the_same(-5i64);
the_same(-5isize);
// floating
the_same(-100f32);
the_same(0f32);
the_same(5f32);
the_same(-100f64);
the_same(5f64);
}
#[test]
fn test_string() {
the_same("".to_string());
the_same("a".to_string());
}
#[test]
fn test_tuple() {
the_same((1isize,));
the_same((1isize,2isize,3isize));
the_same((1isize,"foo".to_string(),()));
}
#[test]
fn test_basic_struct() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Easy {
x: isize,
s: String,
y: usize
}
the_same(Easy{x: -4, s: "foo".to_string(), y: 10});
}
#[test]
fn test_nested_struct() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Easy {
x: isize,
s: String,
y: usize
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Nest {
f: Easy,
b: usize,
s: Easy
}
the_same(Nest {
f: Easy {x: -1, s: "foo".to_string(), y: 20},
b: 100,
s: Easy {x: -100, s: "bar".to_string(), y: 20}
});
}
#[test]
fn test_struct_newtype() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct NewtypeStr(usize);
the_same(NewtypeStr(5));
}
#[test]
fn test_struct_tuple() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct TubStr(usize, String, f32);
the_same(TubStr(5, "hello".to_string(), 3.2));
}
#[test]
fn test_option() {
the_same(Some(5usize));
the_same(Some("foo bar".to_string()));
the_same(None::<usize>);
}
#[test]
fn test_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum TestEnum {
NoArg,
OneArg(usize),
Args(usize, usize),
AnotherNoArg,
StructLike{x: usize, y: f32}
}
the_same(TestEnum::NoArg);
the_same(TestEnum::OneArg(4));
//the_same(TestEnum::Args(4, 5));
the_same(TestEnum::AnotherNoArg);
the_same(TestEnum::StructLike{x: 4, y: 3.14159});
the_same(vec![TestEnum::NoArg, TestEnum::OneArg(5), TestEnum::AnotherNoArg,
TestEnum::StructLike{x: 4, y:1.4}]);
}
#[test]
fn test_vec() {
let v: Vec<u8> = vec![];
the_same(v);
the_same(vec![1u64]);
the_same(vec![1u64,2,3,4,5,6]);
}
#[test]
fn test_map() {
let mut m = HashMap::new();
m.insert(4u64, "foo".to_string());
m.insert(0u64, "bar".to_string());
the_same(m);
}
#[test]
fn test_bool() {
the_same(true);
the_same(false);
}
#[test]
fn test_unicode() {
the_same("å".to_string());
the_same("aåååååååa".to_string());
}
#[test]
fn test_fixed_size_array() {
the_same([24u32; 32]);
the_same([1u64, 2, 3, 4, 5, 6, 7, 8]);
the_same([0u8; 19]);
}
#[test]
fn deserializing_errors() {
fn isize_invalid_deserialize<T: Debug>(res: Result<T>) {
match res.map_err(|e| *e) {
Err(ErrorKind::InvalidEncoding{..}) => {},
Err(ErrorKind::Custom(ref s)) if s.contains("invalid encoding") => {},
Err(ErrorKind::Custom(ref s)) if s.contains("invalid value") => {},
other => panic!("Expecting InvalidEncoding, got {:?}", other),
}
}
isize_invalid_deserialize(deserialize_little::<bool>(&vec![0xA][..]));
isize_invalid_deserialize(deserialize_little::<String>(&vec![1, 0, 0, 0, 0, 0, 0, 0, 0xFF][..]));
// Out-of-bounds variant
#[derive(Serialize, Deserialize, Debug)]
enum Test {
One,
Two,
};
isize_invalid_deserialize(deserialize_little::<Test>(&vec![0, 0, 0, 5][..]));
isize_invalid_deserialize(deserialize_little::<Option<u8>>(&vec![5, 0][..]));
}
#[test]
fn too_big_deserialize() {
let serialized = vec![0,0,0,3];
let deserialized: Result<u32> = deserialize_from_little::<_, _, _>(&mut &serialized[..], Bounded(3));
assert!(deserialized.is_err());
let serialized = vec![0,0,0,3];
let deserialized: Result<u32> = deserialize_from_little::<_, _, _>(&mut &serialized[..], Bounded(4));
assert!(deserialized.is_ok());
}
#[test]
fn char_serialization() {
let chars = "Aa\0☺♪";
for c in chars.chars() {
let encoded = serialize_little(&c, Bounded(4)).expect("serializing char failed");
let decoded: char = deserialize_little(&encoded).expect("deserializing failed");
assert_eq!(decoded, c);
}
}
#[test]
fn too_big_char_deserialize() {
let serialized = vec![0x41];
let deserialized: Result<char> = deserialize_from_little::<_, _, _>(&mut &serialized[..], Bounded(1));
assert!(deserialized.is_ok());
assert_eq!(deserialized.unwrap(), 'A');
}
#[test]
fn too_big_serialize() {
assert!(serialize_little(&0u32, Bounded(3)).is_err());
assert!(serialize_little(&0u32, Bounded(4)).is_ok());
assert!(serialize_little(&"abcde", Bounded(8 + 4)).is_err());
assert!(serialize_little(&"abcde", Bounded(8 + 5)).is_ok());
}
#[test]
fn test_proxy_encoded_size() {
assert!(serialized_size(&0u8) == 1);
assert!(serialized_size(&0u16) == 2);
assert!(serialized_size(&0u32) == 4);
assert!(serialized_size(&0u64) == 8);
// length isize stored as u64
assert!(serialized_size(&"") == 8);
assert!(serialized_size(&"a") == 8 + 1);
assert!(serialized_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
}
#[test]
fn test_serialized_size() {
assert!(serialized_size(&0u8) == 1);
assert!(serialized_size(&0u16) == 2);
assert!(serialized_size(&0u32) == 4);
assert!(serialized_size(&0u64) == 8);
// length isize stored as u64
assert!(serialized_size(&"") == 8);
assert!(serialized_size(&"a") == 8 + 1);
assert!(serialized_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
}
#[test]
fn encode_box() {
the_same(Box::new(5));
}
#[test]
fn test_cow_serialize() {
let large_object = vec![1u32,2,3,4,5,6];
let mut large_map = HashMap::new();
large_map.insert(1, 2);
#[derive(Serialize, Deserialize, Debug)]
enum Message<'a> {
M1(Cow<'a, Vec<u32>>),
M2(Cow<'a, HashMap<u32, u32>>)
}
// Test 1
{
let serialized = serialize_little(&Message::M1(Cow::Borrowed(&large_object)), Infinite).unwrap();
let deserialized: Message<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
match deserialized {
Message::M1(b) => assert!(&b.into_owned() == &large_object),
_ => assert!(false)
}
}
// Test 2
{
let serialized = serialize_little(&Message::M2(Cow::Borrowed(&large_map)), Infinite).unwrap();
let deserialized: Message<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
match deserialized {
Message::M2(b) => assert!(&b.into_owned() == &large_map),
_ => assert!(false)
}
}
}
#[test]
fn test_strbox_serialize() {
let strx: &'static str = "hello world";
let serialized = serialize_little(&Cow::Borrowed(strx), Infinite).unwrap();
let deserialized: Cow<'static, String> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
let stringx: String = deserialized.into_owned();
assert!(strx == &stringx[..]);
}
#[test]
fn test_slicebox_serialize() {
let slice = [1u32, 2, 3 ,4, 5];
let serialized = serialize_little(&Cow::Borrowed(&slice[..]), Infinite).unwrap();
println!("{:?}", serialized);
let deserialized: Cow<'static, Vec<u32>> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
{
let sb: &[u32] = &deserialized;
assert!(slice == sb);
}
let vecx: Vec<u32> = deserialized.into_owned();
assert!(slice == &vecx[..]);
}
#[test]
fn test_multi_strings_serialize() {
assert!(serialize_little(&("foo", "bar", "baz"), Infinite).is_ok());
}
#[test]
fn test_oom_protection() {
use std::io::Cursor;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct FakeVec {
len: u64,
byte: u8
}
let x = serialize_little(&FakeVec { len: 0xffffffffffffffffu64, byte: 1 }, Bounded(10)).unwrap();
let y: Result<Vec<u8>> = deserialize_from_little(&mut Cursor::new(&x[..]), Bounded(10));
assert!(y.is_err());
}
#[test]
fn path_buf() {
use std::path::{Path, PathBuf};
let path = Path::new("foo").to_path_buf();
let serde_encoded = serialize_little(&path, Infinite).unwrap();
let decoded: PathBuf = deserialize_little(&serde_encoded).unwrap();
assert!(path.to_str() == decoded.to_str());
}
#[test]
fn bytes() {
use serde_bytes::Bytes;
let data = b"abc\0123";
let s = serialize_little(&data[..], Infinite).unwrap();
let s2 = serialize_little(&Bytes::new(data), Infinite).unwrap();
assert_eq!(s[..], s2[..]);
}
#[test]
fn serde_bytes() {
use serde_bytes::ByteBuf;
the_same(ByteBuf::from(vec![1,2,3,4,5]));
}
#[test]
fn endian_difference() {
let x = 10u64;
let little = serialize_little(&x, Infinite).unwrap();
let big = serialize::<_, _, byteorder::BigEndian>(&x, Infinite).unwrap();
assert_ne!(little, big);
}
#[test]
fn test_zero_copy_parse() {
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct Foo<'a> {
borrowed_str: &'a str,
borrowed_bytes: &'a [u8],
}
let f = Foo {
borrowed_str: "hi",
borrowed_bytes: &[0, 1, 2, 3],
};
{
let encoded = serialize_little(&f, Infinite).unwrap();
let out: Foo = deserialize_little(&encoded[..]).unwrap();
assert_eq!(out, f);
}
}

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"2fc45d9fc64c5d59fb35be6a68cc26c56843ffa8da258a8a6616d6b9962caa53","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","src/builders.rs":"f4f4764697c65c08bfbf156005c5f40a43bb8b9ae72a4986dc8b5252537de7ec","src/channel.rs":"bc1e970d9a32ffa9f51f285bce511c20f33c4dd56add27d0bb27273e6483aa90","src/context.rs":"c1ab7873702a7b5634a3e83ab4cec9d5db14965fcd17e28d824a739318c0d424","src/device.rs":"490d2e94ecae1e149476c2e8d9aa03c4163987c3efccc962b2d3123e4c09dedf","src/device_collection.rs":"5c492120c0c2ee460d0042320f6ce38711ff38443687bc77b5b9f13369755d68","src/error.rs":"855ff3d3597753f832ecea00e403c71129afd80db3d39456cf3e23cb9aeb91e7","src/ffi_types.rs":"d815d7a80895b5e86907e708dc0219fca4ac4668cde114afee434e7d702a145d","src/format.rs":"5513c537a72af1c222ee7c30b26d4de9d368a69772688b95d88b1a99f6892d5c","src/lib.rs":"6010a5e20b836b8e5c9fba382fde819e6f3c18c0ec2016e6e7e118eabedbcd51","src/log.rs":"c46bae3472043fd076df3229c3421d948a87fae8495c1524b41ab2d8608f612a","src/stream.rs":"8f28a8a7b1ef2567f6764a36ebe2ecfde5f01dcd65befc7599684d82f4a390d6","src/try_call.rs":"020a4c9a795d5c6998a089b45ae0b8132e0421f2a229fe2014afad55c7086d32","src/util.rs":"308cfbaacd615ff600e74415c52daeef007fff34a4a0648a73c0042f6067f84f"},"package":"1ac5bb9e9d8747ae2c0884c970852c158315d809e33ce7c6a7b42b80b6a376aa"}
{"files":{"Cargo.toml":"2c1583ea21c913bbd37de181da827b82075300f40e355dcb24455ee5cb3df6d6","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","src/builders.rs":"f4f4764697c65c08bfbf156005c5f40a43bb8b9ae72a4986dc8b5252537de7ec","src/channel.rs":"bc1e970d9a32ffa9f51f285bce511c20f33c4dd56add27d0bb27273e6483aa90","src/context.rs":"c1ab7873702a7b5634a3e83ab4cec9d5db14965fcd17e28d824a739318c0d424","src/device.rs":"490d2e94ecae1e149476c2e8d9aa03c4163987c3efccc962b2d3123e4c09dedf","src/device_collection.rs":"f6d0c1628cc34b524f86b84a1e1c79971c3f64ebc4ac64eeb10a1330bbe8c238","src/error.rs":"855ff3d3597753f832ecea00e403c71129afd80db3d39456cf3e23cb9aeb91e7","src/ffi_types.rs":"d815d7a80895b5e86907e708dc0219fca4ac4668cde114afee434e7d702a145d","src/format.rs":"5513c537a72af1c222ee7c30b26d4de9d368a69772688b95d88b1a99f6892d5c","src/lib.rs":"6010a5e20b836b8e5c9fba382fde819e6f3c18c0ec2016e6e7e118eabedbcd51","src/log.rs":"c46bae3472043fd076df3229c3421d948a87fae8495c1524b41ab2d8608f612a","src/stream.rs":"28fce5a49384437f5106b0575aebfb09d7b1875e4adb53d57102d79666bbab43","src/try_call.rs":"231bfa3f3448f7531427bb228beb2bcd4fd711f0b13d2d8f412af013470f40c7","src/util.rs":"308cfbaacd615ff600e74415c52daeef007fff34a4a0648a73c0042f6067f84f"},"package":"a6558e6b99511df1b4e7ce219b26527b0cb0f6f56df2fd5877aa9473b7c7eafb"}

View File

@ -12,7 +12,7 @@
[package]
name = "cubeb-core"
version = "0.4.2"
version = "0.4.3"
authors = ["Dan Glastonbury <dglastonbury@mozilla.com>"]
description = "Common types and definitions for cubeb rust and C bindings. Not intended for direct use.\n"
homepage = "https://github.com/djg/cubeb-rs"

View File

@ -27,7 +27,7 @@ impl<'ctx> DeviceCollection<'ctx> {
impl<'ctx> Drop for DeviceCollection<'ctx> {
fn drop(&mut self) {
unsafe {
let _ = try_call!(ffi::cubeb_device_collection_destroy(
let _ = call!(ffi::cubeb_device_collection_destroy(
self.1.as_ptr(),
&mut self.0
));

View File

@ -131,17 +131,17 @@ ffi_type_heap! {
impl StreamRef {
/// Start playback.
pub fn start(&self) -> Result<()> {
unsafe { try_call!(ffi::cubeb_stream_start(self.as_ptr())) }
unsafe { call!(ffi::cubeb_stream_start(self.as_ptr())) }
}
/// Stop playback.
pub fn stop(&self) -> Result<()> {
unsafe { try_call!(ffi::cubeb_stream_stop(self.as_ptr())) }
unsafe { call!(ffi::cubeb_stream_stop(self.as_ptr())) }
}
/// Reset stream to the default device.
pub fn reset_default_device(&self) -> Result<()> {
unsafe { try_call!(ffi::cubeb_stream_reset_default_device(self.as_ptr())) }
unsafe { call!(ffi::cubeb_stream_reset_default_device(self.as_ptr())) }
}
/// Get the current stream playback position.
@ -166,7 +166,7 @@ impl StreamRef {
/// Set the volume for a stream.
pub fn set_volume(&self, volume: f32) -> Result<()> {
unsafe { try_call!(ffi::cubeb_stream_set_volume(self.as_ptr(), volume)) }
unsafe { call!(ffi::cubeb_stream_set_volume(self.as_ptr(), volume)) }
}
/// If the stream is stereo, set the left/right panning. If the stream is mono,
@ -177,7 +177,7 @@ impl StreamRef {
/// mixed in the right channel. 0.0 is equal power in the right
/// and left channel (default).
pub fn set_panning(&self, panning: f32) -> Result<()> {
unsafe { try_call!(ffi::cubeb_stream_set_panning(self.as_ptr(), panning)) }
unsafe { call!(ffi::cubeb_stream_set_panning(self.as_ptr(), panning)) }
}
/// Get the current output device for this stream.
@ -195,7 +195,7 @@ impl StreamRef {
/// Destroy a cubeb_device structure.
pub fn device_destroy(&self, device: DeviceRef) -> Result<()> {
unsafe {
try_call!(ffi::cubeb_stream_device_destroy(
call!(ffi::cubeb_stream_device_destroy(
self.as_ptr(),
device.as_ptr()
))
@ -208,7 +208,7 @@ impl StreamRef {
callback: ffi::cubeb_device_changed_callback,
) -> Result<()> {
unsafe {
try_call!(ffi::cubeb_stream_register_device_changed_callback(
call!(ffi::cubeb_stream_register_device_changed_callback(
self.as_ptr(),
callback
))

View File

@ -14,8 +14,14 @@ pub fn cvt_r(ret: c_int) -> Result<(), Error> {
}
}
macro_rules! try_call {
macro_rules! call {
(ffi::$p:ident ($($e:expr),*)) => ({
::try_call::cvt_r(ffi::$p($($e),*))
})
}
macro_rules! try_call {
(ffi::$p:ident ($($e:expr),*)) => ({
try!(::try_call::cvt_r(ffi::$p($($e),*)))
})
}