Bug 1335525 - Add webrender dependencies to third_party/rust. r=gfx

MozReview-Commit-ID: L77ffKqR5QU
This commit is contained in:
Kartikaya Gupta 2017-02-06 11:42:53 -05:00
parent 3b39cf43fc
commit 10d3b0ebbe
1096 changed files with 277079 additions and 14 deletions

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"12cc0f91b51fedf41ae1670d1624ee1d78a284bdb101645b60a06a12de16c069",".travis.yml":"6b96b2c6bfd7e1acef4b825a2813fc4277859eb9400a16800db8835c25e4087d","Cargo.toml":"789b93a48ce76901375209d5462408469c31809e09a98e71370c57187a4b0923","README.md":"9f048d969f9f8333cdcdb892744cd0816e4f2922c8817fa5e9e07f9472fe1050","src/app_unit.rs":"71b0ac2fa378427883649def1a03008ac9d4eb45addd084b7d9885867049551e","src/lib.rs":"2df7d863c47d8b22f9af66caeafa87e6a206ee713a8aeaa55c5a80a42a92513b"},"package":"636ee56f12e31dbc11dc0a1ac6004f08b04e6e6595963716fc8130e90d4e04cf"}

0
third_party/rust/app_units/.cargo-ok vendored Normal file
View File

2
third_party/rust/app_units/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target/
Cargo.lock

View File

@ -0,0 +1,8 @@
language: rust
notifications:
webhooks: http://build.servo.org:54856/travis
rust:
- stable
- beta
- nightly

18
third_party/rust/app_units/Cargo.toml vendored Normal file
View File

@ -0,0 +1,18 @@
[package]
name = "app_units"
version = "0.3.0"
authors = ["The Servo Project Developers"]
description = "Servo app units type (Au)"
documentation = "http://doc.servo.org/app_units/"
repository = "https://github.com/servo/app_units"
license = "MPL-2.0"
[features]
default = []
plugins = []
[dependencies]
heapsize = "0.3"
num-traits = "0.1.32"
rustc-serialize = "0.3"
serde = "0.8"

3
third_party/rust/app_units/README.md vendored Normal file
View File

@ -0,0 +1,3 @@
# app-units
[Documentation](http://doc.servo.org/app_units/index.html)

View File

@ -0,0 +1,315 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use heapsize::HeapSizeOf;
use num_traits::Zero;
use rustc_serialize::{Encodable, Encoder};
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use std::default::Default;
use std::fmt;
use std::i32;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
/// The number of app units in a pixel.
pub const AU_PER_PX: i32 = 60;
#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)]
pub struct Au(pub i32);
impl HeapSizeOf for Au {
fn heap_size_of_children(&self) -> usize { 0 }
}
impl Deserialize for Au {
fn deserialize<D: Deserializer>(deserializer: &mut D) -> Result<Au, D::Error> {
Ok(Au(try!(i32::deserialize(deserializer))))
}
}
impl Serialize for Au {
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
self.0.serialize(serializer)
}
}
impl Default for Au {
#[inline]
fn default() -> Au {
Au(0)
}
}
impl Zero for Au {
#[inline]
fn zero() -> Au {
Au(0)
}
#[inline]
fn is_zero(&self) -> bool {
self.0 == 0
}
}
pub const MIN_AU: Au = Au(i32::MIN);
pub const MAX_AU: Au = Au(i32::MAX);
impl Encodable for Au {
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
e.emit_f64(self.to_f64_px())
}
}
impl fmt::Debug for Au {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}px", self.to_f64_px())
}
}
impl Add for Au {
type Output = Au;
#[inline]
fn add(self, other: Au) -> Au {
Au(self.0.wrapping_add(other.0))
}
}
impl Sub for Au {
type Output = Au;
#[inline]
fn sub(self, other: Au) -> Au {
Au(self.0.wrapping_sub(other.0))
}
}
impl Mul<i32> for Au {
type Output = Au;
#[inline]
fn mul(self, other: i32) -> Au {
Au(self.0.wrapping_mul(other))
}
}
impl Div<i32> for Au {
type Output = Au;
#[inline]
fn div(self, other: i32) -> Au {
Au(self.0 / other)
}
}
impl Rem<i32> for Au {
type Output = Au;
#[inline]
fn rem(self, other: i32) -> Au {
Au(self.0 % other)
}
}
impl Neg for Au {
type Output = Au;
#[inline]
fn neg(self) -> Au {
Au(-self.0)
}
}
impl AddAssign for Au {
#[inline]
fn add_assign(&mut self, other: Au) {
*self = *self + other;
}
}
impl SubAssign for Au {
#[inline]
fn sub_assign(&mut self, other: Au) {
*self = *self - other;
}
}
impl MulAssign<i32> for Au {
#[inline]
fn mul_assign(&mut self, other: i32) {
*self = *self * other;
}
}
impl DivAssign<i32> for Au {
#[inline]
fn div_assign(&mut self, other: i32) {
*self = *self / other;
}
}
impl Au {
/// FIXME(pcwalton): Workaround for lack of cross crate inlining of newtype structs!
#[inline]
pub fn new(value: i32) -> Au {
Au(value)
}
#[inline]
pub fn scale_by(self, factor: f32) -> Au {
Au(((self.0 as f32) * factor) as i32)
}
#[inline]
pub fn from_px(px: i32) -> Au {
Au((px * AU_PER_PX) as i32)
}
/// Rounds this app unit down to the pixel towards zero and returns it.
#[inline]
pub fn to_px(self) -> i32 {
self.0 / AU_PER_PX
}
/// Ceil this app unit to the appropriate pixel boundary and return it.
#[inline]
pub fn ceil_to_px(self) -> i32 {
((self.0 as f64) / (AU_PER_PX as f64)).ceil() as i32
}
#[inline]
pub fn to_nearest_px(self) -> i32 {
((self.0 as f64) / (AU_PER_PX as f64)).round() as i32
}
#[inline]
pub fn to_nearest_pixel(self, pixels_per_px: f32) -> f32 {
((self.0 as f32) / (AU_PER_PX as f32) * pixels_per_px).round() / pixels_per_px
}
#[inline]
pub fn to_f32_px(self) -> f32 {
(self.0 as f32) / (AU_PER_PX as f32)
}
#[inline]
pub fn to_f64_px(self) -> f64 {
(self.0 as f64) / (AU_PER_PX as f64)
}
#[inline]
pub fn from_f32_px(px: f32) -> Au {
Au((px * (AU_PER_PX as f32)) as i32)
}
#[inline]
pub fn from_f64_px(px: f64) -> Au {
Au((px * (AU_PER_PX as f64)) as i32)
}
}
#[test]
fn create() {
assert_eq!(Au::zero(), Au(0));
assert_eq!(Au::default(), Au(0));
assert_eq!(Au::new(7), Au(7));
}
#[test]
fn operations() {
assert_eq!(Au(7) + Au(5), Au(12));
assert_eq!(MAX_AU + Au(1), MIN_AU);
assert_eq!(Au(7) - Au(5), Au(2));
assert_eq!(MIN_AU - Au(1), MAX_AU);
assert_eq!(Au(7) * 5, Au(35));
assert_eq!(MAX_AU * -1, MIN_AU + Au(1));
assert_eq!(MIN_AU * -1, MIN_AU);
assert_eq!(Au(35) / 5, Au(7));
assert_eq!(Au(35) % 6, Au(5));
assert_eq!(-Au(7), Au(-7));
}
#[test]
#[should_panic]
fn overflowing_div() {
MIN_AU / -1;
}
#[test]
#[should_panic]
fn overflowing_rem() {
MIN_AU % -1;
}
#[test]
fn scale() {
assert_eq!(Au(12).scale_by(1.5), Au(18));
}
#[test]
fn convert() {
assert_eq!(Au::from_px(5), Au(300));
assert_eq!(Au(300).to_px(), 5);
assert_eq!(Au(330).to_px(), 5);
assert_eq!(Au(350).to_px(), 5);
assert_eq!(Au(360).to_px(), 6);
assert_eq!(Au(300).ceil_to_px(), 5);
assert_eq!(Au(310).ceil_to_px(), 6);
assert_eq!(Au(330).ceil_to_px(), 6);
assert_eq!(Au(350).ceil_to_px(), 6);
assert_eq!(Au(360).ceil_to_px(), 6);
assert_eq!(Au(300).to_nearest_px(), 5);
assert_eq!(Au(310).to_nearest_px(), 5);
assert_eq!(Au(330).to_nearest_px(), 6);
assert_eq!(Au(350).to_nearest_px(), 6);
assert_eq!(Au(360).to_nearest_px(), 6);
assert_eq!(Au(60).to_nearest_pixel(2.), 1.);
assert_eq!(Au(70).to_nearest_pixel(2.), 1.);
assert_eq!(Au(80).to_nearest_pixel(2.), 1.5);
assert_eq!(Au(90).to_nearest_pixel(2.), 1.5);
assert_eq!(Au(100).to_nearest_pixel(2.), 1.5);
assert_eq!(Au(110).to_nearest_pixel(2.), 2.);
assert_eq!(Au(120).to_nearest_pixel(2.), 2.);
assert_eq!(Au(300).to_f32_px(), 5.);
assert_eq!(Au(312).to_f32_px(), 5.2);
assert_eq!(Au(330).to_f32_px(), 5.5);
assert_eq!(Au(348).to_f32_px(), 5.8);
assert_eq!(Au(360).to_f32_px(), 6.);
assert_eq!(Au(300).to_f64_px(), 5.);
assert_eq!(Au(312).to_f64_px(), 5.2);
assert_eq!(Au(330).to_f64_px(), 5.5);
assert_eq!(Au(348).to_f64_px(), 5.8);
assert_eq!(Au(360).to_f64_px(), 6.);
assert_eq!(Au::from_f32_px(5.), Au(300));
assert_eq!(Au::from_f32_px(5.2), Au(312));
assert_eq!(Au::from_f32_px(5.5), Au(330));
assert_eq!(Au::from_f32_px(5.8), Au(348));
assert_eq!(Au::from_f32_px(6.), Au(360));
assert_eq!(Au::from_f64_px(5.), Au(300));
assert_eq!(Au::from_f64_px(5.2), Au(312));
assert_eq!(Au::from_f64_px(5.5), Au(330));
assert_eq!(Au::from_f64_px(5.8), Au(348));
assert_eq!(Au::from_f64_px(6.), Au(360));
}
#[test]
fn heapsize() {
use heapsize::HeapSizeOf;
fn f<T: HeapSizeOf>(_: T) {}
f(Au::new(0));
}

16
third_party/rust/app_units/src/lib.rs vendored Normal file
View File

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! An Au is an "App Unit" and represents 1/60th of a CSS pixel. It was
//! originally proposed in 2002 as a standard unit of measure in Gecko.
//! See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info.
extern crate heapsize;
extern crate num_traits;
extern crate rustc_serialize;
extern crate serde;
mod app_unit;
pub use app_unit::{Au, MIN_AU, MAX_AU, AU_PER_PX};

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"e084df3ce631ce22082bd63f9e421e7f4d7a2408d6520de532f6a649e4d320dd",".travis.yml":"cb3f687453522852cb74371892a77d5e6eb61d771b8ef27f6cc6628e556de3d6","Cargo.toml":"d631ecb2eef5a18307a68e795080ed073851c9bea0800405cad98642ed3cc053","LICENSE.md":"90d7e062634054e6866d3c81e6a2b3058a840e6af733e98e80bdfe1a7dec6912","examples/basic.rs":"cdf97f2c4facbc202bf9e1496030d09bef3b7cd5538407325a38f0fe2e49415e","logo.png":"ebc5305aae938c1f834cf35302faa8be0f1b7b8c3c3beef5cf6b2f68b9628c35","readme.dev.md":"43bad3bcc13a5c057344d3ba7f64bd2b313f8c133d6afa068108df73e8e8facd","readme.md":"1fe1bda36327400cfedfcf103d58091c8465067b62706b0a368d287ca0312cd9","src/lib.rs":"1a85a12afad0b6150b8dbede093d19f4a32a3cd6976ee018a625fbc05051bf80","src/refbox.rs":"f0470baabbf0f9852df939c2535865793dc31c9d9d35eecf9c237a9df431a9fc","src/rustc_serialize/mod.rs":"188f5ff7fc9c5e0ac1404b919ceafac5ce4385950d22ae470ddc1775d2a0643b","src/rustc_serialize/reader.rs":"7983c37556fdef552bfeba386d557863fb5113c8fada55d4cf6a605f13214253","src/rustc_serialize/writer.rs":"684844799673fce3c54f1aca42430b6730da13473d732ee2954ebc56994ebd95","src/serde/mod.rs":"7818bbe5c320af2a15762c421d5471865a7364e1c9754c57960402fdcf09c595","src/serde/reader.rs":"1f88a55923dfc3ad82ec32571c9c7ca42818d996897966dea08a595f804d117f","src/serde/writer.rs":"d987134b3a00eb17a25e601757ad20607dd1de8989452266e9e4e7955fcd87f1","tests/test.rs":"b72a5902be11c3210dd56814276ff036155eba10d5f0aa566c86e7a1ce463adf"},"package":"55eb0b7fd108527b0c77860f75eca70214e11a8b4c6ef05148c54c05a25d48ad"}

0
third_party/rust/bincode/.cargo-ok vendored Normal file
View File

5
third_party/rust/bincode/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/target
/Cargo.lock
*.swp
*.swo
.cargo

29
third_party/rust/bincode/.travis.yml vendored Normal file
View File

@ -0,0 +1,29 @@
lang: c
after_success: |
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
cargo doc &&
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
sudo pip install ghp-import &&
ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
env:
matrix:
- CHANNEL='stable'
- CHANNEL='beta'
- CHANNEL='nightly'
global:
- secure: SZSxNqg9wiGx8EnJhifJ2kb/aCRcLim9TzTQyfurPqd8qVGkDOeVjTtbs+VTxLVXYtMJAz+YYnrQDwsu8kc/uYpQajU+gRMqNGEP5gNj3Ha5iNGDasAS6piIHQSMROayZ+D9g22nlGnjk8t9eZtLHC/Z8IWMCnjcIHvqMFY6cgI=
install:
- curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh > ./rustup.sh
- chmod +x ./rustup.sh
- ./rustup.sh --yes
script:
- multirust default $CHANNEL
- cargo build
- cargo build --no-default-features --features "rustc-serialize"
- cargo build --no-default-features --features "serde"
- if [ $CHANNEL = 'nightly' ] ; then cargo test ; fi

29
third_party/rust/bincode/Cargo.toml vendored Normal file
View File

@ -0,0 +1,29 @@
[package]
name = "bincode"
version = "0.6.1"
authors = ["Ty Overby <ty@pre-alpha.com>", "Francesco Mazzoli <f@mazzo.li>"]
repository = "https://github.com/TyOverby/bincode"
documentation = "http://tyoverby.github.io/bincode/bincode/"
keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
license = "MIT"
description = "A binary serialization / deserialization strategy and implementation with serde and rustc-serialize backends."
[dependencies]
byteorder = "1.0.0"
num-traits = "0.1.32"
[dependencies.rustc-serialize]
version = "0.3.*"
optional = true
[dependencies.serde]
version = "0.8.*"
optional = true
[dev-dependencies]
serde_derive = "0.8.*"
[features]
default = ["rustc-serialize", "serde"]

21
third_party/rust/bincode/LICENSE.md vendored Normal file
View File

@ -0,0 +1,21 @@
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

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

BIN
third_party/rust/bincode/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

39
third_party/rust/bincode/readme.dev.md vendored Normal file
View File

@ -0,0 +1,39 @@
# 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.

72
third_party/rust/bincode/readme.md vendored Normal file
View File

@ -0,0 +1,72 @@
# 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 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 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/)
## Example
```rust
extern crate bincode;
extern crate rustc_serialize;
use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Entity {
x: f32,
y: f32,
}
#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct World {
entities: Vec<Entity>
}
fn main() {
let world = World {
entities: vec![Entity {x: 0.0, y: 4.0}, Entity {x: 10.0, y: 20.5}]
};
let encoded: Vec<u8> = encode(&world, SizeLimit::Infinite).unwrap();
// 8 bytes for the length of the vector, 4 bytes per float.
assert_eq!(encoded.len(), 8 + 4 * 4);
let decoded: World = decode(&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.

79
third_party/rust/bincode/src/lib.rs vendored Normal file
View File

@ -0,0 +1,79 @@
//! `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
//! There are two ways to encode and decode structs using `bincode`, either using `rustc_serialize`
//! or the `serde` crate. `rustc_serialize` and `serde` are crates and and also the names of their
//! corresponding modules inside of `bincode`. Both modules have exactly equivalant functions, and
//! and the only difference is whether or not the library user wants to use `rustc_serialize` or
//! `serde`.
//!
//! ### Using Basic Functions
//!
//! ```rust
//! #![allow(unstable)]
//! extern crate bincode;
//! use bincode::rustc_serialize::{encode, decode};
//! fn main() {
//! // The object that we will serialize.
//! let target = Some("hello world".to_string());
//! // The maximum size of the encoded message.
//! let limit = bincode::SizeLimit::Bounded(20);
//!
//! let encoded: Vec<u8> = encode(&target, limit).unwrap();
//! let decoded: Option<String> = decode(&encoded[..]).unwrap();
//! assert_eq!(target, decoded);
//! }
//! ```
#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "./icon.png")]
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize as rustc_serialize_crate;
extern crate byteorder;
extern crate num_traits;
#[cfg(feature = "serde")]
extern crate serde as serde_crate;
pub use refbox::{RefBox, StrBox, SliceBox};
mod refbox;
#[cfg(feature = "rustc-serialize")]
pub mod rustc_serialize;
#[cfg(feature = "serde")]
pub mod serde;
/// 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.
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum SizeLimit {
Infinite,
Bounded(u64)
}

434
third_party/rust/bincode/src/refbox.rs vendored Normal file
View File

@ -0,0 +1,434 @@
use std::boxed::Box;
use std::ops::Deref;
#[cfg(feature = "rustc-serialize")]
use rustc_serialize_crate::{Encodable, Encoder, Decodable, Decoder};
#[cfg(feature = "serde")]
use serde_crate as serde;
/// A struct for encoding nested reference types.
///
/// Encoding large objects by reference is really handy. For example,
/// `encode(&large_hashmap, ...)` encodes the large structure without having to
/// own the hashmap. However, it is impossible to serialize a reference if that
/// reference is inside of a struct.
///
/// ```ignore rust
/// // Not possible, rustc can not decode the reference.
/// #[derive(RustcEncoding, RustcDecoding)]
/// struct Message<'a> {
/// big_map: &'a HashMap<u32, u32>,
/// message_type: String,
/// }
/// ```
///
/// This is because on the decoding side, you can't create the Message struct
/// because it needs to have a reference to a HashMap, which is impossible because
/// during deserialization, all members need to be owned by the deserialized
/// object.
///
/// This is where RefBox comes in. During serialization, it serializs a reference,
/// but during deserialization, it puts that sub-object into a box!
///
/// ```ignore rust
/// // This works!
/// #[derive(RustcEncoding, RustcDecoding)]
/// struct Message<'a> {
/// big_map: RefBox<'a, HashMap<u32, u32>>,
/// message_type: String
/// }
/// ```
///
/// Now we can write
///
/// ```ignore rust
/// let my_map = HashMap::new();
/// let my_msg = Message {
/// big_map: RefBox::new(&my_map),
/// message_type: "foo".to_string()
/// };
///
/// let encoded = encode(&my_msg, ...).unwrap();
/// let decoded: Message<'static> = decode(&encoded[]).unwrap();
/// ```
///
/// Notice that we managed to encode and decode a struct with a nested reference
/// and that the decoded message has the lifetime `'static` which shows us
/// that the message owns everything inside it completely.
///
/// Please don't stick RefBox inside deep data structures. It is much better
/// suited in the outermost layer of whatever it is that you are encoding.
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
pub struct RefBox<'a, T: 'a> {
inner: RefBoxInner<'a, T, Box<T>>
}
/// Like a RefBox, but encoding from a `str` and decoedes to a `String`.
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
pub struct StrBox<'a> {
inner: RefBoxInner<'a, str, String>
}
/// Like a RefBox, but encodes from a `[T]` and encodes to a `Vec<T>`.
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
pub struct SliceBox<'a, T: 'a> {
inner: RefBoxInner<'a, [T], Vec<T>>
}
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
enum RefBoxInner<'a, A: 'a + ?Sized, B> {
Ref(&'a A),
Box(B)
}
impl<'a, T> Clone for RefBoxInner<'a, T, Box<T>> where T: Clone {
fn clone(&self) -> RefBoxInner<'a, T, Box<T>> {
match *self {
RefBoxInner::Ref(reff) => RefBoxInner::Box(Box::new(reff.clone())),
RefBoxInner::Box(ref boxed) => RefBoxInner::Box(boxed.clone())
}
}
}
impl<'a> Clone for RefBoxInner<'a, str, String> {
fn clone(&self) -> RefBoxInner<'a, str, String> {
match *self {
RefBoxInner::Ref(reff) => RefBoxInner::Box(String::from(reff)),
RefBoxInner::Box(ref boxed) => RefBoxInner::Box(boxed.clone())
}
}
}
impl<'a, T> Clone for RefBoxInner<'a, [T], Vec<T>> where T: Clone {
fn clone(&self) -> RefBoxInner<'a, [T], Vec<T>> {
match *self {
RefBoxInner::Ref(reff) => RefBoxInner::Box(Vec::from(reff)),
RefBoxInner::Box(ref boxed) => RefBoxInner::Box(boxed.clone())
}
}
}
impl <'a, T> RefBox<'a, T> {
/// Creates a new RefBox that looks at a borrowed value.
pub fn new(v: &'a T) -> RefBox<'a, T> {
RefBox {
inner: RefBoxInner::Ref(v)
}
}
}
impl <T> RefBox<'static, T> {
/// Takes the value out of this refbox.
///
/// Fails if this refbox was not created out of a deserialization.
///
/// Unless you are doing some really weird things with static references,
/// this function will never fail.
pub fn take(self) -> Box<T> {
match self.inner {
RefBoxInner::Box(b) => b,
_ => unreachable!()
}
}
/// Tries to take the value out of this refbox.
pub fn try_take(self) -> Result<Box<T>, RefBox<'static, T>> {
match self.inner {
RefBoxInner::Box(b) => Ok(b),
o => Err(RefBox{ inner: o})
}
}
}
#[cfg(feature = "rustc-serialize")]
impl <'a, T: Encodable> Encodable for RefBox<'a, T> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
self.inner.encode(s)
}
}
#[cfg(feature = "rustc-serialize")]
impl <T: Decodable> Decodable for RefBox<'static, T> {
fn decode<D: Decoder>(d: &mut D) -> Result<RefBox<'static, T>, D::Error> {
let inner = try!(Decodable::decode(d));
Ok(RefBox{inner: inner})
}
}
#[cfg(feature = "serde")]
impl<'a, T> serde::Serialize for RefBox<'a, T>
where T: serde::Serialize,
{
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer
{
serde::Serialize::serialize(&self.inner, serializer)
}
}
#[cfg(feature = "serde")]
impl<'a, T: serde::Deserialize> serde::Deserialize for RefBox<'a, T> {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: serde::Deserializer
{
let inner = try!(serde::Deserialize::deserialize(deserializer));
Ok(RefBox{ inner: inner })
}
}
impl<'a> StrBox<'a> {
/// Creates a new StrBox that looks at a borrowed value.
pub fn new(s: &'a str) -> StrBox<'a> {
StrBox {
inner: RefBoxInner::Ref(s)
}
}
/// Extract a String from a StrBox.
pub fn into_string(self) -> String {
match self.inner {
RefBoxInner::Ref(s) => String::from(s),
RefBoxInner::Box(s) => s
}
}
/// Convert to an Owned `SliceBox`.
pub fn to_owned(self) -> StrBox<'static> {
match self.inner {
RefBoxInner::Ref(s) => StrBox::boxed(String::from(s)),
RefBoxInner::Box(s) => StrBox::boxed(s)
}
}
}
impl<'a> AsRef<str> for StrBox<'a> {
fn as_ref(&self) -> &str {
match self.inner {
RefBoxInner::Ref(ref s) => s,
RefBoxInner::Box(ref s) => s
}
}
}
impl StrBox<'static> {
/// Creates a new StrBox made from an allocated String.
pub fn boxed(s: String) -> StrBox<'static> {
StrBox { inner: RefBoxInner::Box(s) }
}
/// Takes the value out of this refbox.
///
/// Fails if this refbox was not created out of a deserialization.
///
/// Unless you are doing some really weird things with static references,
/// this function will never fail.
pub fn take(self) -> String {
match self.inner {
RefBoxInner::Box(b) => b,
RefBoxInner::Ref(b) => String::from(b)
}
}
/// Tries to take the value out of this refbox.
pub fn try_take(self) -> Result<String, StrBox<'static>> {
match self.inner {
RefBoxInner::Box(b) => Ok(b),
o => Err(StrBox{ inner: o})
}
}
}
#[cfg(feature = "rustc-serialize")]
impl <'a> Encodable for StrBox<'a> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
self.inner.encode(s)
}
}
#[cfg(feature = "rustc-serialize")]
impl Decodable for StrBox<'static> {
fn decode<D: Decoder>(d: &mut D) -> Result<StrBox<'static>, D::Error> {
let inner: RefBoxInner<'static, str, String> = try!(Decodable::decode(d));
Ok(StrBox{inner: inner})
}
}
#[cfg(feature = "serde")]
impl<'a> serde::Serialize for StrBox<'a> {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer
{
serde::Serialize::serialize(&self.inner, serializer)
}
}
#[cfg(feature = "serde")]
impl serde::Deserialize for StrBox<'static> {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: serde::Deserializer
{
let inner = try!(serde::Deserialize::deserialize(deserializer));
Ok(StrBox{ inner: inner })
}
}
//
// SliceBox
//
impl <'a, T> SliceBox<'a, T> {
/// Creates a new RefBox that looks at a borrowed value.
pub fn new(v: &'a [T]) -> SliceBox<'a, T> {
SliceBox {
inner: RefBoxInner::Ref(v)
}
}
/// Extract a `Vec<T>` from a `SliceBox`.
pub fn into_vec(self) -> Vec<T> where T: Clone {
match self.inner {
RefBoxInner::Ref(s) => s.to_vec(),
RefBoxInner::Box(s) => s
}
}
/// Convert to an Owned `SliceBox`.
pub fn to_owned(self) -> SliceBox<'static, T> where T: Clone {
match self.inner {
RefBoxInner::Ref(s) => SliceBox::boxed(s.to_vec()),
RefBoxInner::Box(s) => SliceBox::boxed(s)
}
}
}
impl <T> SliceBox<'static, T> {
/// Creates a new SliceBox made from an allocated `Vec<T>`.
pub fn boxed(s: Vec<T>) -> SliceBox<'static, T> {
SliceBox { inner: RefBoxInner::Box(s) }
}
/// Takes the value out of this refbox.
///
/// Fails if this refbox was not created out of a deserialization.
///
/// Unless you are doing some really weird things with static references,
/// this function will never fail.
pub fn take(self) -> Vec<T> {
match self.inner {
RefBoxInner::Box(b) => b,
_ => unreachable!()
}
}
/// Tries to take the value out of this refbox.
pub fn try_take(self) -> Result<Vec<T>, SliceBox<'static, T>> {
match self.inner {
RefBoxInner::Box(b) => Ok(b),
o => Err(SliceBox{ inner: o})
}
}
}
#[cfg(feature = "rustc-serialize")]
impl <'a, T: Encodable> Encodable for SliceBox<'a, T> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
self.inner.encode(s)
}
}
#[cfg(feature = "rustc-serialize")]
impl <T: Decodable> Decodable for SliceBox<'static, T> {
fn decode<D: Decoder>(d: &mut D) -> Result<SliceBox<'static, T>, D::Error> {
let inner: RefBoxInner<'static, [T], Vec<T>> = try!(Decodable::decode(d));
Ok(SliceBox{inner: inner})
}
}
#[cfg(feature = "serde")]
impl<'a, T> serde::Serialize for SliceBox<'a, T>
where T: serde::Serialize,
{
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer
{
serde::Serialize::serialize(&self.inner, serializer)
}
}
#[cfg(feature = "serde")]
impl<'a, T: serde::Deserialize> serde::Deserialize for SliceBox<'a, T> {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: serde::Deserializer
{
let inner = try!(serde::Deserialize::deserialize(deserializer));
Ok(SliceBox{ inner: inner })
}
}
#[cfg(feature = "rustc-serialize")]
impl <'a, A: Encodable + ?Sized, B: Encodable> Encodable for RefBoxInner<'a, A, B> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
match self {
&RefBoxInner::Ref(ref r) => r.encode(s),
&RefBoxInner::Box(ref b) => b.encode(s)
}
}
}
#[cfg(feature = "serde")]
impl<'a, A: ?Sized, B> serde::Serialize for RefBoxInner<'a, A, B>
where A: serde::Serialize,
B: serde::Serialize,
{
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer
{
match self {
&RefBoxInner::Ref(ref r) => serde::Serialize::serialize(r, serializer),
&RefBoxInner::Box(ref b) => serde::Serialize::serialize(b, serializer),
}
}
}
#[cfg(feature = "rustc-serialize")]
impl <A: ?Sized, B: Decodable> Decodable for RefBoxInner<'static, A, B> {
fn decode<D: Decoder>(d: &mut D) -> Result<RefBoxInner<'static, A, B>, D::Error> {
let decoded = try!(Decodable::decode(d));
Ok(RefBoxInner::Box(decoded))
}
}
#[cfg(feature = "serde")]
impl<'a, A: ?Sized, B> serde::Deserialize for RefBoxInner<'a, A, B>
where B: serde::Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: serde::Deserializer
{
let deserialized = try!(serde::Deserialize::deserialize(deserializer));
Ok(RefBoxInner::Box(deserialized))
}
}
impl <'a, T> Deref for RefBox<'a, T> {
type Target = T;
fn deref(&self) -> &T {
match &self.inner {
&RefBoxInner::Ref(ref t) => t,
&RefBoxInner::Box(ref b) => b.deref()
}
}
}
impl <'a, T> Deref for SliceBox<'a, T> {
type Target = [T];
fn deref(&self) -> &[T] {
match &self.inner {
&RefBoxInner::Ref(ref t) => t,
&RefBoxInner::Box(ref b) => b.deref()
}
}
}

View File

@ -0,0 +1,102 @@
//! A collection of serialization and deserialization functions
//! that use the `rustc_serialize` crate for the encodable and decodable
//! implementation.
use rustc_serialize_crate::{Encodable, Decodable};
use std::io::{Write, Read};
use ::SizeLimit;
pub use self::writer::{SizeChecker, EncoderWriter, EncodingResult, EncodingError};
pub use self::reader::{DecoderReader, DecodingResult, DecodingError, InvalidEncoding};
mod reader;
mod writer;
/// Encodes an encodable object into a `Vec` of bytes.
///
/// If the encoding would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn encode<T: Encodable>(t: &T, size_limit: SizeLimit) -> EncodingResult<Vec<u8>> {
// Since we are putting values directly into a vector, we can do size
// computation out here and pre-allocate a buffer of *exactly*
// the right size.
let mut w = if let SizeLimit::Bounded(l) = size_limit {
let actual_size = encoded_size_bounded(t, l);
let actual_size = try!(actual_size.ok_or(EncodingError::SizeLimit));
Vec::with_capacity(actual_size as usize)
} else {
vec![]
};
match encode_into(t, &mut w, SizeLimit::Infinite) {
Ok(()) => Ok(w),
Err(e) => Err(e)
}
}
/// Decodes 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 decode<T: Decodable>(b: &[u8]) -> DecodingResult<T> {
let mut b = b;
decode_from(&mut b, SizeLimit::Infinite)
}
/// Encodes an object directly into a `Writer`.
///
/// If the encoding 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 `EncodingError` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// encoding.
pub fn encode_into<T: Encodable, W: Write>(t: &T,
w: &mut W,
size_limit: SizeLimit)
-> EncodingResult<()> {
try!(match size_limit {
SizeLimit::Infinite => Ok(()),
SizeLimit::Bounded(x) => {
let mut size_checker = SizeChecker::new(x);
t.encode(&mut size_checker)
}
});
t.encode(&mut writer::EncoderWriter::new(w))
}
/// Decoes an object directly from a `Buffer`ed Reader.
///
/// If the provided `SizeLimit` is reached, the decode 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 `DecodingError`, 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 decode_from<R: Read, T: Decodable>(r: &mut R, size_limit: SizeLimit) -> DecodingResult<T> {
Decodable::decode(&mut reader::DecoderReader::new(r, size_limit))
}
/// Returns the size that an object would be if encoded 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 encoded_size<T: Encodable>(t: &T) -> u64 {
use std::u64::MAX;
let mut size_checker = SizeChecker::new(MAX);
t.encode(&mut size_checker).ok();
size_checker.written
}
/// Given a maximum size limit, check how large an object would be if it
/// were to be encoded.
///
/// If it can be encoded in `max` or fewer bytes, that number will be returned
/// inside `Some`. If it goes over bounds, then None is returned.
pub fn encoded_size_bounded<T: Encodable>(t: &T, max: u64) -> Option<u64> {
let mut size_checker = SizeChecker::new(max);
t.encode(&mut size_checker).ok().map(|_| size_checker.written)
}

View File

@ -0,0 +1,392 @@
use std::io::Read;
use std::io::Error as IoError;
use std::error::Error;
use std::fmt;
use std::convert::From;
use rustc_serialize_crate::Decoder;
use byteorder::{BigEndian, ReadBytesExt};
use ::SizeLimit;
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct InvalidEncoding {
pub desc: &'static str,
pub detail: Option<String>,
}
impl fmt::Display for InvalidEncoding {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
InvalidEncoding { detail: None, desc } =>
write!(fmt, "{}", desc),
InvalidEncoding { detail: Some(ref detail), desc } =>
write!(fmt, "{} ({})", desc, detail)
}
}
}
/// An error that can be produced during decoding.
///
/// If decoding from a Buffer, assume that the buffer has been left
/// in an invalid state.
#[derive(Debug)]
pub enum DecodingError {
/// If the error stems from the reader that is being used
/// during decoding, 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(InvalidEncoding),
/// If decoding a message takes more than the provided size limit, this
/// error is returned.
SizeLimit
}
impl fmt::Display for DecodingError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
DecodingError::IoError(ref ioerr) =>
write!(fmt, "IoError: {}", ioerr),
DecodingError::InvalidEncoding(ref ib) =>
write!(fmt, "InvalidEncoding: {}", ib),
DecodingError::SizeLimit =>
write!(fmt, "SizeLimit")
}
}
}
pub type DecodingResult<T> = Result<T, DecodingError>;
fn wrap_io(err: IoError) -> DecodingError {
DecodingError::IoError(err)
}
impl Error for DecodingError {
fn description(&self) -> &str {
match *self {
DecodingError::IoError(ref err) => Error::description(err),
DecodingError::InvalidEncoding(ref ib) => ib.desc,
DecodingError::SizeLimit => "the size limit for decoding has been reached"
}
}
fn cause(&self) -> Option<&Error> {
match *self {
DecodingError::IoError(ref err) => err.cause(),
DecodingError::InvalidEncoding(_) => None,
DecodingError::SizeLimit => None
}
}
}
impl From<IoError> for DecodingError {
fn from(err: IoError) -> DecodingError {
DecodingError::IoError(err)
}
}
/// A Decoder that reads bytes from a buffer.
///
/// This struct should rarely be used.
/// In most cases, prefer the `decode_from` function.
///
/// ```rust,ignore
/// let dr = bincode::rustc_serialize::DecoderReader::new(&mut some_reader, SizeLimit::Infinite);
/// let result: T = Decodable::decode(&mut dr);
/// let bytes_read = dr.bytes_read();
/// ```
pub struct DecoderReader<'a, R: 'a> {
reader: &'a mut R,
size_limit: SizeLimit,
read: u64
}
impl<'a, R: Read> DecoderReader<'a, R> {
pub fn new(r: &'a mut R, size_limit: SizeLimit) -> DecoderReader<'a, R> {
DecoderReader {
reader: r,
size_limit: size_limit,
read: 0
}
}
/// Returns the number of bytes read from the contained Reader.
pub fn bytes_read(&self) -> u64 {
self.read
}
}
impl <'a, A> DecoderReader<'a, A> {
fn read_bytes(&mut self, count: u64) -> Result<(), DecodingError> {
self.read = match self.read.checked_add(count) {
Some(read) => read,
None => return Err(DecodingError::SizeLimit),
};
match self.size_limit {
SizeLimit::Infinite => Ok(()),
SizeLimit::Bounded(x) if self.read <= x => Ok(()),
SizeLimit::Bounded(_) => Err(DecodingError::SizeLimit)
}
}
fn read_type<T>(&mut self) -> Result<(), DecodingError> {
use std::mem::size_of;
self.read_bytes(size_of::<T>() as u64)
}
}
impl<'a, R: Read> Decoder for DecoderReader<'a, R> {
type Error = DecodingError;
fn read_nil(&mut self) -> DecodingResult<()> {
Ok(())
}
fn read_usize(&mut self) -> DecodingResult<usize> {
Ok(try!(self.read_u64().map(|x| x as usize)))
}
fn read_u64(&mut self) -> DecodingResult<u64> {
try!(self.read_type::<u64>());
self.reader.read_u64::<BigEndian>().map_err(wrap_io)
}
fn read_u32(&mut self) -> DecodingResult<u32> {
try!(self.read_type::<u32>());
self.reader.read_u32::<BigEndian>().map_err(wrap_io)
}
fn read_u16(&mut self) -> DecodingResult<u16> {
try!(self.read_type::<u16>());
self.reader.read_u16::<BigEndian>().map_err(wrap_io)
}
fn read_u8(&mut self) -> DecodingResult<u8> {
try!(self.read_type::<u8>());
self.reader.read_u8().map_err(wrap_io)
}
fn read_isize(&mut self) -> DecodingResult<isize> {
self.read_i64().map(|x| x as isize)
}
fn read_i64(&mut self) -> DecodingResult<i64> {
try!(self.read_type::<i64>());
self.reader.read_i64::<BigEndian>().map_err(wrap_io)
}
fn read_i32(&mut self) -> DecodingResult<i32> {
try!(self.read_type::<i32>());
self.reader.read_i32::<BigEndian>().map_err(wrap_io)
}
fn read_i16(&mut self) -> DecodingResult<i16> {
try!(self.read_type::<i16>());
self.reader.read_i16::<BigEndian>().map_err(wrap_io)
}
fn read_i8(&mut self) -> DecodingResult<i8> {
try!(self.read_type::<i8>());
self.reader.read_i8().map_err(wrap_io)
}
fn read_bool(&mut self) -> DecodingResult<bool> {
let x = try!(self.read_i8());
match x {
1 => Ok(true),
0 => Ok(false),
_ => Err(DecodingError::InvalidEncoding(InvalidEncoding{
desc: "invalid u8 when decoding bool",
detail: Some(format!("Expected 0 or 1, got {}", x))
})),
}
}
fn read_f64(&mut self) -> DecodingResult<f64> {
try!(self.read_type::<f64>());
self.reader.read_f64::<BigEndian>().map_err(wrap_io)
}
fn read_f32(&mut self) -> DecodingResult<f32> {
try!(self.read_type::<f32>());
self.reader.read_f32::<BigEndian>().map_err(wrap_io)
}
fn read_char(&mut self) -> DecodingResult<char> {
use std::str;
let error = DecodingError::InvalidEncoding(InvalidEncoding {
desc: "Invalid char encoding",
detail: None
});
let mut buf = [0];
let _ = try!(self.reader.read(&mut buf[..]));
let first_byte = buf[0];
let width = utf8_char_width(first_byte);
if width == 1 { return Ok(first_byte as char) }
if width == 0 { return Err(error)}
let mut buf = [first_byte, 0, 0, 0];
{
let mut start = 1;
while start < width {
match try!(self.reader.read(&mut buf[start .. width])) {
n if n == width - start => break,
n if n < width - start => { start += n; }
_ => return Err(error)
}
}
}
let res = try!(match str::from_utf8(&buf[..width]).ok() {
Some(s) => Ok(s.chars().next().unwrap()),
None => Err(error)
});
try!(self.read_bytes(res.len_utf8() as u64));
Ok(res)
}
fn read_str(&mut self) -> DecodingResult<String> {
let len = try!(self.read_usize());
try!(self.read_bytes(len as u64));
let mut buff = Vec::new();
try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buff));
match String::from_utf8(buff) {
Ok(s) => Ok(s),
Err(err) => Err(DecodingError::InvalidEncoding(InvalidEncoding {
desc: "error while decoding utf8 string",
detail: Some(format!("Decoding error: {}", err))
})),
}
}
fn read_enum<T, F>(&mut self, _: &str, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> DecodingResult<T>
where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult<T>
{
let id = try!(self.read_u32());
let id = id as usize;
if id >= names.len() {
Err(DecodingError::InvalidEncoding(InvalidEncoding {
desc: "out of bounds tag when reading enum variant",
detail: Some(format!("Expected tag < {}, got {}", names.len(), id))
}))
} else {
f(self, id)
}
}
fn read_enum_variant_arg<T, F>(&mut self, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodingResult<T>
where F: FnMut(&mut DecoderReader<'a, R>, usize) -> DecodingResult<T>
{
self.read_enum_variant(names, f)
}
fn read_enum_struct_variant_field<T, F>(&mut self,
_: &str,
f_idx: usize,
f: F)
-> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
self.read_enum_variant_arg(f_idx, f)
}
fn read_struct<T, F>(&mut self, _: &str, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_struct_field<T, F>(&mut self, _: &str, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_tuple<T, F>(&mut self, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_tuple_arg<T, F>(&mut self, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_tuple_struct<T, F>(&mut self, _: &str, len: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
self.read_tuple(len, f)
}
fn read_tuple_struct_arg<T, F>(&mut self, a_idx: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
self.read_tuple_arg(a_idx, f)
}
fn read_option<T, F>(&mut self, mut f: F) -> DecodingResult<T>
where F: FnMut(&mut DecoderReader<'a, R>, bool) -> DecodingResult<T>
{
let x = try!(self.read_u8());
match x {
1 => f(self, true),
0 => f(self, false),
_ => Err(DecodingError::InvalidEncoding(InvalidEncoding {
desc: "invalid tag when decoding Option",
detail: Some(format!("Expected 0 or 1, got {}", x))
})),
}
}
fn read_seq<T, F>(&mut self, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult<T>
{
let len = try!(self.read_usize());
f(self, len)
}
fn read_seq_elt<T, F>(&mut self, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_map<T, F>(&mut self, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>, usize) -> DecodingResult<T>
{
let len = try!(self.read_usize());
f(self, len)
}
fn read_map_elt_key<T, F>(&mut self, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn read_map_elt_val<T, F>(&mut self, _: usize, f: F) -> DecodingResult<T>
where F: FnOnce(&mut DecoderReader<'a, R>) -> DecodingResult<T>
{
f(self)
}
fn error(&mut self, err: &str) -> DecodingError {
DecodingError::InvalidEncoding(InvalidEncoding {
desc: "user-induced error",
detail: Some(err.to_string()),
})
}
}
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

@ -0,0 +1,422 @@
use std::io::Write;
use std::io::Error as IoError;
use std::error::Error;
use std::fmt;
use rustc_serialize_crate::Encoder;
use byteorder::{BigEndian, WriteBytesExt};
pub type EncodingResult<T> = Result<T, EncodingError>;
/// An error that can be produced during encoding.
#[derive(Debug)]
pub enum EncodingError {
/// An error originating from the underlying `Writer`.
IoError(IoError),
/// An object could not be encoded with the given size limit.
///
/// This error is returned before any bytes are written to the
/// output `Writer`.
SizeLimit,
}
/// An Encoder that encodes values directly into a Writer.
///
/// This struct should not be used often.
/// For most cases, prefer the `encode_into` function.
pub struct EncoderWriter<'a, W: 'a> {
writer: &'a mut W,
}
pub struct SizeChecker {
pub size_limit: u64,
pub written: u64
}
fn wrap_io(err: IoError) -> EncodingError {
EncodingError::IoError(err)
}
impl fmt::Display for EncodingError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
EncodingError::IoError(ref err) => write!(f, "IoError: {}", err),
EncodingError::SizeLimit => write!(f, "SizeLimit")
}
}
}
impl Error for EncodingError {
fn description(&self) -> &str {
match *self {
EncodingError::IoError(ref err) => Error::description(err),
EncodingError::SizeLimit => "the size limit for decoding has been reached"
}
}
fn cause(&self) -> Option<&Error> {
match *self {
EncodingError::IoError(ref err) => err.cause(),
EncodingError::SizeLimit => None
}
}
}
impl <'a, W: Write> EncoderWriter<'a, W> {
pub fn new(w: &'a mut W) -> EncoderWriter<'a, W> {
EncoderWriter {
writer: w,
}
}
}
impl SizeChecker {
pub fn new(limit: u64) -> SizeChecker {
SizeChecker {
size_limit: limit,
written: 0
}
}
fn add_raw(&mut self, size: usize) -> EncodingResult<()> {
self.written += size as u64;
if self.written <= self.size_limit {
Ok(())
} else {
Err(EncodingError::SizeLimit)
}
}
fn add_value<T>(&mut self, t: T) -> EncodingResult<()> {
use std::mem::size_of_val;
self.add_raw(size_of_val(&t))
}
}
impl<'a, W: Write> Encoder for EncoderWriter<'a, W> {
type Error = EncodingError;
fn emit_nil(&mut self) -> EncodingResult<()> {
Ok(())
}
fn emit_usize(&mut self, v: usize) -> EncodingResult<()> {
self.emit_u64(v as u64)
}
fn emit_u64(&mut self, v: u64) -> EncodingResult<()> {
self.writer.write_u64::<BigEndian>(v).map_err(wrap_io)
}
fn emit_u32(&mut self, v: u32) -> EncodingResult<()> {
self.writer.write_u32::<BigEndian>(v).map_err(wrap_io)
}
fn emit_u16(&mut self, v: u16) -> EncodingResult<()> {
self.writer.write_u16::<BigEndian>(v).map_err(wrap_io)
}
fn emit_u8(&mut self, v: u8) -> EncodingResult<()> {
self.writer.write_u8(v).map_err(wrap_io)
}
fn emit_isize(&mut self, v: isize) -> EncodingResult<()> {
self.emit_i64(v as i64)
}
fn emit_i64(&mut self, v: i64) -> EncodingResult<()> {
self.writer.write_i64::<BigEndian>(v).map_err(wrap_io)
}
fn emit_i32(&mut self, v: i32) -> EncodingResult<()> {
self.writer.write_i32::<BigEndian>(v).map_err(wrap_io)
}
fn emit_i16(&mut self, v: i16) -> EncodingResult<()> {
self.writer.write_i16::<BigEndian>(v).map_err(wrap_io)
}
fn emit_i8(&mut self, v: i8) -> EncodingResult<()> {
self.writer.write_i8(v).map_err(wrap_io)
}
fn emit_bool(&mut self, v: bool) -> EncodingResult<()> {
self.writer.write_u8(if v {1} else {0}).map_err(wrap_io)
}
fn emit_f64(&mut self, v: f64) -> EncodingResult<()> {
self.writer.write_f64::<BigEndian>(v).map_err(wrap_io)
}
fn emit_f32(&mut self, v: f32) -> EncodingResult<()> {
self.writer.write_f32::<BigEndian>(v).map_err(wrap_io)
}
fn emit_char(&mut self, v: char) -> EncodingResult<()> {
// TODO: change this back once unicode works
//let mut cbuf = [0; 4];
//let sz = v.encode_utf8(&mut cbuf[..]).unwrap_or(0);
//let ptr = &cbuf[..sz];
//self.writer.write_all(ptr).map_err(EncodingError::IoError)
let mut inter = String::with_capacity(1);
inter.push(v);
self.writer.write_all(inter.as_bytes()).map_err(EncodingError::IoError)
}
fn emit_str(&mut self, v: &str) -> EncodingResult<()> {
try!(self.emit_usize(v.len()));
self.writer.write_all(v.as_bytes()).map_err(EncodingError::IoError)
}
fn emit_enum<F>(&mut self, __: &str, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_enum_variant<F>(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
let max_u32: u32 = ::std::u32::MAX;
if v_id > (max_u32 as usize) {
panic!("Variant tag doesn't fit in a u32")
}
try!(self.emit_u32(v_id as u32));
f(self)
}
fn emit_enum_variant_arg<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_enum_struct_variant<F>(&mut self,
v_name: &str,
v_id: usize,
len: usize,
f: F)
-> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
self.emit_enum_variant(v_name, v_id, len, f)
}
fn emit_enum_struct_variant_field<F>(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_struct<F>(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_struct_field<F>(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_tuple<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_tuple_arg<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
self.emit_tuple(len, f)
}
fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
self.emit_tuple_arg(f_idx, f)
}
fn emit_option<F>(&mut self, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_option_none(&mut self) -> EncodingResult<()> {
self.writer.write_u8(0).map_err(wrap_io)
}
fn emit_option_some<F>(&mut self, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
try!(self.writer.write_u8(1).map_err(wrap_io));
f(self)
}
fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
try!(self.emit_usize(len));
f(self)
}
fn emit_seq_elt<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_map<F>(&mut self, len: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
try!(self.emit_usize(len));
f(self)
}
fn emit_map_elt_key<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
fn emit_map_elt_val<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut EncoderWriter<'a, W>) -> EncodingResult<()>
{
f(self)
}
}
impl Encoder for SizeChecker {
type Error = EncodingError;
fn emit_nil(&mut self) -> EncodingResult<()> {
Ok(())
}
fn emit_usize(&mut self, v: usize) -> EncodingResult<()> {
self.add_value(v as u64)
}
fn emit_u64(&mut self, v: u64) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_u32(&mut self, v: u32) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_u16(&mut self, v: u16) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_u8(&mut self, v: u8) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_isize(&mut self, v: isize) -> EncodingResult<()> {
self.add_value(v as i64)
}
fn emit_i64(&mut self, v: i64) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_i32(&mut self, v: i32) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_i16(&mut self, v: i16) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_i8(&mut self, v: i8) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_bool(&mut self, _: bool) -> EncodingResult<()> {
self.add_value(0 as u8)
}
fn emit_f64(&mut self, v: f64) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_f32(&mut self, v: f32) -> EncodingResult<()> {
self.add_value(v)
}
fn emit_char(&mut self, v: char) -> EncodingResult<()> {
self.add_raw(v.len_utf8())
}
fn emit_str(&mut self, v: &str) -> EncodingResult<()> {
try!(self.add_value(0 as u64));
self.add_raw(v.len())
}
fn emit_enum<F>(&mut self, __: &str, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_enum_variant<F>(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
try!(self.add_value(v_id as u32));
f(self)
}
fn emit_enum_variant_arg<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_enum_struct_variant<F>(&mut self,
_: &str,
_: usize,
_: usize,
f: F)
-> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_enum_struct_variant_field<F>(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_struct<F>(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_struct_field<F>(&mut self, _: &str, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_tuple<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_tuple_arg<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
self.emit_tuple(len, f)
}
fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
self.emit_tuple_arg(f_idx, f)
}
fn emit_option<F>(&mut self, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_option_none(&mut self) -> EncodingResult<()> {
self.add_value(0 as u8)
}
fn emit_option_some<F>(&mut self, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
try!(self.add_value(1 as u8));
f(self)
}
fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
try!(self.emit_usize(len));
f(self)
}
fn emit_seq_elt<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_map<F>(&mut self, len: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
try!(self.emit_usize(len));
f(self)
}
fn emit_map_elt_key<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
fn emit_map_elt_val<F>(&mut self, _: usize, f: F) -> EncodingResult<()>
where F: FnOnce(&mut SizeChecker) -> EncodingResult<()>
{
f(self)
}
}

View File

@ -0,0 +1,123 @@
//! A collection of serialization and deserialization functions
//! that use the `serde` crate for the serializable and deserializable
//! implementation.
use std::io::{Write, Read};
use ::SizeLimit;
pub use self::reader::{
Deserializer,
DeserializeResult,
DeserializeError,
InvalidEncoding
};
pub use self::writer::{
Serializer,
SerializeResult,
SerializeError,
};
use self::writer::SizeChecker;
use serde_crate as serde;
mod reader;
mod writer;
/// 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 `SerializeError` (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, T>(writer: &mut W, value: &T, size_limit: SizeLimit) -> SerializeResult<()>
where W: Write, T: serde::Serialize,
{
match size_limit {
SizeLimit::Infinite => { }
SizeLimit::Bounded(x) => {
let mut size_checker = SizeChecker::new(x);
try!(value.serialize(&mut size_checker))
}
}
let mut serializer = Serializer::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>(value: &T, size_limit: SizeLimit) -> SerializeResult<Vec<u8>>
where T: serde::Serialize,
{
// Since we are putting values directly into a vector, we can do size
// computation out here and pre-allocate a buffer of *exactly*
// the right size.
let mut writer = match size_limit {
SizeLimit::Bounded(size_limit) => {
let actual_size = match serialized_size_bounded(value, size_limit) {
Some(actual_size) => actual_size,
None => { return Err(SerializeError::SizeLimit); }
};
Vec::with_capacity(actual_size as usize)
}
SizeLimit::Infinite => Vec::new()
};
try!(serialize_into(&mut writer, value, SizeLimit::Infinite));
Ok(writer)
}
/// 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: serde::Serialize>(value: &T) -> u64 {
use std::u64::MAX;
let mut size_checker = SizeChecker::new(MAX);
value.serialize(&mut size_checker).ok();
size_checker.written
}
/// 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: serde::Serialize>(value: &T, max: u64) -> Option<u64> {
let mut size_checker = SizeChecker::new(max);
value.serialize(&mut size_checker).ok().map(|_| size_checker.written)
}
/// 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 `DeserializeError`, 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, T>(reader: &mut R, size_limit: SizeLimit) -> DeserializeResult<T>
where R: Read,
T: serde::Deserialize,
{
let mut deserializer = Deserializer::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<T>(bytes: &[u8]) -> DeserializeResult<T>
where T: serde::Deserialize,
{
let mut reader = bytes;
deserialize_from(&mut reader, SizeLimit::Infinite)
}

View File

@ -0,0 +1,571 @@
use std::io::Read;
use std::io::Error as IoError;
use std::error::Error;
use std::fmt;
use std::convert::From;
use byteorder::{BigEndian, ReadBytesExt};
use num_traits;
use serde_crate as serde;
use serde_crate::de::value::ValueDeserializer;
use ::SizeLimit;
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct InvalidEncoding {
pub desc: &'static str,
pub detail: Option<String>,
}
impl fmt::Display for InvalidEncoding {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
InvalidEncoding { detail: None, desc } =>
write!(fmt, "{}", desc),
InvalidEncoding { detail: Some(ref detail), desc } =>
write!(fmt, "{} ({})", desc, detail)
}
}
}
/// An error that can be produced during decoding.
///
/// If decoding from a Buffer, assume that the buffer has been left
/// in an invalid state.
#[derive(Debug)]
pub enum DeserializeError {
/// If the error stems from the reader that is being used
/// during decoding, 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(InvalidEncoding),
/// If decoding a message takes more than the provided size limit, this
/// error is returned.
SizeLimit,
Serde(serde::de::value::Error)
}
impl Error for DeserializeError {
fn description(&self) -> &str {
match *self {
DeserializeError::IoError(ref err) => Error::description(err),
DeserializeError::InvalidEncoding(ref ib) => ib.desc,
DeserializeError::SizeLimit => "the size limit for decoding has been reached",
DeserializeError::Serde(ref s) => s.description(),
}
}
fn cause(&self) -> Option<&Error> {
match *self {
DeserializeError::IoError(ref err) => err.cause(),
DeserializeError::InvalidEncoding(_) => None,
DeserializeError::SizeLimit => None,
DeserializeError::Serde(ref s) => s.cause(),
}
}
}
impl From<IoError> for DeserializeError {
fn from(err: IoError) -> DeserializeError {
DeserializeError::IoError(err)
}
}
impl From<serde::de::value::Error> for DeserializeError {
fn from(err: serde::de::value::Error) -> DeserializeError {
DeserializeError::Serde(err)
}
}
impl fmt::Display for DeserializeError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
DeserializeError::IoError(ref ioerr) =>
write!(fmt, "IoError: {}", ioerr),
DeserializeError::InvalidEncoding(ref ib) =>
write!(fmt, "InvalidEncoding: {}", ib),
DeserializeError::SizeLimit =>
write!(fmt, "SizeLimit"),
DeserializeError::Serde(ref s) =>
s.fmt(fmt),
}
}
}
impl serde::de::Error for DeserializeError {
fn custom<T: Into<String>>(desc: T) -> DeserializeError {
DeserializeError::Serde(serde::de::value::Error::Custom(desc.into()))
}
fn end_of_stream() -> DeserializeError {
DeserializeError::Serde(serde::de::value::Error::EndOfStream)
}
}
pub type DeserializeResult<T> = Result<T, DeserializeError>;
/// A Deserializer that reads bytes from a buffer.
///
/// This struct should rarely be used.
/// In most cases, prefer the `decode_from` function.
///
/// ```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<'a, R: 'a> {
reader: &'a mut R,
size_limit: SizeLimit,
read: u64
}
impl<'a, R: Read> Deserializer<'a, R> {
pub fn new(r: &'a mut R, size_limit: SizeLimit) -> Deserializer<'a, R> {
Deserializer {
reader: r,
size_limit: size_limit,
read: 0
}
}
/// Returns the number of bytes read from the contained Reader.
pub fn bytes_read(&self) -> u64 {
self.read
}
fn read_bytes(&mut self, count: u64) -> Result<(), DeserializeError> {
self.read += count;
match self.size_limit {
SizeLimit::Infinite => Ok(()),
SizeLimit::Bounded(x) if self.read <= x => Ok(()),
SizeLimit::Bounded(_) => Err(DeserializeError::SizeLimit)
}
}
fn read_type<T>(&mut self) -> Result<(), DeserializeError> {
use std::mem::size_of;
self.read_bytes(size_of::<T>() as u64)
}
fn read_string(&mut self) -> DeserializeResult<String> {
let len = try!(serde::Deserialize::deserialize(self));
try!(self.read_bytes(len));
let mut buffer = Vec::new();
try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buffer));
String::from_utf8(buffer).map_err(|err|
DeserializeError::InvalidEncoding(InvalidEncoding {
desc: "error while decoding utf8 string",
detail: Some(format!("Deserialize error: {}", err))
}))
}
}
macro_rules! impl_nums {
($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
#[inline]
fn $dser_method<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
try!(self.read_type::<$ty>());
let value = try!(self.reader.$reader_method::<BigEndian>());
visitor.$visitor_method(value)
}
}
}
impl<'a, R: Read> serde::Deserializer for Deserializer<'a, R> {
type Error = DeserializeError;
#[inline]
fn deserialize<V>(&mut self, _visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
let message = "bincode does not support Deserializer::deserialize";
Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into())))
}
fn deserialize_bool<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
let value: u8 = try!(serde::Deserialize::deserialize(self));
match value {
1 => visitor.visit_bool(true),
0 => visitor.visit_bool(false),
value => {
Err(DeserializeError::InvalidEncoding(InvalidEncoding {
desc: "invalid u8 when decoding bool",
detail: Some(format!("Expected 0 or 1, got {}", value))
}))
}
}
}
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>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
try!(self.read_type::<u8>());
visitor.visit_u8(try!(self.reader.read_u8()))
}
#[inline]
fn deserialize_usize<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
try!(self.read_type::<u64>());
let value = try!(self.reader.read_u64::<BigEndian>());
match num_traits::cast(value) {
Some(value) => visitor.visit_usize(value),
None => Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected usize".into())))
}
}
#[inline]
fn deserialize_i8<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
try!(self.read_type::<i8>());
visitor.visit_i8(try!(self.reader.read_i8()))
}
#[inline]
fn deserialize_isize<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
try!(self.read_type::<i64>());
let value = try!(self.reader.read_i64::<BigEndian>());
match num_traits::cast(value) {
Some(value) => visitor.visit_isize(value),
None => Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected isize".into()))),
}
}
fn deserialize_unit<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
visitor.visit_unit()
}
fn deserialize_char<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
use std::str;
let error = DeserializeError::InvalidEncoding(InvalidEncoding {
desc: "Invalid char encoding",
detail: None
});
let mut buf = [0];
let _ = try!(self.reader.read(&mut buf[..]));
let first_byte = buf[0];
let width = utf8_char_width(first_byte);
if width == 1 { return visitor.visit_char(first_byte as char) }
if width == 0 { return Err(error)}
let mut buf = [first_byte, 0, 0, 0];
{
let mut start = 1;
while start < width {
match try!(self.reader.read(&mut buf[start .. width])) {
n if n == width - start => break,
n if n < width - start => { start += n; }
_ => return Err(error)
}
}
}
let res = try!(match str::from_utf8(&buf[..width]).ok() {
Some(s) => Ok(s.chars().next().unwrap()),
None => Err(error)
});
visitor.visit_char(res)
}
fn deserialize_str<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
visitor.visit_str(&try!(self.read_string()))
}
fn deserialize_string<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
visitor.visit_string(try!(self.read_string()))
}
fn deserialize_bytes<V>(&mut self, visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
self.deserialize_seq(visitor)
}
fn deserialize_enum<V>(&mut self,
_enum: &'static str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Self::Error>
where V: serde::de::EnumVisitor,
{
visitor.visit(self)
}
fn deserialize_tuple<V>(&mut self,
_len: usize,
mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
struct TupleVisitor<'a, 'b: 'a, R: Read + 'b>(&'a mut Deserializer<'b, R>);
impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, 'b, R> {
type Error = DeserializeError;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: serde::de::Deserialize,
{
let value = try!(serde::Deserialize::deserialize(self.0));
Ok(Some(value))
}
fn end(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
visitor.visit_seq(TupleVisitor(self))
}
fn deserialize_seq_fixed_size<V>(&mut self,
_: usize,
visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
self.deserialize_seq(visitor)
}
fn deserialize_option<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
let value: u8 = try!(serde::de::Deserialize::deserialize(self));
match value {
0 => visitor.visit_none(),
1 => visitor.visit_some(self),
_ => Err(DeserializeError::InvalidEncoding(InvalidEncoding {
desc: "invalid tag when decoding Option",
detail: Some(format!("Expected 0 or 1, got {}", value))
})),
}
}
fn deserialize_seq<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
struct SeqVisitor<'a, 'b: 'a, R: Read + 'b> {
deserializer: &'a mut Deserializer<'b, R>,
len: usize,
}
impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for SeqVisitor<'a, 'b, R> {
type Error = DeserializeError;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: serde::de::Deserialize,
{
if self.len > 0 {
self.len -= 1;
let value = try!(serde::Deserialize::deserialize(self.deserializer));
Ok(Some(value))
} else {
Ok(None)
}
}
fn end(&mut self) -> Result<(), Self::Error> {
if self.len == 0 {
Ok(())
} else {
Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected end".into())))
}
}
}
let len = try!(serde::Deserialize::deserialize(self));
visitor.visit_seq(SeqVisitor { deserializer: self, len: len })
}
fn deserialize_map<V>(&mut self, mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
struct MapVisitor<'a, 'b: 'a, R: Read + 'b> {
deserializer: &'a mut Deserializer<'b, R>,
len: usize,
}
impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for MapVisitor<'a, 'b, R> {
type Error = DeserializeError;
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
where K: serde::de::Deserialize,
{
if self.len > 0 {
self.len -= 1;
let key = try!(serde::Deserialize::deserialize(self.deserializer));
Ok(Some(key))
} else {
Ok(None)
}
}
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
where V: serde::de::Deserialize,
{
let value = try!(serde::Deserialize::deserialize(self.deserializer));
Ok(value)
}
fn end(&mut self) -> Result<(), Self::Error> {
if self.len == 0 {
Ok(())
} else {
Err(DeserializeError::Serde(serde::de::value::Error::Custom("expected end".into())))
}
}
}
let len = try!(serde::Deserialize::deserialize(self));
visitor.visit_map(MapVisitor { deserializer: self, len: len })
}
fn deserialize_struct<V>(&mut self,
_name: &str,
fields: &'static [&'static str],
visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
self.deserialize_tuple(fields.len(), visitor)
}
fn deserialize_struct_field<V>(&mut self,
_visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
let message = "bincode does not support Deserializer::deserialize_struct_field";
Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into())))
}
fn deserialize_newtype_struct<V>(&mut self,
_name: &str,
mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_unit_struct<V>(&mut self,
_name: &'static str,
mut visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
visitor.visit_unit()
}
fn deserialize_tuple_struct<V>(&mut self,
_name: &'static str,
len: usize,
visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
self.deserialize_tuple(len, visitor)
}
fn deserialize_ignored_any<V>(&mut self,
_visitor: V) -> DeserializeResult<V::Value>
where V: serde::de::Visitor,
{
let message = "bincode does not support Deserializer::deserialize_ignored_any";
Err(DeserializeError::Serde(serde::de::value::Error::Custom(message.into())))
}
}
impl<'a, R: Read> serde::de::VariantVisitor for Deserializer<'a, R> {
type Error = DeserializeError;
fn visit_variant<V>(&mut self) -> Result<V, Self::Error>
where V: serde::Deserialize,
{
let index: u32 = try!(serde::Deserialize::deserialize(self));
let mut deserializer = (index as usize).into_deserializer();
let attempt: Result<V, serde::de::value::Error> = serde::Deserialize::deserialize(&mut deserializer);
Ok(try!(attempt))
}
fn visit_unit(&mut self) -> Result<(), Self::Error> {
Ok(())
}
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
where T: serde::de::Deserialize,
{
serde::de::Deserialize::deserialize(self)
}
fn visit_tuple<V>(&mut self,
len: usize,
visitor: V) -> Result<V::Value, Self::Error>
where V: serde::de::Visitor,
{
serde::de::Deserializer::deserialize_tuple(self, len, visitor)
}
fn visit_struct<V>(&mut self,
fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Self::Error>
where V: serde::de::Visitor,
{
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

@ -0,0 +1,642 @@
use std::error::Error;
use std::fmt;
use std::io::Error as IoError;
use std::io::Write;
use std::u32;
use serde_crate as serde;
use byteorder::{BigEndian, WriteBytesExt};
pub type SerializeResult<T> = Result<T, SerializeError>;
/// An error that can be produced during encoding.
#[derive(Debug)]
pub enum SerializeError {
/// An error originating from the underlying `Writer`.
IoError(IoError),
/// An object could not be encoded with the given size limit.
///
/// This error is returned before any bytes are written to the
/// output `Writer`.
SizeLimit,
/// A custom error message
Custom(String)
}
/// An Serializer that encodes values directly into a Writer.
///
/// This struct should not be used often.
/// For most cases, prefer the `encode_into` function.
pub struct Serializer<'a, W: 'a> {
writer: &'a mut W,
}
fn wrap_io(err: IoError) -> SerializeError {
SerializeError::IoError(err)
}
impl serde::ser::Error for SerializeError {
fn custom<T: Into<String>>(msg: T) -> Self {
SerializeError::Custom(msg.into())
}
}
impl fmt::Display for SerializeError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
SerializeError::IoError(ref err) => write!(f, "IoError: {}", err),
SerializeError::Custom(ref s) => write!(f, "Custom Error {}", s),
SerializeError::SizeLimit => write!(f, "SizeLimit"),
}
}
}
impl Error for SerializeError {
fn description(&self) -> &str {
match *self {
SerializeError::IoError(ref err) => Error::description(err),
SerializeError::SizeLimit => "the size limit for decoding has been reached",
SerializeError::Custom(_) => "a custom serialization error was reported",
}
}
fn cause(&self) -> Option<&Error> {
match *self {
SerializeError::IoError(ref err) => err.cause(),
SerializeError::SizeLimit => None,
SerializeError::Custom(_) => None,
}
}
}
impl<'a, W: Write> Serializer<'a, W> {
pub fn new(w: &'a mut W) -> Serializer<'a, W> {
Serializer {
writer: w,
}
}
fn add_enum_tag(&mut self, tag: usize) -> SerializeResult<()> {
if tag > u32::MAX as usize {
panic!("Variant tag doesn't fit in a u32")
}
serde::Serializer::serialize_u32(self, tag as u32)
}
}
impl<'a, W: Write> serde::Serializer for Serializer<'a, W> {
type Error = SerializeError;
type SeqState = ();
type TupleState = ();
type TupleStructState = ();
type TupleVariantState = ();
type MapState = ();
type StructState = ();
type StructVariantState = ();
fn serialize_unit(&mut self) -> SerializeResult<()> { Ok(()) }
fn serialize_unit_struct(&mut self, _: &'static str) -> SerializeResult<()> { Ok(()) }
fn serialize_bool(&mut self, v: bool) -> SerializeResult<()> {
self.writer.write_u8(if v {1} else {0}).map_err(wrap_io)
}
fn serialize_u8(&mut self, v: u8) -> SerializeResult<()> {
self.writer.write_u8(v).map_err(wrap_io)
}
fn serialize_u16(&mut self, v: u16) -> SerializeResult<()> {
self.writer.write_u16::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_u32(&mut self, v: u32) -> SerializeResult<()> {
self.writer.write_u32::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_u64(&mut self, v: u64) -> SerializeResult<()> {
self.writer.write_u64::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_usize(&mut self, v: usize) -> SerializeResult<()> {
self.serialize_u64(v as u64)
}
fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> {
self.writer.write_i8(v).map_err(wrap_io)
}
fn serialize_i16(&mut self, v: i16) -> SerializeResult<()> {
self.writer.write_i16::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_i32(&mut self, v: i32) -> SerializeResult<()> {
self.writer.write_i32::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_i64(&mut self, v: i64) -> SerializeResult<()> {
self.writer.write_i64::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_isize(&mut self, v: isize) -> SerializeResult<()> {
self.serialize_i64(v as i64)
}
fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> {
self.writer.write_f32::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_f64(&mut self, v: f64) -> SerializeResult<()> {
self.writer.write_f64::<BigEndian>(v).map_err(wrap_io)
}
fn serialize_str(&mut self, v: &str) -> SerializeResult<()> {
try!(self.serialize_usize(v.len()));
self.writer.write_all(v.as_bytes()).map_err(SerializeError::IoError)
}
fn serialize_char(&mut self, c: char) -> SerializeResult<()> {
self.writer.write_all(encode_utf8(c).as_slice()).map_err(SerializeError::IoError)
}
fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> {
try!(self.serialize_usize(v.len()));
self.writer.write_all(v).map_err(SerializeError::IoError)
}
fn serialize_none(&mut self) -> SerializeResult<()> {
self.writer.write_u8(0).map_err(wrap_io)
}
fn serialize_some<T>(&mut self, v: T) -> SerializeResult<()>
where T: serde::Serialize,
{
try!(self.writer.write_u8(1).map_err(wrap_io));
v.serialize(self)
}
fn serialize_seq(&mut self, len: Option<usize>) -> SerializeResult<()> {
let len = len.expect("do not know how to serialize a sequence with no length");
self.serialize_usize(len)
}
fn serialize_seq_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_seq_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_seq_fixed_size(&mut self, len: usize) -> SerializeResult<()> {
self.serialize_seq(Some(len))
}
fn serialize_tuple(&mut self, _len: usize) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_tuple_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_struct_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_tuple_struct_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_variant(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str,
_len: usize) -> SerializeResult<()>
{
self.add_enum_tag(variant_index)
}
fn serialize_tuple_variant_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_tuple_variant_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_map(&mut self, len: Option<usize>) -> SerializeResult<()> {
let len = len.expect("do not know how to serialize a map with no length");
self.serialize_usize(len)
}
fn serialize_map_key<K>(&mut self, _: &mut (), key: K) -> SerializeResult<()>
where K: serde::Serialize,
{
key.serialize(self)
}
fn serialize_map_value<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_map_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> {
Ok(())
}
fn serialize_struct_elt<V>(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_struct_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_struct_variant(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str,
_len: usize) -> SerializeResult<()>
{
self.add_enum_tag(variant_index)
}
fn serialize_struct_variant_elt<V>(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_struct_variant_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_newtype_struct<T>(&mut self,
_name: &'static str,
value: T) -> SerializeResult<()>
where T: serde::ser::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str,
value: T) -> SerializeResult<()>
where T: serde::ser::Serialize,
{
try!(self.add_enum_tag(variant_index));
value.serialize(self)
}
fn serialize_unit_variant(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str) -> SerializeResult<()> {
self.add_enum_tag(variant_index)
}
}
pub struct SizeChecker {
pub size_limit: u64,
pub written: u64
}
impl SizeChecker {
pub fn new(limit: u64) -> SizeChecker {
SizeChecker {
size_limit: limit,
written: 0
}
}
fn add_raw(&mut self, size: usize) -> SerializeResult<()> {
self.written += size as u64;
if self.written <= self.size_limit {
Ok(())
} else {
Err(SerializeError::SizeLimit)
}
}
fn add_value<T>(&mut self, t: T) -> SerializeResult<()> {
use std::mem::size_of_val;
self.add_raw(size_of_val(&t))
}
fn add_enum_tag(&mut self, tag: usize) -> SerializeResult<()> {
if tag > u32::MAX as usize {
panic!("Variant tag doesn't fit in a u32")
}
self.add_value(tag as u32)
}
}
impl serde::Serializer for SizeChecker {
type Error = SerializeError;
type SeqState = ();
type TupleState = ();
type TupleStructState = ();
type TupleVariantState = ();
type MapState = ();
type StructState = ();
type StructVariantState = ();
fn serialize_unit(&mut self) -> SerializeResult<()> { Ok(()) }
fn serialize_unit_struct(&mut self, _: &'static str) -> SerializeResult<()> { Ok(()) }
fn serialize_bool(&mut self, _: bool) -> SerializeResult<()> {
self.add_value(0 as u8)
}
fn serialize_u8(&mut self, v: u8) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_u16(&mut self, v: u16) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_u32(&mut self, v: u32) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_u64(&mut self, v: u64) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_usize(&mut self, v: usize) -> SerializeResult<()> {
self.serialize_u64(v as u64)
}
fn serialize_i8(&mut self, v: i8) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_i16(&mut self, v: i16) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_i32(&mut self, v: i32) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_i64(&mut self, v: i64) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_isize(&mut self, v: isize) -> SerializeResult<()> {
self.serialize_i64(v as i64)
}
fn serialize_f32(&mut self, v: f32) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_f64(&mut self, v: f64) -> SerializeResult<()> {
self.add_value(v)
}
fn serialize_str(&mut self, v: &str) -> SerializeResult<()> {
try!(self.add_value(0 as u64));
self.add_raw(v.len())
}
fn serialize_char(&mut self, c: char) -> SerializeResult<()> {
self.add_raw(encode_utf8(c).as_slice().len())
}
fn serialize_bytes(&mut self, v: &[u8]) -> SerializeResult<()> {
try!(self.add_value(0 as u64));
self.add_raw(v.len())
}
fn serialize_none(&mut self) -> SerializeResult<()> {
self.add_value(0 as u8)
}
fn serialize_some<T>(&mut self, v: T) -> SerializeResult<()>
where T: serde::Serialize,
{
try!(self.add_value(1 as u8));
v.serialize(self)
}
fn serialize_seq(&mut self, len: Option<usize>) -> SerializeResult<()> {
let len = len.expect("do not know how to serialize a sequence with no length");
self.serialize_usize(len)
}
fn serialize_seq_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_seq_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_seq_fixed_size(&mut self, len: usize) -> SerializeResult<()> {
self.serialize_seq(Some(len))
}
fn serialize_tuple(&mut self, _len: usize) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_tuple_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_struct_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_tuple_struct_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_tuple_variant(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str,
_len: usize) -> SerializeResult<()>
{
self.add_enum_tag(variant_index)
}
fn serialize_tuple_variant_elt<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_tuple_variant_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_map(&mut self, len: Option<usize>) -> SerializeResult<()>
{
let len = len.expect("do not know how to serialize a map with no length");
self.serialize_usize(len)
}
fn serialize_map_key<K>(&mut self, _: &mut (), key: K) -> SerializeResult<()>
where K: serde::Serialize,
{
key.serialize(self)
}
fn serialize_map_value<V>(&mut self, _: &mut (), value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_map_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_struct(&mut self, _name: &'static str, _len: usize) -> SerializeResult<()> {
Ok(())
}
fn serialize_struct_elt<V>(&mut self, _: &mut (), _key: &'static str, value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_struct_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_struct_variant(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str,
_len: usize) -> SerializeResult<()>
{
self.add_enum_tag(variant_index)
}
fn serialize_struct_variant_elt<V>(&mut self, _: &mut (), _field: &'static str, value: V) -> SerializeResult<()>
where V: serde::Serialize,
{
value.serialize(self)
}
fn serialize_struct_variant_end(&mut self, _: ()) -> SerializeResult<()> {
Ok(())
}
fn serialize_newtype_struct<V: serde::Serialize>(&mut self, _name: &'static str, v: V) -> SerializeResult<()> {
v.serialize(self)
}
fn serialize_unit_variant(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str) -> SerializeResult<()> {
self.add_enum_tag(variant_index)
}
fn serialize_newtype_variant<V: serde::Serialize>(&mut self,
_name: &'static str,
variant_index: usize,
_variant: &'static str,
value: V) -> SerializeResult<()>
{
try!(self.add_enum_tag(variant_index));
value.serialize(self)
}
}
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..]
}
}

579
third_party/rust/bincode/tests/test.rs vendored Normal file
View File

@ -0,0 +1,579 @@
#![feature(proc_macro)]
#[macro_use]
extern crate serde_derive;
extern crate bincode;
extern crate rustc_serialize;
extern crate serde;
use std::fmt::Debug;
use std::collections::HashMap;
use std::ops::Deref;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use bincode::{RefBox, StrBox, SliceBox};
use bincode::SizeLimit::{self, Infinite, Bounded};
use bincode::rustc_serialize::{encode, decode, decode_from, DecodingError};
use bincode::serde::{serialize, deserialize, deserialize_from, DeserializeError, DeserializeResult};
fn proxy_encode<V>(element: &V, size_limit: SizeLimit) -> Vec<u8>
where V: Encodable + Decodable + serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static
{
let v1 = bincode::rustc_serialize::encode(element, size_limit).unwrap();
let v2 = bincode::serde::serialize(element, size_limit).unwrap();
assert_eq!(v1, v2);
v1
}
fn proxy_decode<V>(slice: &[u8]) -> V
where V: Encodable + Decodable + serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static
{
let e1 = bincode::rustc_serialize::decode(slice).unwrap();
let e2 = bincode::serde::deserialize(slice).unwrap();
assert_eq!(e1, e2);
e1
}
fn proxy_encoded_size<V>(element: &V) -> u64
where V: Encodable + serde::Serialize + PartialEq + Debug + 'static
{
let ser_size = bincode::rustc_serialize::encoded_size(element);
let serde_size = bincode::serde::serialized_size(element);
assert_eq!(ser_size, serde_size);
ser_size
}
fn the_same<V>(element: V)
where V: Encodable+Decodable+serde::Serialize+serde::Deserialize+PartialEq+Debug+'static
{
// Make sure that the bahavior isize correct when wrapping with a RefBox.
fn ref_box_correct<V>(v: &V) -> bool
where V: Encodable + Decodable + PartialEq + Debug + 'static
{
let rf = RefBox::new(v);
let encoded = bincode::rustc_serialize::encode(&rf, Infinite).unwrap();
let decoded: RefBox<'static, V> = bincode::rustc_serialize::decode(&encoded[..]).unwrap();
decoded.take().deref() == v
}
let size = proxy_encoded_size(&element);
let encoded = proxy_encode(&element, Infinite);
let decoded = proxy_decode(&encoded[..]);
assert_eq!(element, decoded);
assert_eq!(size, encoded.len() as u64);
assert!(ref_box_correct(&element));
}
#[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(RustcEncodable, RustcDecodable, 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(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
struct Easy {
x: isize,
s: String,
y: usize
}
#[derive(RustcEncodable, RustcDecodable, 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(RustcEncodable, RustcDecodable, Serialize, Deserialize, PartialEq, Debug)]
struct NewtypeStr(usize);
the_same(NewtypeStr(5));
}
#[test]
fn test_struct_tuple() {
#[derive(RustcEncodable, RustcDecodable, 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(RustcEncodable, RustcDecodable, 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 decoding_errors() {
fn isize_invalid_encoding<T>(res: bincode::rustc_serialize::DecodingResult<T>) {
match res {
Ok(_) => panic!("Expecting error"),
Err(DecodingError::IoError(_)) => panic!("Expecting InvalidEncoding"),
Err(DecodingError::SizeLimit) => panic!("Expecting InvalidEncoding"),
Err(DecodingError::InvalidEncoding(_)) => {},
}
}
isize_invalid_encoding(decode::<bool>(&vec![0xA][..]));
isize_invalid_encoding(decode::<String>(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..]));
// Out-of-bounds variant
#[derive(RustcEncodable, RustcDecodable, Serialize)]
enum Test {
One,
Two,
};
isize_invalid_encoding(decode::<Test>(&vec![0, 0, 0, 5][..]));
isize_invalid_encoding(decode::<Option<u8>>(&vec![5, 0][..]));
}
#[test]
fn deserializing_errors() {
fn isize_invalid_deserialize<T: Debug>(res: DeserializeResult<T>) {
match res {
Err(DeserializeError::InvalidEncoding(_)) => {},
Err(DeserializeError::Serde(serde::de::value::Error::UnknownVariant(_))) => {},
Err(DeserializeError::Serde(serde::de::value::Error::InvalidValue(_))) => {},
_ => panic!("Expecting InvalidEncoding, got {:?}", res),
}
}
isize_invalid_deserialize(deserialize::<bool>(&vec![0xA][..]));
isize_invalid_deserialize(deserialize::<String>(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..]));
// Out-of-bounds variant
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, Debug)]
enum Test {
One,
Two,
};
isize_invalid_deserialize(deserialize::<Test>(&vec![0, 0, 0, 5][..]));
isize_invalid_deserialize(deserialize::<Option<u8>>(&vec![5, 0][..]));
}
#[test]
fn too_big_decode() {
let encoded = vec![0,0,0,3];
let decoded: Result<u32, _> = decode_from(&mut &encoded[..], Bounded(3));
assert!(decoded.is_err());
let encoded = vec![0,0,0,3];
let decoded: Result<u32, _> = decode_from(&mut &encoded[..], Bounded(4));
assert!(decoded.is_ok());
}
#[test]
fn too_big_deserialize() {
let serialized = vec![0,0,0,3];
let deserialized: Result<u32, _> = deserialize_from(&mut &serialized[..], Bounded(3));
assert!(deserialized.is_err());
let serialized = vec![0,0,0,3];
let deserialized: Result<u32, _> = deserialize_from(&mut &serialized[..], Bounded(4));
assert!(deserialized.is_ok());
}
#[test]
fn char_serialization() {
let chars = "Aa\0☺♪";
for c in chars.chars() {
let encoded = serialize(&c, Bounded(4)).expect("serializing char failed");
let decoded: char = deserialize(&encoded).expect("deserializing failed");
assert_eq!(decoded, c);
}
}
#[test]
fn too_big_char_decode() {
let encoded = vec![0x41];
let decoded: Result<char, _> = decode_from(&mut &encoded[..], Bounded(1));
assert!(decoded.is_ok());
assert_eq!(decoded.unwrap(), 'A');
}
#[test]
fn too_big_char_deserialize() {
let serialized = vec![0x41];
let deserialized: Result<char, _> = deserialize_from(&mut &serialized[..], Bounded(1));
assert!(deserialized.is_ok());
assert_eq!(deserialized.unwrap(), 'A');
}
#[test]
fn too_big_encode() {
assert!(encode(&0u32, Bounded(3)).is_err());
assert!(encode(&0u32, Bounded(4)).is_ok());
assert!(encode(&"abcde", Bounded(8 + 4)).is_err());
assert!(encode(&"abcde", Bounded(8 + 5)).is_ok());
}
#[test]
fn too_big_serialize() {
assert!(serialize(&0u32, Bounded(3)).is_err());
assert!(serialize(&0u32, Bounded(4)).is_ok());
assert!(serialize(&"abcde", Bounded(8 + 4)).is_err());
assert!(serialize(&"abcde", Bounded(8 + 5)).is_ok());
}
#[test]
fn test_proxy_encoded_size() {
assert!(proxy_encoded_size(&0u8) == 1);
assert!(proxy_encoded_size(&0u16) == 2);
assert!(proxy_encoded_size(&0u32) == 4);
assert!(proxy_encoded_size(&0u64) == 8);
// length isize stored as u64
assert!(proxy_encoded_size(&"") == 8);
assert!(proxy_encoded_size(&"a") == 8 + 1);
assert!(proxy_encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
}
#[test]
fn test_serialized_size() {
assert!(proxy_encoded_size(&0u8) == 1);
assert!(proxy_encoded_size(&0u16) == 2);
assert!(proxy_encoded_size(&0u32) == 4);
assert!(proxy_encoded_size(&0u64) == 8);
// length isize stored as u64
assert!(proxy_encoded_size(&"") == 8);
assert!(proxy_encoded_size(&"a") == 8 + 1);
assert!(proxy_encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
}
#[test]
fn encode_box() {
the_same(Box::new(5));
}
#[test]
fn test_refbox_encode() {
let large_object = vec![1u32,2,3,4,5,6];
let mut large_map = HashMap::new();
large_map.insert(1, 2);
#[derive(RustcEncodable, RustcDecodable, Debug)]
enum Message<'a> {
M1(RefBox<'a, Vec<u32>>),
M2(RefBox<'a, HashMap<u32, u32>>)
}
// Test 1
{
let encoded = encode(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap();
let decoded: Message<'static> = decode(&encoded[..]).unwrap();
match decoded {
Message::M1(b) => assert!(b.take().deref() == &large_object),
_ => assert!(false)
}
}
// Test 2
{
let encoded = encode(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap();
let decoded: Message<'static> = decode(&encoded[..]).unwrap();
match decoded {
Message::M2(b) => assert!(b.take().deref() == &large_map),
_ => assert!(false)
}
}
}
#[test]
fn test_refbox_serialize() {
let large_object = vec![1u32,2,3,4,5,6];
let mut large_map = HashMap::new();
large_map.insert(1, 2);
#[derive(RustcEncodable, RustcDecodable, Serialize, Deserialize, Debug)]
enum Message<'a> {
M1(RefBox<'a, Vec<u32>>),
M2(RefBox<'a, HashMap<u32, u32>>)
}
// Test 1
{
let serialized = serialize(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap();
let deserialized: Message<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
match deserialized {
Message::M1(b) => assert!(b.take().deref() == &large_object),
_ => assert!(false)
}
}
// Test 2
{
let serialized = serialize(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap();
let deserialized: Message<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
match deserialized {
Message::M2(b) => assert!(b.take().deref() == &large_map),
_ => assert!(false)
}
}
}
#[test]
fn test_strbox_encode() {
let strx: &'static str = "hello world";
let encoded = encode(&StrBox::new(strx), Infinite).unwrap();
let decoded: StrBox<'static> = decode(&encoded[..]).unwrap();
let stringx: String = decoded.take();
assert!(strx == &stringx[..]);
}
#[test]
fn test_strbox_serialize() {
let strx: &'static str = "hello world";
let serialized = serialize(&StrBox::new(strx), Infinite).unwrap();
let deserialized: StrBox<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
let stringx: String = deserialized.take();
assert!(strx == &stringx[..]);
}
#[test]
fn test_slicebox_encode() {
let slice = [1u32, 2, 3 ,4, 5];
let encoded = encode(&SliceBox::new(&slice), Infinite).unwrap();
let decoded: SliceBox<'static, u32> = decode(&encoded[..]).unwrap();
{
let sb: &[u32] = &decoded;
assert!(slice == sb);
}
let vecx: Vec<u32> = decoded.take();
assert!(slice == &vecx[..]);
}
#[test]
fn test_slicebox_serialize() {
let slice = [1u32, 2, 3 ,4, 5];
let serialized = serialize(&SliceBox::new(&slice), Infinite).unwrap();
let deserialized: SliceBox<'static, u32> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
{
let sb: &[u32] = &deserialized;
assert!(slice == sb);
}
let vecx: Vec<u32> = deserialized.take();
assert!(slice == &vecx[..]);
}
#[test]
fn test_multi_strings_encode() {
assert!(encode(&("foo", "bar", "baz"), Infinite).is_ok());
}
#[test]
fn test_multi_strings_serialize() {
assert!(serialize(&("foo", "bar", "baz"), Infinite).is_ok());
}
#[test]
fn test_oom_protection() {
use std::io::Cursor;
#[derive(RustcEncodable, RustcDecodable)]
struct FakeVec {
len: u64,
byte: u8
}
let x = bincode::rustc_serialize::encode(&FakeVec { len: 0xffffffffffffffffu64, byte: 1 }, bincode::SizeLimit::Bounded(10)).unwrap();
let y : Result<Vec<u8>, _> = bincode::rustc_serialize::decode_from(&mut Cursor::new(&x[..]), bincode::SizeLimit::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 = bincode::serde::serialize(&path, Infinite).unwrap();
let decoded: PathBuf = bincode::serde::deserialize(&serde_encoded).unwrap();
assert!(path.to_str() == decoded.to_str());
}
#[test]
fn bytes() {
let data = b"abc\0123";
let b = bincode::rustc_serialize::encode(&data, Infinite).unwrap();
let s = bincode::serde::serialize(&data, Infinite).unwrap();
assert_eq!(b, s);
use serde::bytes::Bytes;
let s2 = bincode::serde::serialize(&Bytes::new(data), Infinite).unwrap();
assert_eq!(s, s2);
}
#[test]
fn test_manual_enum_encoding() {
#[derive(PartialEq)]
enum Enumeration {
Variant1,
Variant2 { val: u64 }
}
impl Encodable for Enumeration {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_enum("Enumeration", |s| {
match *self {
Enumeration::Variant1 => {
s.emit_enum_variant("Variant1", 0, 0, |_| Ok(()))
},
Enumeration::Variant2 { val } => {
s.emit_enum_struct_variant("Variant2", 1, 1, |s| {
s.emit_enum_struct_variant_field("val", 0, |s| s.emit_u64(val))
})
}
}
})
}
}
impl Decodable for Enumeration {
fn decode<D: Decoder>(s: &mut D) -> Result<Self, D::Error> {
s.read_enum("Enumeration", |s| {
s.read_enum_struct_variant(&["Variant1", "Variant2"], |s, num| {
match num {
0 => Ok(Enumeration::Variant1),
1 => Ok(Enumeration::Variant2 { val: try!(s.read_u64()) }),
_ => Err(s.error("Unknown enum variant"))
}
})
})
}
}
let encoded = bincode::rustc_serialize::encode(&Enumeration::Variant1, Infinite).unwrap();
let decoded: Enumeration = decode(&encoded[..]).unwrap();
assert!(decoded == Enumeration::Variant1);
let encoded = bincode::rustc_serialize::encode(&Enumeration::Variant2 { val: 42 }, Infinite).unwrap();
let decoded: Enumeration = decode(&encoded[..]).unwrap();
assert!(decoded == Enumeration::Variant2 { val: 42 });
}

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"e684c9479b485343f5b932e8f9de7ac046accfb4c1e3c534e6e0fb9e0c8d919b","Cargo.toml":"a30078c3db5bccf6a567ad9ae78a6258d18b990034eda7e4ce8f4b3041ff2aa9","LICENSE-APACHE":"8173d5c29b4f956d532781d2b86e4e30f83e6b7878dce18c919451d6ba707c90","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"d3a2993cd15ac201b30c86fe69f2bb692b386875eace571715007637d7ca7abf","deploy-docs.sh":"7b66111b124c1c7e59cb84cf110d98b5cb783bd35a676e970d9b3035e55f7dfd","src/lib.rs":"7276279f7008dd633d0bb90cc0ff73de170b89d69644fb21c35728c94e913c4d"},"package":"d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"}

0
third_party/rust/bit-set/.cargo-ok vendored Normal file
View File

2
third_party/rust/bit-set/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
Cargo.lock

18
third_party/rust/bit-set/.travis.yml vendored Normal file
View File

@ -0,0 +1,18 @@
language: rust
sudo: false
matrix:
include:
- rust: stable
- rust: nightly
env: FEATURES="--features nightly"
script:
- cargo build $FEATURES
- cargo test $FEATURES
- cargo doc --no-deps
after_success: |
[ "$TRAVIS_RUST_VERSION" = nightly ] &&
[ "$TRAVIS_BRANCH" = master ] &&
[ "$TRAVIS_PULL_REQUEST" = false ] &&
bash deploy-docs.sh
notifications:
webhooks: http://huon.me:54857/travis

20
third_party/rust/bit-set/Cargo.toml vendored Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "bit-set"
version = "0.4.0"
authors = ["Alexis Beingessner <a.beingessner@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A set of bits"
repository = "https://github.com/contain-rs/bit-set"
homepage = "https://github.com/contain-rs/bit-set"
documentation = "https://contain-rs.github.io/bit-set/bit_set"
keywords = ["data-structures", "bitset"]
readme = "README.md"
[dev-dependencies]
rand = "0.3"
[dependencies]
bit-vec = "0.4"
[features]
nightly = []

201
third_party/rust/bit-set/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
third_party/rust/bit-set/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2016 The Rust Project Developers
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.

6
third_party/rust/bit-set/README.md vendored Normal file
View File

@ -0,0 +1,6 @@
A Set of bits.
Documentation is available at https://contain-rs.github.io/bit-set/bit_set.
[![Build Status](https://travis-ci.org/contain-rs/bit-set.svg?branch=master)](https://travis-ci.org/contain-rs/bit-set)
[![crates.io](http://meritbadge.herokuapp.com/bit-set)](https://crates.io/crates/bit-set)

20
third_party/rust/bit-set/deploy-docs.sh vendored Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
set -o errexit -o nounset
rev=$(git rev-parse --short HEAD)
cd target/doc
git init
git config user.email 'FlashCat@users.noreply.github.com'
git config user.name 'FlashCat'
git remote add upstream "https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git"
git fetch upstream gh-pages
git reset upstream/gh-pages
touch .
git add -A .
git commit -m "rebuild pages at ${rev}"
git push -q upstream HEAD:gh-pages

1436
third_party/rust/bit-set/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"26dbdd3f33aeefa6216804c025626b8e2bef5c05103410faa5e6e93f20331cbe","Cargo.toml":"895a872c944e7c0f4b6f54bae20c6eb0df2f3b3a67a896fc56d1f22b42f5033e","LICENSE-APACHE":"8173d5c29b4f956d532781d2b86e4e30f83e6b7878dce18c919451d6ba707c90","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"2a42423b7acd5af0ee7f47dcc430b267cfe4661ced77131af2d6e97e6a15377a","benches/extern.rs":"30152d15cc55493d06396baf9eebb90c8f32b314f0dc77398ac8a121bd5ff917","crusader.sh":"e656dcb62d5122a64d55f837992e63cfd3beee37cf74c5ab6ff178a3c7ef943e","deploy-docs.sh":"7b66111b124c1c7e59cb84cf110d98b5cb783bd35a676e970d9b3035e55f7dfd","src/bench.rs":"a24345464fdbc70b5b877d13fa1b9da809ba4917e592d5de69f01b8b1340e8bb","src/lib.rs":"7b754cfc597877bbae0e94283cce684a3bf62771a2ec5f01838c84dc3c180f8b"},"package":"5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"}

0
third_party/rust/bit-vec/.cargo-ok vendored Normal file
View File

2
third_party/rust/bit-vec/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
Cargo.lock

19
third_party/rust/bit-vec/.travis.yml vendored Normal file
View File

@ -0,0 +1,19 @@
language: rust
sudo: false
matrix:
include:
- rust: stable
- rust: nightly
env: FEATURES="--features nightly"
script:
- cargo build $FEATURES
- cargo test $FEATURES
- cargo doc --no-deps
- bash crusader.sh
after_success: |
[ "$TRAVIS_RUST_VERSION" = nightly ] &&
[ "$TRAVIS_BRANCH" = master ] &&
[ "$TRAVIS_PULL_REQUEST" = false ] &&
bash deploy-docs.sh
notifications:
webhooks: http://huon.me:54857/travis

17
third_party/rust/bit-vec/Cargo.toml vendored Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "bit-vec"
version = "0.4.3"
authors = ["Alexis Beingessner <a.beingessner@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A vector of bits"
repository = "https://github.com/contain-rs/bit-vec"
homepage = "https://github.com/contain-rs/bit-vec"
documentation = "https://contain-rs.github.io/bit-vec/bit_vec"
keywords = ["data-structures", "bitvec", "bitmask", "bitmap", "bit"]
readme = "README.md"
[dev-dependencies]
rand = "*"
[features]
nightly = []

201
third_party/rust/bit-vec/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
third_party/rust/bit-vec/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2015 The Rust Project Developers
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.

6
third_party/rust/bit-vec/README.md vendored Normal file
View File

@ -0,0 +1,6 @@
A Vec of bits.
Documentation is available at https://contain-rs.github.io/bit-vec/bit_vec.
[![Build Status](https://travis-ci.org/contain-rs/bit-vec.svg?branch=master)](https://travis-ci.org/contain-rs/bit-vec)
[![crates.io](http://meritbadge.herokuapp.com/bit-vec)](https://crates.io/crates/bit-vec)

View File

@ -0,0 +1,22 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![cfg(all(test, feature = "nightly"))]
#![feature(test)]
extern crate test;
extern crate rand;
extern crate bit_vec;
pub use bit_vec::BitVec;
#[path = "../src/bench.rs"]
mod bench;

11
third_party/rust/bit-vec/crusader.sh vendored Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
git clone https://github.com/brson/cargo-crusader
cd cargo-crusader
cargo build --release
export PATH=$PATH:`pwd`/target/release/
cd ../
cargo crusader
exit

20
third_party/rust/bit-vec/deploy-docs.sh vendored Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
set -o errexit -o nounset
rev=$(git rev-parse --short HEAD)
cd target/doc
git init
git config user.email 'FlashCat@users.noreply.github.com'
git config user.name 'FlashCat'
git remote add upstream "https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git"
git fetch upstream gh-pages
git reset upstream/gh-pages
touch .
git add -A .
git commit -m "rebuild pages at ${rev}"
git push -q upstream HEAD:gh-pages

116
third_party/rust/bit-vec/src/bench.rs vendored Normal file
View File

@ -0,0 +1,116 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use super::BitVec;
use rand::{Rng, weak_rng, XorShiftRng};
use test::{Bencher, black_box};
const BENCH_BITS : usize = 1 << 14;
const U32_BITS: usize = 32;
fn rng() -> XorShiftRng {
weak_rng()
}
#[bench]
fn bench_usize_small(b: &mut Bencher) {
let mut r = rng();
let mut bit_vec = 0 as usize;
b.iter(|| {
for _ in 0..100 {
bit_vec |= 1 << ((r.next_u32() as usize) % U32_BITS);
}
black_box(&bit_vec);
});
}
#[bench]
fn bench_bit_set_big_fixed(b: &mut Bencher) {
let mut r = rng();
let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
b.iter(|| {
for _ in 0..100 {
bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
}
black_box(&bit_vec);
});
}
#[bench]
fn bench_bit_set_big_variable(b: &mut Bencher) {
let mut r = rng();
let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
b.iter(|| {
for _ in 0..100 {
bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
}
black_box(&bit_vec);
});
}
#[bench]
fn bench_bit_set_small(b: &mut Bencher) {
let mut r = rng();
let mut bit_vec = BitVec::from_elem(U32_BITS, false);
b.iter(|| {
for _ in 0..100 {
bit_vec.set((r.next_u32() as usize) % U32_BITS, true);
}
black_box(&bit_vec);
});
}
#[bench]
fn bench_bit_vec_big_union(b: &mut Bencher) {
let mut b1 = BitVec::from_elem(BENCH_BITS, false);
let b2 = BitVec::from_elem(BENCH_BITS, false);
b.iter(|| {
b1.union(&b2)
})
}
#[bench]
fn bench_bit_vec_small_iter(b: &mut Bencher) {
let bit_vec = BitVec::from_elem(U32_BITS, false);
b.iter(|| {
let mut sum = 0;
for _ in 0..10 {
for pres in &bit_vec {
sum += pres as usize;
}
}
sum
})
}
#[bench]
fn bench_bit_vec_big_iter(b: &mut Bencher) {
let bit_vec = BitVec::from_elem(BENCH_BITS, false);
b.iter(|| {
let mut sum = 0;
for pres in &bit_vec {
sum += pres as usize;
}
sum
})
}
#[bench]
fn bench_from_elem(b: &mut Bencher) {
let cap = black_box(BENCH_BITS);
let bit = black_box(true);
b.iter(|| {
// create a BitVec and popcount it
BitVec::from_elem(cap, bit).blocks()
.fold(0, |acc, b| acc + b.count_ones())
});
b.bytes = cap as u64 / 8;
}

2089
third_party/rust/bit-vec/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"2b615144d3f4b2e63ba6ec435cc18df7d76354aa07c2a02d6c707028cc448784","Cargo.toml":"db8c2e9ea912c5f3d2d89cf4cf936c448300e356b0fb533db8875923cb135256","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"8cfbc986af45867d9e620188af2392320fe6e0d9536753ba415c94ab522f5fb5","src/lib.rs":"618ce383bb219725363fba174fc66beb4874d9682e5da953f9e3e9cb3f786d5f","tests/external.rs":"546e549ec831876a5dc272bd0537adc9e9886c6da54656c825e7bffc079e2c74","tests/external_no_std.rs":"48929f5109aabc156442d5ae2ab07b4bce5d648488bf49dba725f6ab23bcb48a"},"package":"aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"}

0
third_party/rust/bitflags/.cargo-ok vendored Normal file
View File

2
third_party/rust/bitflags/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/Cargo.lock

24
third_party/rust/bitflags/.travis.yml vendored Normal file
View File

@ -0,0 +1,24 @@
language: rust
rust:
- stable
- beta
- nightly
sudo: false
script:
- cargo build --verbose
- cargo test --verbose
- cargo doc
after_success: |
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
[ $TRAVIS_RUST_VERSION = nightly ] &&
echo '<meta http-equiv=refresh content=0;url=bitflags/index.html>' > target/doc/index.html &&
pip install ghp-import --user $USER &&
$HOME/.local/bin/ghp-import -n target/doc &&
git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
env:
global:
secure: d+l63TtlF6cfFVDGauYRexgx4lBww4ORqqK4Vt75nWbiCbjZYsKXbcTUdhAr193nIVGiNW50A8SekM01F3EngHwHwr6u5kFleOggm+HA0kkBVeX+k2A4WCVVfYI+gth+zk99WaF8h46MA0evhx6FYDoqeyl9oqmVifI4kaqhMwc=
notifications:
email:
on_success: never

13
third_party/rust/bitflags/Cargo.toml vendored Normal file
View File

@ -0,0 +1,13 @@
[package]
name = "bitflags"
version = "0.7.0"
authors = ["The Rust Project Developers"]
license = "MIT/Apache-2.0"
readme = "README.md"
repository = "https://github.com/rust-lang/bitflags"
homepage = "https://github.com/rust-lang/bitflags"
documentation = "https://doc.rust-lang.org/bitflags"
description = """
A macro to generate structures which behave like bitflags.
"""

201
third_party/rust/bitflags/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
third_party/rust/bitflags/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 The Rust Project Developers
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.

24
third_party/rust/bitflags/README.md vendored Normal file
View File

@ -0,0 +1,24 @@
bitflags
========
A Rust macro to generate structures which behave like a set of bitflags
[![Build Status](https://travis-ci.org/rust-lang-nursery/bitflags.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/bitflags)
[Documentation](https://doc.rust-lang.org/bitflags)
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
bitflags = "0.6"
```
and this to your crate root:
```rust
#[macro_use]
extern crate bitflags;
```

808
third_party/rust/bitflags/src/lib.rs vendored Normal file
View File

@ -0,0 +1,808 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A typesafe bitmask flag generator.
#![no_std]
#[cfg(test)]
#[macro_use]
extern crate std;
// Re-export libstd/libcore using an alias so that the macros can work in no_std
// crates while remaining compatible with normal crates.
#[allow(private_in_public)]
#[doc(hidden)]
pub use core as __core;
/// The `bitflags!` macro generates a `struct` that holds a set of C-style
/// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
///
/// The flags should only be defined for integer types, otherwise unexpected
/// type errors may occur at compile time.
///
/// # Example
///
/// ```{.rust}
/// #[macro_use]
/// extern crate bitflags;
///
/// bitflags! {
/// flags Flags: u32 {
/// const FLAG_A = 0b00000001,
/// const FLAG_B = 0b00000010,
/// const FLAG_C = 0b00000100,
/// const FLAG_ABC = FLAG_A.bits
/// | FLAG_B.bits
/// | FLAG_C.bits,
/// }
/// }
///
/// fn main() {
/// let e1 = FLAG_A | FLAG_C;
/// let e2 = FLAG_B | FLAG_C;
/// assert_eq!((e1 | e2), FLAG_ABC); // union
/// assert_eq!((e1 & e2), FLAG_C); // intersection
/// assert_eq!((e1 - e2), FLAG_A); // set difference
/// assert_eq!(!e2, FLAG_A); // set complement
/// }
/// ```
///
/// The generated `struct`s can also be extended with type and trait
/// implementations:
///
/// ```{.rust}
/// #[macro_use]
/// extern crate bitflags;
///
/// use std::fmt;
///
/// bitflags! {
/// flags Flags: u32 {
/// const FLAG_A = 0b00000001,
/// const FLAG_B = 0b00000010,
/// }
/// }
///
/// impl Flags {
/// pub fn clear(&mut self) {
/// self.bits = 0; // The `bits` field can be accessed from within the
/// // same module where the `bitflags!` macro was invoked.
/// }
/// }
///
/// impl fmt::Display for Flags {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "hi!")
/// }
/// }
///
/// fn main() {
/// let mut flags = FLAG_A | FLAG_B;
/// flags.clear();
/// assert!(flags.is_empty());
/// assert_eq!(format!("{}", flags), "hi!");
/// assert_eq!(format!("{:?}", FLAG_A | FLAG_B), "FLAG_A | FLAG_B");
/// assert_eq!(format!("{:?}", FLAG_B), "FLAG_B");
/// }
/// ```
///
/// # Visibility
///
/// The generated struct and its associated flag constants are not exported
/// out of the current module by default. A definition can be exported out of
/// the current module by adding `pub` before `flags`:
///
/// ```{.rust},ignore
/// #[macro_use]
/// extern crate bitflags;
///
/// mod example {
/// bitflags! {
/// pub flags Flags1: u32 {
/// const FLAG_A = 0b00000001,
/// }
/// }
/// bitflags! {
/// flags Flags2: u32 {
/// const FLAG_B = 0b00000010,
/// }
/// }
/// }
///
/// fn main() {
/// let flag1 = example::FLAG_A;
/// let flag2 = example::FLAG_B; // error: const `FLAG_B` is private
/// }
/// ```
///
/// # Attributes
///
/// Attributes can be attached to the generated `struct` by placing them
/// before the `flags` keyword.
///
/// # Trait implementations
///
/// The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
/// traits automatically derived for the `struct` using the `derive` attribute.
/// Additional traits can be derived by providing an explicit `derive`
/// attribute on `flags`.
///
/// The `Extend` and `FromIterator` traits are implemented for the `struct`,
/// too: `Extend` adds the union of the instances of the `struct` iterated over,
/// while `FromIterator` calculates the union.
///
/// The `Debug` trait is also implemented by displaying the bits value of the
/// internal struct.
///
/// ## Operators
///
/// The following operator traits are implemented for the generated `struct`:
///
/// - `BitOr` and `BitOrAssign`: union
/// - `BitAnd` and `BitAndAssign`: intersection
/// - `BitXor` and `BitXorAssign`: toggle
/// - `Sub` and `SubAssign`: set difference
/// - `Not`: set complement
///
/// As long as the assignment operators are unstable rust feature they are only
/// available with the crate feature `assignment_ops` enabled.
///
/// # Methods
///
/// The following methods are defined for the generated `struct`:
///
/// - `empty`: an empty set of flags
/// - `all`: the set of all flags
/// - `bits`: the raw value of the flags currently stored
/// - `from_bits`: convert from underlying bit representation, unless that
/// representation contains bits that do not correspond to a flag
/// - `from_bits_truncate`: convert from underlying bit representation, dropping
/// any bits that do not correspond to flags
/// - `is_empty`: `true` if no flags are currently stored
/// - `is_all`: `true` if all flags are currently set
/// - `intersects`: `true` if there are flags common to both `self` and `other`
/// - `contains`: `true` all of the flags in `other` are contained within `self`
/// - `insert`: inserts the specified flags in-place
/// - `remove`: removes the specified flags in-place
/// - `toggle`: the specified flags will be inserted if not present, and removed
/// if they are.
#[macro_export]
macro_rules! bitflags {
($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
}) => {
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
$(#[$attr])*
pub struct $BitFlags {
bits: $T,
}
$($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
bitflags! {
@_impl flags $BitFlags: $T {
$($(#[$Flag_attr])* const $Flag = $value),+
}
}
};
($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
}) => {
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
$(#[$attr])*
struct $BitFlags {
bits: $T,
}
$($(#[$Flag_attr])* const $Flag: $BitFlags = $BitFlags { bits: $value };)+
bitflags! {
@_impl flags $BitFlags: $T {
$($(#[$Flag_attr])* const $Flag = $value),+
}
}
};
(@_impl flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
}) => {
impl $crate::__core::fmt::Debug for $BitFlags {
fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result {
// This convoluted approach is to handle #[cfg]-based flag
// omission correctly. Some of the $Flag variants may not be
// defined in this module so we create an inner module which
// defines *all* flags to the value of 0. We then create a
// second inner module that defines all of the flags with #[cfg]
// to their real values. Afterwards the glob will import
// variants from the second inner module, shadowing all
// defined variants, leaving only the undefined ones with the
// bit value of 0.
#[allow(dead_code)]
#[allow(unused_assignments)]
mod dummy {
// We can't use the real $BitFlags struct because it may be
// private, which prevents us from using it to define
// public constants.
pub struct $BitFlags {
bits: u64,
}
mod real_flags {
use super::$BitFlags;
$($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags {
bits: super::super::$Flag.bits as u64
};)+
}
// Now we define the "undefined" versions of the flags.
// This way, all the names exist, even if some are #[cfg]ed
// out.
$(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
#[inline]
pub fn fmt(self_: u64,
f: &mut $crate::__core::fmt::Formatter)
-> $crate::__core::fmt::Result {
// Now we import the real values for the flags.
// Only ones that are #[cfg]ed out will be 0.
use self::real_flags::*;
let mut first = true;
$(
// $Flag.bits == 0 means that $Flag doesn't exist
if $Flag.bits != 0 && self_ & $Flag.bits as u64 == $Flag.bits as u64 {
if !first {
try!(f.write_str(" | "));
}
first = false;
try!(f.write_str(stringify!($Flag)));
}
)+
Ok(())
}
}
dummy::fmt(self.bits as u64, f)
}
}
#[allow(dead_code)]
impl $BitFlags {
/// Returns an empty set of flags.
#[inline]
pub fn empty() -> $BitFlags {
$BitFlags { bits: 0 }
}
/// Returns the set containing all flags.
#[inline]
pub fn all() -> $BitFlags {
// See above `dummy` module for why this approach is taken.
#[allow(dead_code)]
mod dummy {
pub struct $BitFlags {
bits: u64,
}
mod real_flags {
use super::$BitFlags;
$($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags {
bits: super::super::$Flag.bits as u64
};)+
}
$(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
#[inline]
pub fn all() -> u64 {
use self::real_flags::*;
$($Flag.bits)|+
}
}
$BitFlags { bits: dummy::all() as $T }
}
/// Returns the raw value of the flags currently stored.
#[inline]
pub fn bits(&self) -> $T {
self.bits
}
/// Convert from underlying bit representation, unless that
/// representation contains bits that do not correspond to a flag.
#[inline]
pub fn from_bits(bits: $T) -> $crate::__core::option::Option<$BitFlags> {
if (bits & !$BitFlags::all().bits()) == 0 {
$crate::__core::option::Option::Some($BitFlags { bits: bits })
} else {
$crate::__core::option::Option::None
}
}
/// Convert from underlying bit representation, dropping any bits
/// that do not correspond to flags.
#[inline]
pub fn from_bits_truncate(bits: $T) -> $BitFlags {
$BitFlags { bits: bits } & $BitFlags::all()
}
/// Returns `true` if no flags are currently stored.
#[inline]
pub fn is_empty(&self) -> bool {
*self == $BitFlags::empty()
}
/// Returns `true` if all flags are currently set.
#[inline]
pub fn is_all(&self) -> bool {
*self == $BitFlags::all()
}
/// Returns `true` if there are flags common to both `self` and `other`.
#[inline]
pub fn intersects(&self, other: $BitFlags) -> bool {
!(*self & other).is_empty()
}
/// Returns `true` all of the flags in `other` are contained within `self`.
#[inline]
pub fn contains(&self, other: $BitFlags) -> bool {
(*self & other) == other
}
/// Inserts the specified flags in-place.
#[inline]
pub fn insert(&mut self, other: $BitFlags) {
self.bits |= other.bits;
}
/// Removes the specified flags in-place.
#[inline]
pub fn remove(&mut self, other: $BitFlags) {
self.bits &= !other.bits;
}
/// Toggles the specified flags in-place.
#[inline]
pub fn toggle(&mut self, other: $BitFlags) {
self.bits ^= other.bits;
}
}
impl $crate::__core::ops::BitOr for $BitFlags {
type Output = $BitFlags;
/// Returns the union of the two sets of flags.
#[inline]
fn bitor(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits | other.bits }
}
}
impl $crate::__core::ops::BitOrAssign for $BitFlags {
/// Adds the set of flags.
#[inline]
fn bitor_assign(&mut self, other: $BitFlags) {
self.bits |= other.bits;
}
}
impl $crate::__core::ops::BitXor for $BitFlags {
type Output = $BitFlags;
/// Returns the left flags, but with all the right flags toggled.
#[inline]
fn bitxor(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits ^ other.bits }
}
}
impl $crate::__core::ops::BitXorAssign for $BitFlags {
/// Toggles the set of flags.
#[inline]
fn bitxor_assign(&mut self, other: $BitFlags) {
self.bits ^= other.bits;
}
}
impl $crate::__core::ops::BitAnd for $BitFlags {
type Output = $BitFlags;
/// Returns the intersection between the two sets of flags.
#[inline]
fn bitand(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits & other.bits }
}
}
impl $crate::__core::ops::BitAndAssign for $BitFlags {
/// Disables all flags disabled in the set.
#[inline]
fn bitand_assign(&mut self, other: $BitFlags) {
self.bits &= other.bits;
}
}
impl $crate::__core::ops::Sub for $BitFlags {
type Output = $BitFlags;
/// Returns the set difference of the two sets of flags.
#[inline]
fn sub(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits & !other.bits }
}
}
impl $crate::__core::ops::SubAssign for $BitFlags {
/// Disables all flags enabled in the set.
#[inline]
fn sub_assign(&mut self, other: $BitFlags) {
self.bits &= !other.bits;
}
}
impl $crate::__core::ops::Not for $BitFlags {
type Output = $BitFlags;
/// Returns the complement of this set of flags.
#[inline]
fn not(self) -> $BitFlags {
$BitFlags { bits: !self.bits } & $BitFlags::all()
}
}
impl $crate::__core::iter::Extend<$BitFlags> for $BitFlags {
fn extend<T: $crate::__core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
for item in iterator {
self.insert(item)
}
}
}
impl $crate::__core::iter::FromIterator<$BitFlags> for $BitFlags {
fn from_iter<T: $crate::__core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
let mut result = Self::empty();
result.extend(iterator);
result
}
}
};
($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
}) => {
bitflags! {
$(#[$attr])*
pub flags $BitFlags: $T {
$($(#[$Flag_attr])* const $Flag = $value),+
}
}
};
($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
}) => {
bitflags! {
$(#[$attr])*
flags $BitFlags: $T {
$($(#[$Flag_attr])* const $Flag = $value),+
}
}
};
}
#[cfg(test)]
#[allow(non_upper_case_globals, dead_code)]
mod tests {
use std::hash::{SipHasher, Hash, Hasher};
bitflags! {
#[doc = "> The first principle is that you must not fool yourself — and"]
#[doc = "> you are the easiest person to fool."]
#[doc = "> "]
#[doc = "> - Richard Feynman"]
flags Flags: u32 {
const FlagA = 0b00000001,
#[doc = "<pcwalton> macros are way better at generating code than trans is"]
const FlagB = 0b00000010,
const FlagC = 0b00000100,
#[doc = "* cmr bed"]
#[doc = "* strcat table"]
#[doc = "<strcat> wait what?"]
const FlagABC = FlagA.bits
| FlagB.bits
| FlagC.bits,
}
}
bitflags! {
flags _CfgFlags: u32 {
#[cfg(windows)]
const _CfgA = 0b01,
#[cfg(unix)]
const _CfgB = 0b01,
#[cfg(windows)]
const _CfgC = _CfgA.bits | 0b10,
}
}
bitflags! {
flags AnotherSetOfFlags: i8 {
const AnotherFlag = -1_i8,
}
}
#[test]
fn test_bits(){
assert_eq!(Flags::empty().bits(), 0b00000000);
assert_eq!(FlagA.bits(), 0b00000001);
assert_eq!(FlagABC.bits(), 0b00000111);
assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
assert_eq!(AnotherFlag.bits(), !0_i8);
}
#[test]
fn test_from_bits() {
assert_eq!(Flags::from_bits(0), Some(Flags::empty()));
assert_eq!(Flags::from_bits(0b1), Some(FlagA));
assert_eq!(Flags::from_bits(0b10), Some(FlagB));
assert_eq!(Flags::from_bits(0b11), Some(FlagA | FlagB));
assert_eq!(Flags::from_bits(0b1000), None);
assert_eq!(AnotherSetOfFlags::from_bits(!0_i8), Some(AnotherFlag));
}
#[test]
fn test_from_bits_truncate() {
assert_eq!(Flags::from_bits_truncate(0), Flags::empty());
assert_eq!(Flags::from_bits_truncate(0b1), FlagA);
assert_eq!(Flags::from_bits_truncate(0b10), FlagB);
assert_eq!(Flags::from_bits_truncate(0b11), (FlagA | FlagB));
assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty());
assert_eq!(Flags::from_bits_truncate(0b1001), FlagA);
assert_eq!(AnotherSetOfFlags::from_bits_truncate(0_i8), AnotherSetOfFlags::empty());
}
#[test]
fn test_is_empty(){
assert!(Flags::empty().is_empty());
assert!(!FlagA.is_empty());
assert!(!FlagABC.is_empty());
assert!(!AnotherFlag.is_empty());
}
#[test]
fn test_is_all() {
assert!(Flags::all().is_all());
assert!(!FlagA.is_all());
assert!(FlagABC.is_all());
assert!(AnotherFlag.is_all());
}
#[test]
fn test_two_empties_do_not_intersect() {
let e1 = Flags::empty();
let e2 = Flags::empty();
assert!(!e1.intersects(e2));
assert!(AnotherFlag.intersects(AnotherFlag));
}
#[test]
fn test_empty_does_not_intersect_with_full() {
let e1 = Flags::empty();
let e2 = FlagABC;
assert!(!e1.intersects(e2));
}
#[test]
fn test_disjoint_intersects() {
let e1 = FlagA;
let e2 = FlagB;
assert!(!e1.intersects(e2));
}
#[test]
fn test_overlapping_intersects() {
let e1 = FlagA;
let e2 = FlagA | FlagB;
assert!(e1.intersects(e2));
}
#[test]
fn test_contains() {
let e1 = FlagA;
let e2 = FlagA | FlagB;
assert!(!e1.contains(e2));
assert!(e2.contains(e1));
assert!(FlagABC.contains(e2));
assert!(AnotherFlag.contains(AnotherFlag));
}
#[test]
fn test_insert(){
let mut e1 = FlagA;
let e2 = FlagA | FlagB;
e1.insert(e2);
assert_eq!(e1, e2);
let mut e3 = AnotherSetOfFlags::empty();
e3.insert(AnotherFlag);
assert_eq!(e3, AnotherFlag);
}
#[test]
fn test_remove(){
let mut e1 = FlagA | FlagB;
let e2 = FlagA | FlagC;
e1.remove(e2);
assert_eq!(e1, FlagB);
let mut e3 = AnotherFlag;
e3.remove(AnotherFlag);
assert_eq!(e3, AnotherSetOfFlags::empty());
}
#[test]
fn test_operators() {
let e1 = FlagA | FlagC;
let e2 = FlagB | FlagC;
assert_eq!((e1 | e2), FlagABC); // union
assert_eq!((e1 & e2), FlagC); // intersection
assert_eq!((e1 - e2), FlagA); // set difference
assert_eq!(!e2, FlagA); // set complement
assert_eq!(e1 ^ e2, FlagA | FlagB); // toggle
let mut e3 = e1;
e3.toggle(e2);
assert_eq!(e3, FlagA | FlagB);
let mut m4 = AnotherSetOfFlags::empty();
m4.toggle(AnotherSetOfFlags::empty());
assert_eq!(m4, AnotherSetOfFlags::empty());
}
#[test]
fn test_assignment_operators() {
let mut m1 = Flags::empty();
let e1 = FlagA | FlagC;
// union
m1 |= FlagA;
assert_eq!(m1, FlagA);
// intersection
m1 &= e1;
assert_eq!(m1, FlagA);
// set difference
m1 -= m1;
assert_eq!(m1, Flags::empty());
// toggle
m1 ^= e1;
assert_eq!(m1, e1);
}
#[test]
fn test_extend() {
let mut flags;
flags = Flags::empty();
flags.extend([].iter().cloned());
assert_eq!(flags, Flags::empty());
flags = Flags::empty();
flags.extend([FlagA, FlagB].iter().cloned());
assert_eq!(flags, FlagA | FlagB);
flags = FlagA;
flags.extend([FlagA, FlagB].iter().cloned());
assert_eq!(flags, FlagA | FlagB);
flags = FlagB;
flags.extend([FlagA, FlagABC].iter().cloned());
assert_eq!(flags, FlagABC);
}
#[test]
fn test_from_iterator() {
assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty());
assert_eq!([FlagA, FlagB].iter().cloned().collect::<Flags>(), FlagA | FlagB);
assert_eq!([FlagA, FlagABC].iter().cloned().collect::<Flags>(), FlagABC);
}
#[test]
fn test_lt() {
let mut a = Flags::empty();
let mut b = Flags::empty();
assert!(!(a < b) && !(b < a));
b = FlagB;
assert!(a < b);
a = FlagC;
assert!(!(a < b) && b < a);
b = FlagC | FlagB;
assert!(a < b);
}
#[test]
fn test_ord() {
let mut a = Flags::empty();
let mut b = Flags::empty();
assert!(a <= b && a >= b);
a = FlagA;
assert!(a > b && a >= b);
assert!(b < a && b <= a);
b = FlagB;
assert!(b > a && b >= a);
assert!(a < b && a <= b);
}
fn hash<T: Hash>(t: &T) -> u64 {
let mut s = SipHasher::new_with_keys(0, 0);
t.hash(&mut s);
s.finish()
}
#[test]
fn test_hash() {
let mut x = Flags::empty();
let mut y = Flags::empty();
assert_eq!(hash(&x), hash(&y));
x = Flags::all();
y = FlagABC;
assert_eq!(hash(&x), hash(&y));
}
#[test]
fn test_debug() {
assert_eq!(format!("{:?}", FlagA | FlagB), "FlagA | FlagB");
assert_eq!(format!("{:?}", FlagABC), "FlagA | FlagB | FlagC | FlagABC");
}
mod submodule {
bitflags! {
pub flags PublicFlags: i8 {
const FlagX = 0,
}
}
bitflags! {
flags PrivateFlags: i8 {
const FlagY = 0,
}
}
#[test]
fn test_private() {
let _ = FlagY;
}
}
#[test]
fn test_public() {
let _ = submodule::FlagX;
}
mod t1 {
mod foo {
pub type Bar = i32;
}
bitflags! {
/// baz
flags Flags: foo::Bar {
const A = 0b00000001,
#[cfg(foo)]
const B = 0b00000010,
#[cfg(foo)]
const C = 0b00000010,
}
}
}
}

View File

@ -0,0 +1,21 @@
#![allow(dead_code)]
#[macro_use]
extern crate bitflags;
bitflags! {
/// baz
flags Flags: u32 {
const A = 0b00000001,
#[doc = "bar"]
const B = 0b00000010,
const C = 0b00000100,
#[doc = "foo"]
const ABC = A.bits | B.bits | C.bits,
}
}
#[test]
fn smoke() {
assert_eq!(ABC, A | B | C);
}

View File

@ -0,0 +1,22 @@
#![allow(dead_code)]
#![no_std]
#[macro_use]
extern crate bitflags;
bitflags! {
/// baz
flags Flags: u32 {
const A = 0b00000001,
#[doc = "bar"]
const B = 0b00000010,
const C = 0b00000100,
#[doc = "foo"]
const ABC = A.bits | B.bits | C.bits,
}
}
#[test]
fn smoke() {
assert_eq!(ABC, A | B | C);
}

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"2879af3c0512f976015d532e2d768f04ff22fdcf8745b69b955b78fda321c3fb",".travis.yml":"81545ce3c6c72111a68434464c3f9fa8df9cbe39759a081fac527628ab21ae0c","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"a7282931b50dff2e463f82baaed95a9d76636bc0fef3e921acd8ca69eab32b83","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","Makefile":"a45a128685a2ae7d4fa39d310786674417ee113055ef290a11f88002285865fc","README.md":"fbcc46b6d0a585096737f50922818b59016b69d959b05f1b29863b2af8e4da43","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"f583692d829c8dfe19b1d5b9e968ccf5c74d6733367ca183edff74041a6afedd","session.vim":"95cb1d7caf0ff7fbe76ec911988d908ddd883381c925ba64b537695bc9f021c4","src/lib.rs":"ef9e7a218fa3a4912c47f6840d32b975940d98277b6c9be85e8d7d045552eb87","src/new.rs":"161c21b7ebb5668c7cc70b46b0eb37709e06bb9c854f2fdfc6ce3d3babcbf3de"},"package":"0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"}

View File

View File

@ -0,0 +1,6 @@
.*.swp
doc
tags
build
target
Cargo.lock

View File

@ -0,0 +1,15 @@
language: rust
matrix:
include:
- rust: "nightly"
env: TEST_SUITE=suite_nightly
- rust: "beta"
env: TEST_SUITE=suite_beta
- rust: "stable"
env: TEST_SUITE=suite_stable
script:
- cargo build --verbose
- cargo test --verbose
- if [ "$TEST_SUITE" = "suite_nightly" ]; then
cargo bench --verbose;
fi

View File

@ -0,0 +1,3 @@
This project is dual-licensed under the Unlicense and MIT licenses.
You may use this code under the terms of either license.

View File

@ -0,0 +1,25 @@
[package]
name = "byteorder"
version = "0.5.3" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = "Library for reading/writing numbers in big-endian and little-endian."
documentation = "http://burntsushi.net/rustdoc/byteorder/"
homepage = "https://github.com/BurntSushi/byteorder"
repository = "https://github.com/BurntSushi/byteorder"
readme = "README.md"
keywords = ["byte", "endian", "big-endian", "little-endian", "binary"]
license = "Unlicense/MIT"
[lib]
name = "byteorder"
[dev-dependencies]
quickcheck = "0.2"
rand = "0.3"
[features]
default = ["std"]
std = []
[profile.bench]
opt-level = 3

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Andrew Gallant
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

@ -0,0 +1,14 @@
all:
echo Nothing to do...
ctags:
ctags --recurse --options=ctags.rust --languages=Rust
docs:
cargo doc
in-dir ./target/doc fix-perms
rscp ./target/doc/* gopher:~/www/burntsushi.net/rustdoc/
push:
git push origin master
git push github master

View File

@ -0,0 +1,59 @@
This crate provides convenience methods for encoding and decoding numbers in
either big-endian or little-endian order. This is meant to replace the old
methods defined on the standard library `Reader` and `Writer` traits.
[![Build status](https://api.travis-ci.org/BurntSushi/byteorder.png)](https://travis-ci.org/BurntSushi/byteorder)
[![](http://meritbadge.herokuapp.com/byteorder)](https://crates.io/crates/byteorder)
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
### Documentation
[http://burntsushi.net/rustdoc/byteorder/](http://burntsushi.net/rustdoc/byteorder/).
The documentation includes examples.
### Installation
This crate works with Cargo and is on
[crates.io](https://crates.io/crates/byteorder). The package is regularly
updated. Add it to your `Cargo.toml` like so:
```toml
[dependencies]
byteorder = "0.5"
```
If you want to augment existing `Read` and `Write` traits, then import the
extension methods like so:
```rust
extern crate byteorder;
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
```
For example:
```rust
use std::io::Cursor;
use byteorder::{BigEndian, ReadBytesExt};
let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
// Note that we use type parameters to indicate which kind of byte order
// we want!
assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
```
### `no_std` crates
This crate has a feature, `std`, that is enabled by default. To use this crate
in a `no_std` context, add the following to your `Cargo.toml`:
```toml
[dependencies]
byteorder = { version = "0.5", default-features = false }
```

View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
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 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.
For more information, please refer to <http://unlicense.org/>

View File

@ -0,0 +1,148 @@
#![feature(test)]
extern crate byteorder;
extern crate test;
macro_rules! bench_num {
($name:ident, $read:ident, $bytes:expr, $data:expr) => (
mod $name {
use byteorder::{ByteOrder, BigEndian, NativeEndian, LittleEndian};
use super::test::Bencher;
use super::test::black_box as bb;
const NITER: usize = 100_000;
#[bench]
fn read_big_endian(b: &mut Bencher) {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
bb(BigEndian::$read(&buf, $bytes));
}
});
}
#[bench]
fn read_little_endian(b: &mut Bencher) {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
bb(LittleEndian::$read(&buf, $bytes));
}
});
}
#[bench]
fn read_native_endian(b: &mut Bencher) {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
bb(NativeEndian::$read(&buf, $bytes));
}
});
}
}
);
($ty:ident, $max:ident,
$read:ident, $write:ident, $size:expr, $data:expr) => (
mod $ty {
use std::$ty;
use byteorder::{ByteOrder, BigEndian, NativeEndian, LittleEndian};
use super::test::Bencher;
use super::test::black_box as bb;
const NITER: usize = 100_000;
#[bench]
fn read_big_endian(b: &mut Bencher) {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
bb(BigEndian::$read(&buf));
}
});
}
#[bench]
fn read_little_endian(b: &mut Bencher) {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
bb(LittleEndian::$read(&buf));
}
});
}
#[bench]
fn read_native_endian(b: &mut Bencher) {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
bb(NativeEndian::$read(&buf));
}
});
}
#[bench]
fn write_big_endian(b: &mut Bencher) {
let mut buf = $data;
let n = $ty::$max;
b.iter(|| {
for _ in 0..NITER {
bb(BigEndian::$write(&mut buf, n));
}
});
}
#[bench]
fn write_little_endian(b: &mut Bencher) {
let mut buf = $data;
let n = $ty::$max;
b.iter(|| {
for _ in 0..NITER {
bb(LittleEndian::$write(&mut buf, n));
}
});
}
#[bench]
fn write_native_endian(b: &mut Bencher) {
let mut buf = $data;
let n = $ty::$max;
b.iter(|| {
for _ in 0..NITER {
bb(NativeEndian::$write(&mut buf, n));
}
});
}
}
);
}
bench_num!(u16, MAX, read_u16, write_u16, 2, [1, 2]);
bench_num!(i16, MAX, read_i16, write_i16, 2, [1, 2]);
bench_num!(u32, MAX, read_u32, write_u32, 4, [1, 2, 3, 4]);
bench_num!(i32, MAX, read_i32, write_i32, 4, [1, 2, 3, 4]);
bench_num!(u64, MAX, read_u64, write_u64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
bench_num!(i64, MAX, read_i64, write_i64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
bench_num!(f32, MAX, read_f32, write_f32, 4, [1, 2, 3, 4]);
bench_num!(f64, MAX, read_f64, write_f64, 8,
[1, 2, 3, 4, 5, 6, 7, 8]);
bench_num!(uint_1, read_uint, 1, [1]);
bench_num!(uint_2, read_uint, 2, [1, 2]);
bench_num!(uint_3, read_uint, 3, [1, 2, 3]);
bench_num!(uint_4, read_uint, 4, [1, 2, 3, 4]);
bench_num!(uint_5, read_uint, 5, [1, 2, 3, 4, 5]);
bench_num!(uint_6, read_uint, 6, [1, 2, 3, 4, 5, 6]);
bench_num!(uint_7, read_uint, 7, [1, 2, 3, 4, 5, 6, 7]);
bench_num!(uint_8, read_uint, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
bench_num!(int_1, read_int, 1, [1]);
bench_num!(int_2, read_int, 2, [1, 2]);
bench_num!(int_3, read_int, 3, [1, 2, 3]);
bench_num!(int_4, read_int, 4, [1, 2, 3, 4]);
bench_num!(int_5, read_int, 5, [1, 2, 3, 4, 5]);
bench_num!(int_6, read_int, 6, [1, 2, 3, 4, 5, 6]);
bench_num!(int_7, read_int, 7, [1, 2, 3, 4, 5, 6, 7]);
bench_num!(int_8, read_int, 8, [1, 2, 3, 4, 5, 6, 7, 8]);

View File

@ -0,0 +1 @@
au BufWritePost *.rs silent!make ctags > /dev/null 2>&1

View File

@ -0,0 +1,802 @@
/*!
This crate provides convenience methods for encoding and decoding numbers
in either big-endian or little-endian order.
The organization of the crate is pretty simple. A trait, `ByteOrder`, specifies
byte conversion methods for each type of number in Rust (sans numbers that have
a platform dependent size like `usize` and `isize`). Two types, `BigEndian`
and `LittleEndian` implement these methods. Finally, `ReadBytesExt` and
`WriteBytesExt` provide convenience methods available to all types that
implement `Read` and `Write`.
# Examples
Read unsigned 16 bit big-endian integers from a `Read` type:
```rust
use std::io::Cursor;
use byteorder::{BigEndian, ReadBytesExt};
let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
// Note that we use type parameters to indicate which kind of byte order
// we want!
assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
```
Write unsigned 16 bit little-endian integers to a `Write` type:
```rust
use byteorder::{LittleEndian, WriteBytesExt};
let mut wtr = vec![];
wtr.write_u16::<LittleEndian>(517).unwrap();
wtr.write_u16::<LittleEndian>(768).unwrap();
assert_eq!(wtr, vec![5, 2, 0, 3]);
```
*/
#![crate_name = "byteorder"]
#![doc(html_root_url = "http://burntsushi.net/rustdoc/byteorder")]
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
#[cfg(feature = "std")]
extern crate core;
use core::mem::transmute;
use core::ptr::copy_nonoverlapping;
#[cfg(feature = "std")]
pub use new::{ReadBytesExt, WriteBytesExt};
#[cfg(feature = "std")]
mod new;
#[inline]
fn extend_sign(val: u64, nbytes: usize) -> i64 {
let shift = (8 - nbytes) * 8;
(val << shift) as i64 >> shift
}
#[inline]
fn unextend_sign(val: i64, nbytes: usize) -> u64 {
let shift = (8 - nbytes) * 8;
(val << shift) as u64 >> shift
}
#[inline]
fn pack_size(n: u64) -> usize {
if n < 1 << 8 {
1
} else if n < 1 << 16 {
2
} else if n < 1 << 24 {
3
} else if n < 1 << 32 {
4
} else if n < 1 << 40 {
5
} else if n < 1 << 48 {
6
} else if n < 1 << 56 {
7
} else {
8
}
}
/// ByteOrder describes types that can serialize integers as bytes.
///
/// Note that `Self` does not appear anywhere in this trait's definition!
/// Therefore, in order to use it, you'll need to use syntax like
/// `T::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
///
/// This crate provides two types that implement `ByteOrder`: `BigEndian`
/// and `LittleEndian`.
///
/// # Examples
///
/// Write and read `u32` numbers in little endian order:
///
/// ```rust
/// use byteorder::{ByteOrder, LittleEndian};
///
/// let mut buf = [0; 4];
/// LittleEndian::write_u32(&mut buf, 1_000_000);
/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
/// ```
///
/// Write and read `i16` numbers in big endian order:
///
/// ```rust
/// use byteorder::{ByteOrder, BigEndian};
///
/// let mut buf = [0; 2];
/// BigEndian::write_i16(&mut buf, -50_000);
/// assert_eq!(-50_000, BigEndian::read_i16(&buf));
/// ```
pub trait ByteOrder {
/// Reads an unsigned 16 bit integer from `buf`.
///
/// Panics when `buf.len() < 2`.
fn read_u16(buf: &[u8]) -> u16;
/// Reads an unsigned 32 bit integer from `buf`.
///
/// Panics when `buf.len() < 4`.
fn read_u32(buf: &[u8]) -> u32;
/// Reads an unsigned 64 bit integer from `buf`.
///
/// Panics when `buf.len() < 8`.
fn read_u64(buf: &[u8]) -> u64;
/// Reads an unsigned n-bytes integer from `buf`.
///
/// Panics when `nbytes < 1` or `nbytes > 8` or
/// `buf.len() < nbytes`
fn read_uint(buf: &[u8], nbytes: usize) -> u64;
/// Writes an unsigned 16 bit integer `n` to `buf`.
///
/// Panics when `buf.len() < 2`.
fn write_u16(buf: &mut [u8], n: u16);
/// Writes an unsigned 32 bit integer `n` to `buf`.
///
/// Panics when `buf.len() < 4`.
fn write_u32(buf: &mut [u8], n: u32);
/// Writes an unsigned 64 bit integer `n` to `buf`.
///
/// Panics when `buf.len() < 8`.
fn write_u64(buf: &mut [u8], n: u64);
/// Writes an unsigned integer `n` to `buf` using only `nbytes`.
///
/// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
/// this method panics.
fn write_uint(buf: &mut [u8], n: u64, nbytes: usize);
/// Reads a signed 16 bit integer from `buf`.
///
/// Panics when `buf.len() < 2`.
#[inline]
fn read_i16(buf: &[u8]) -> i16 {
Self::read_u16(buf) as i16
}
/// Reads a signed 32 bit integer from `buf`.
///
/// Panics when `buf.len() < 4`.
#[inline]
fn read_i32(buf: &[u8]) -> i32 {
Self::read_u32(buf) as i32
}
/// Reads a signed 64 bit integer from `buf`.
///
/// Panics when `buf.len() < 8`.
#[inline]
fn read_i64(buf: &[u8]) -> i64 {
Self::read_u64(buf) as i64
}
/// Reads a signed n-bytes integer from `buf`.
///
/// Panics when `nbytes < 1` or `nbytes > 8` or
/// `buf.len() < nbytes`
#[inline]
fn read_int(buf: &[u8], nbytes: usize) -> i64 {
extend_sign(Self::read_uint(buf, nbytes), nbytes)
}
/// Reads a IEEE754 single-precision (4 bytes) floating point number.
///
/// Panics when `buf.len() < 4`.
#[inline]
fn read_f32(buf: &[u8]) -> f32 {
unsafe { transmute(Self::read_u32(buf)) }
}
/// Reads a IEEE754 double-precision (8 bytes) floating point number.
///
/// Panics when `buf.len() < 8`.
#[inline]
fn read_f64(buf: &[u8]) -> f64 {
unsafe { transmute(Self::read_u64(buf)) }
}
/// Writes a signed 16 bit integer `n` to `buf`.
///
/// Panics when `buf.len() < 2`.
#[inline]
fn write_i16(buf: &mut [u8], n: i16) {
Self::write_u16(buf, n as u16)
}
/// Writes a signed 32 bit integer `n` to `buf`.
///
/// Panics when `buf.len() < 4`.
#[inline]
fn write_i32(buf: &mut [u8], n: i32) {
Self::write_u32(buf, n as u32)
}
/// Writes a signed 64 bit integer `n` to `buf`.
///
/// Panics when `buf.len() < 8`.
#[inline]
fn write_i64(buf: &mut [u8], n: i64) {
Self::write_u64(buf, n as u64)
}
/// Writes a signed integer `n` to `buf` using only `nbytes`.
///
/// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
/// this method panics.
#[inline]
fn write_int(buf: &mut [u8], n: i64, nbytes: usize) {
Self::write_uint(buf, unextend_sign(n, nbytes), nbytes)
}
/// Writes a IEEE754 single-precision (4 bytes) floating point number.
///
/// Panics when `buf.len() < 4`.
#[inline]
fn write_f32(buf: &mut [u8], n: f32) {
Self::write_u32(buf, unsafe { transmute(n) })
}
/// Writes a IEEE754 double-precision (8 bytes) floating point number.
///
/// Panics when `buf.len() < 8`.
#[inline]
fn write_f64(buf: &mut [u8], n: f64) {
Self::write_u64(buf, unsafe { transmute(n) })
}
}
/// Defines big-endian serialization.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[allow(missing_copy_implementations)] pub enum BigEndian {}
/// Defines little-endian serialization.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[allow(missing_copy_implementations)] pub enum LittleEndian {}
/// Defines network byte order serialization.
///
/// Network byte order is defined by [RFC 1700][1] to be big-endian, and is
/// referred to in several protocol specifications. This type is an alias of
/// BigEndian.
///
/// [1]: https://tools.ietf.org/html/rfc1700
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
pub type NetworkEndian = BigEndian;
/// Defines system native-endian serialization.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[cfg(target_endian = "little")]
pub type NativeEndian = LittleEndian;
/// Defines system native-endian serialization.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[cfg(target_endian = "big")]
pub type NativeEndian = BigEndian;
macro_rules! read_num_bytes {
($ty:ty, $size:expr, $src:expr, $which:ident) => ({
assert!($size == ::core::mem::size_of::<$ty>());
assert!($size <= $src.len());
let mut data: $ty = 0;
unsafe {
copy_nonoverlapping(
$src.as_ptr(),
&mut data as *mut $ty as *mut u8,
$size);
}
data.$which()
});
}
macro_rules! write_num_bytes {
($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => ({
assert!($size <= $dst.len());
unsafe {
// N.B. https://github.com/rust-lang/rust/issues/22776
let bytes = transmute::<_, [u8; $size]>($n.$which());
copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
}
});
}
impl ByteOrder for BigEndian {
#[inline]
fn read_u16(buf: &[u8]) -> u16 {
read_num_bytes!(u16, 2, buf, to_be)
}
#[inline]
fn read_u32(buf: &[u8]) -> u32 {
read_num_bytes!(u32, 4, buf, to_be)
}
#[inline]
fn read_u64(buf: &[u8]) -> u64 {
read_num_bytes!(u64, 8, buf, to_be)
}
#[inline]
fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
let mut out = [0u8; 8];
let ptr_out = out.as_mut_ptr();
unsafe {
copy_nonoverlapping(
buf.as_ptr(), ptr_out.offset((8 - nbytes) as isize), nbytes);
(*(ptr_out as *const u64)).to_be()
}
}
#[inline]
fn write_u16(buf: &mut [u8], n: u16) {
write_num_bytes!(u16, 2, n, buf, to_be);
}
#[inline]
fn write_u32(buf: &mut [u8], n: u32) {
write_num_bytes!(u32, 4, n, buf, to_be);
}
#[inline]
fn write_u64(buf: &mut [u8], n: u64) {
write_num_bytes!(u64, 8, n, buf, to_be);
}
#[inline]
fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
assert!(pack_size(n) <= nbytes && nbytes <= 8);
assert!(nbytes <= buf.len());
unsafe {
let bytes: [u8; 8] = transmute(n.to_be());
copy_nonoverlapping(
bytes.as_ptr().offset((8 - nbytes) as isize),
buf.as_mut_ptr(),
nbytes);
}
}
}
impl ByteOrder for LittleEndian {
#[inline]
fn read_u16(buf: &[u8]) -> u16 {
read_num_bytes!(u16, 2, buf, to_le)
}
#[inline]
fn read_u32(buf: &[u8]) -> u32 {
read_num_bytes!(u32, 4, buf, to_le)
}
#[inline]
fn read_u64(buf: &[u8]) -> u64 {
read_num_bytes!(u64, 8, buf, to_le)
}
#[inline]
fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
let mut out = [0u8; 8];
let ptr_out = out.as_mut_ptr();
unsafe {
copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
(*(ptr_out as *const u64)).to_le()
}
}
#[inline]
fn write_u16(buf: &mut [u8], n: u16) {
write_num_bytes!(u16, 2, n, buf, to_le);
}
#[inline]
fn write_u32(buf: &mut [u8], n: u32) {
write_num_bytes!(u32, 4, n, buf, to_le);
}
#[inline]
fn write_u64(buf: &mut [u8], n: u64) {
write_num_bytes!(u64, 8, n, buf, to_le);
}
#[inline]
fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
assert!(pack_size(n as u64) <= nbytes && nbytes <= 8);
assert!(nbytes <= buf.len());
unsafe {
let bytes: [u8; 8] = transmute(n.to_le());
copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
}
}
}
#[cfg(test)]
mod test {
extern crate quickcheck;
extern crate rand;
use test::rand::thread_rng;
use test::quickcheck::{QuickCheck, StdGen, Testable};
const U64_MAX: u64 = ::std::u64::MAX;
const I64_MAX: u64 = ::std::i64::MAX as u64;
fn qc_sized<A: Testable>(f: A, size: u64) {
QuickCheck::new()
.gen(StdGen::new(thread_rng(), size as usize))
.tests(1_00)
.max_tests(10_000)
.quickcheck(f);
}
macro_rules! qc_byte_order {
($name:ident, $ty_int:ident, $max:expr,
$bytes:expr, $read:ident, $write:ident) => (
mod $name {
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
use super::qc_sized;
#[test]
fn big_endian() {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut buf = [0; 8];
BigEndian::$write(&mut buf, n, $bytes);
n == BigEndian::$read(&mut buf[..$bytes], $bytes)
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
#[test]
fn little_endian() {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut buf = [0; 8];
LittleEndian::$write(&mut buf, n, $bytes);
n == LittleEndian::$read(&mut buf[..$bytes], $bytes)
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
#[test]
fn native_endian() {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut buf = [0; 8];
NativeEndian::$write(&mut buf, n, $bytes);
n == NativeEndian::$read(&mut buf[..$bytes], $bytes)
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
}
);
($name:ident, $ty_int:ident, $max:expr,
$read:ident, $write:ident) => (
mod $name {
use std::mem::size_of;
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
use super::qc_sized;
#[test]
fn big_endian() {
fn prop(n: $ty_int) -> bool {
let bytes = size_of::<$ty_int>();
let mut buf = [0; 8];
BigEndian::$write(&mut buf[8 - bytes..], n);
n == BigEndian::$read(&mut buf[8 - bytes..])
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
#[test]
fn little_endian() {
fn prop(n: $ty_int) -> bool {
let bytes = size_of::<$ty_int>();
let mut buf = [0; 8];
LittleEndian::$write(&mut buf[..bytes], n);
n == LittleEndian::$read(&mut buf[..bytes])
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
#[test]
fn native_endian() {
fn prop(n: $ty_int) -> bool {
let bytes = size_of::<$ty_int>();
let mut buf = [0; 8];
NativeEndian::$write(&mut buf[..bytes], n);
n == NativeEndian::$read(&mut buf[..bytes])
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
}
);
}
qc_byte_order!(prop_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
qc_byte_order!(prop_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
qc_byte_order!(prop_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
qc_byte_order!(prop_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
qc_byte_order!(prop_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
qc_byte_order!(prop_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
qc_byte_order!(prop_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
qc_byte_order!(prop_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
qc_byte_order!(prop_uint_1, u64, super::U64_MAX, 1, read_uint, write_uint);
qc_byte_order!(prop_uint_2, u64, super::U64_MAX, 2, read_uint, write_uint);
qc_byte_order!(prop_uint_3, u64, super::U64_MAX, 3, read_uint, write_uint);
qc_byte_order!(prop_uint_4, u64, super::U64_MAX, 4, read_uint, write_uint);
qc_byte_order!(prop_uint_5, u64, super::U64_MAX, 5, read_uint, write_uint);
qc_byte_order!(prop_uint_6, u64, super::U64_MAX, 6, read_uint, write_uint);
qc_byte_order!(prop_uint_7, u64, super::U64_MAX, 7, read_uint, write_uint);
qc_byte_order!(prop_uint_8, u64, super::U64_MAX, 8, read_uint, write_uint);
qc_byte_order!(prop_int_1, i64, super::I64_MAX, 1, read_int, write_int);
qc_byte_order!(prop_int_2, i64, super::I64_MAX, 2, read_int, write_int);
qc_byte_order!(prop_int_3, i64, super::I64_MAX, 3, read_int, write_int);
qc_byte_order!(prop_int_4, i64, super::I64_MAX, 4, read_int, write_int);
qc_byte_order!(prop_int_5, i64, super::I64_MAX, 5, read_int, write_int);
qc_byte_order!(prop_int_6, i64, super::I64_MAX, 6, read_int, write_int);
qc_byte_order!(prop_int_7, i64, super::I64_MAX, 7, read_int, write_int);
qc_byte_order!(prop_int_8, i64, super::I64_MAX, 8, read_int, write_int);
macro_rules! qc_bytes_ext {
($name:ident, $ty_int:ident, $max:expr,
$bytes:expr, $read:ident, $write:ident) => (
mod $name {
use std::io::Cursor;
use {
ReadBytesExt, WriteBytesExt,
BigEndian, NativeEndian, LittleEndian,
};
use super::qc_sized;
#[test]
fn big_endian() {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut wtr = vec![];
wtr.$write::<BigEndian>(n).unwrap();
let mut rdr = Vec::new();
rdr.extend(wtr[8 - $bytes..].iter().map(|&x|x));
let mut rdr = Cursor::new(rdr);
n == rdr.$read::<BigEndian>($bytes).unwrap()
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
#[test]
fn little_endian() {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut wtr = vec![];
wtr.$write::<LittleEndian>(n).unwrap();
let mut rdr = Cursor::new(wtr);
n == rdr.$read::<LittleEndian>($bytes).unwrap()
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
#[test]
fn native_endian() {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut wtr = vec![];
wtr.$write::<NativeEndian>(n).unwrap();
let mut rdr = Cursor::new(wtr);
n == rdr.$read::<NativeEndian>($bytes).unwrap()
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
}
);
($name:ident, $ty_int:ident, $max:expr, $read:ident, $write:ident) => (
mod $name {
use std::io::Cursor;
use {
ReadBytesExt, WriteBytesExt,
BigEndian, NativeEndian, LittleEndian,
};
use super::qc_sized;
#[test]
fn big_endian() {
fn prop(n: $ty_int) -> bool {
let mut wtr = vec![];
wtr.$write::<BigEndian>(n).unwrap();
let mut rdr = Cursor::new(wtr);
n == rdr.$read::<BigEndian>().unwrap()
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
#[test]
fn little_endian() {
fn prop(n: $ty_int) -> bool {
let mut wtr = vec![];
wtr.$write::<LittleEndian>(n).unwrap();
let mut rdr = Cursor::new(wtr);
n == rdr.$read::<LittleEndian>().unwrap()
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
#[test]
fn native_endian() {
fn prop(n: $ty_int) -> bool {
let mut wtr = vec![];
wtr.$write::<NativeEndian>(n).unwrap();
let mut rdr = Cursor::new(wtr);
n == rdr.$read::<NativeEndian>().unwrap()
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
}
);
}
qc_bytes_ext!(prop_ext_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
qc_bytes_ext!(prop_ext_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
qc_bytes_ext!(prop_ext_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
qc_bytes_ext!(prop_ext_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
qc_bytes_ext!(prop_ext_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
qc_bytes_ext!(prop_ext_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
qc_bytes_ext!(prop_ext_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
qc_bytes_ext!(prop_ext_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
qc_bytes_ext!(prop_ext_uint_1, u64, super::U64_MAX, 1, read_uint, write_u64);
qc_bytes_ext!(prop_ext_uint_2, u64, super::U64_MAX, 2, read_uint, write_u64);
qc_bytes_ext!(prop_ext_uint_3, u64, super::U64_MAX, 3, read_uint, write_u64);
qc_bytes_ext!(prop_ext_uint_4, u64, super::U64_MAX, 4, read_uint, write_u64);
qc_bytes_ext!(prop_ext_uint_5, u64, super::U64_MAX, 5, read_uint, write_u64);
qc_bytes_ext!(prop_ext_uint_6, u64, super::U64_MAX, 6, read_uint, write_u64);
qc_bytes_ext!(prop_ext_uint_7, u64, super::U64_MAX, 7, read_uint, write_u64);
qc_bytes_ext!(prop_ext_uint_8, u64, super::U64_MAX, 8, read_uint, write_u64);
qc_bytes_ext!(prop_ext_int_1, i64, super::I64_MAX, 1, read_int, write_i64);
qc_bytes_ext!(prop_ext_int_2, i64, super::I64_MAX, 2, read_int, write_i64);
qc_bytes_ext!(prop_ext_int_3, i64, super::I64_MAX, 3, read_int, write_i64);
qc_bytes_ext!(prop_ext_int_4, i64, super::I64_MAX, 4, read_int, write_i64);
qc_bytes_ext!(prop_ext_int_5, i64, super::I64_MAX, 5, read_int, write_i64);
qc_bytes_ext!(prop_ext_int_6, i64, super::I64_MAX, 6, read_int, write_i64);
qc_bytes_ext!(prop_ext_int_7, i64, super::I64_MAX, 7, read_int, write_i64);
qc_bytes_ext!(prop_ext_int_8, i64, super::I64_MAX, 8, read_int, write_i64);
// Test that all of the byte conversion functions panic when given a
// buffer that is too small.
//
// These tests are critical to ensure safety, otherwise we might end up
// with a buffer overflow.
macro_rules! too_small {
($name:ident, $maximally_small:expr, $zero:expr,
$read:ident, $write:ident) => (
mod $name {
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
#[test]
#[should_panic]
fn read_big_endian() {
let buf = [0; $maximally_small];
BigEndian::$read(&buf);
}
#[test]
#[should_panic]
fn read_little_endian() {
let buf = [0; $maximally_small];
LittleEndian::$read(&buf);
}
#[test]
#[should_panic]
fn read_native_endian() {
let buf = [0; $maximally_small];
NativeEndian::$read(&buf);
}
#[test]
#[should_panic]
fn write_big_endian() {
let mut buf = [0; $maximally_small];
BigEndian::$write(&mut buf, $zero);
}
#[test]
#[should_panic]
fn write_little_endian() {
let mut buf = [0; $maximally_small];
LittleEndian::$write(&mut buf, $zero);
}
#[test]
#[should_panic]
fn write_native_endian() {
let mut buf = [0; $maximally_small];
NativeEndian::$write(&mut buf, $zero);
}
}
);
($name:ident, $maximally_small:expr, $read:ident) => (
mod $name {
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
#[test]
#[should_panic]
fn read_big_endian() {
let buf = [0; $maximally_small];
BigEndian::$read(&buf, $maximally_small + 1);
}
#[test]
#[should_panic]
fn read_little_endian() {
let buf = [0; $maximally_small];
LittleEndian::$read(&buf, $maximally_small + 1);
}
#[test]
#[should_panic]
fn read_native_endian() {
let buf = [0; $maximally_small];
NativeEndian::$read(&buf, $maximally_small + 1);
}
}
);
}
too_small!(small_u16, 1, 0, read_u16, write_u16);
too_small!(small_i16, 1, 0, read_i16, write_i16);
too_small!(small_u32, 3, 0, read_u32, write_u32);
too_small!(small_i32, 3, 0, read_i32, write_i32);
too_small!(small_u64, 7, 0, read_u64, write_u64);
too_small!(small_i64, 7, 0, read_i64, write_i64);
too_small!(small_f32, 3, 0.0, read_f32, write_f32);
too_small!(small_f64, 7, 0.0, read_f64, write_f64);
too_small!(small_uint_1, 1, read_uint);
too_small!(small_uint_2, 2, read_uint);
too_small!(small_uint_3, 3, read_uint);
too_small!(small_uint_4, 4, read_uint);
too_small!(small_uint_5, 5, read_uint);
too_small!(small_uint_6, 6, read_uint);
too_small!(small_uint_7, 7, read_uint);
too_small!(small_int_1, 1, read_int);
too_small!(small_int_2, 2, read_int);
too_small!(small_int_3, 3, read_int);
too_small!(small_int_4, 4, read_int);
too_small!(small_int_5, 5, read_int);
too_small!(small_int_6, 6, read_int);
too_small!(small_int_7, 7, read_int);
#[test]
fn uint_bigger_buffer() {
use {ByteOrder, LittleEndian};
let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
assert_eq!(n, 0x0504030201);
}
}

View File

@ -0,0 +1,269 @@
use std::io::{self, Result};
use ByteOrder;
/// Extends `Read` with methods for reading numbers. (For `std::io`.)
///
/// Most of the methods defined here have an unconstrained type parameter that
/// must be explicitly instantiated. Typically, it is instantiated with either
/// the `BigEndian` or `LittleEndian` types defined in this crate.
///
/// # Examples
///
/// Read unsigned 16 bit big-endian integers from a `Read`:
///
/// ```rust
/// use std::io::Cursor;
/// use byteorder::{BigEndian, ReadBytesExt};
///
/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
/// ```
pub trait ReadBytesExt: io::Read {
/// Reads an unsigned 8 bit integer from the underlying reader.
///
/// Note that since this reads a single byte, no byte order conversions
/// are used. It is included for completeness.
#[inline]
fn read_u8(&mut self) -> Result<u8> {
let mut buf = [0; 1];
try!(self.read_exact(&mut buf));
Ok(buf[0])
}
/// Reads a signed 8 bit integer from the underlying reader.
///
/// Note that since this reads a single byte, no byte order conversions
/// are used. It is included for completeness.
#[inline]
fn read_i8(&mut self) -> Result<i8> {
let mut buf = [0; 1];
try!(self.read_exact(&mut buf));
Ok(buf[0] as i8)
}
/// Reads an unsigned 16 bit integer from the underlying reader.
#[inline]
fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
let mut buf = [0; 2];
try!(self.read_exact(&mut buf));
Ok(T::read_u16(&buf))
}
/// Reads a signed 16 bit integer from the underlying reader.
#[inline]
fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
let mut buf = [0; 2];
try!(self.read_exact(&mut buf));
Ok(T::read_i16(&buf))
}
/// Reads an unsigned 32 bit integer from the underlying reader.
#[inline]
fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
let mut buf = [0; 4];
try!(self.read_exact(&mut buf));
Ok(T::read_u32(&buf))
}
/// Reads a signed 32 bit integer from the underlying reader.
#[inline]
fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
let mut buf = [0; 4];
try!(self.read_exact(&mut buf));
Ok(T::read_i32(&buf))
}
/// Reads an unsigned 64 bit integer from the underlying reader.
#[inline]
fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
let mut buf = [0; 8];
try!(self.read_exact(&mut buf));
Ok(T::read_u64(&buf))
}
/// Reads a signed 64 bit integer from the underlying reader.
#[inline]
fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
let mut buf = [0; 8];
try!(self.read_exact(&mut buf));
Ok(T::read_i64(&buf))
}
/// Reads an unsigned n-bytes integer from the underlying reader.
#[inline]
fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
let mut buf = [0; 8];
try!(self.read_exact(&mut buf[..nbytes]));
Ok(T::read_uint(&buf[..nbytes], nbytes))
}
/// Reads a signed n-bytes integer from the underlying reader.
#[inline]
fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
let mut buf = [0; 8];
try!(self.read_exact(&mut buf[..nbytes]));
Ok(T::read_int(&buf[..nbytes], nbytes))
}
/// Reads a IEEE754 single-precision (4 bytes) floating point number from
/// the underlying reader.
#[inline]
fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
let mut buf = [0; 4];
try!(self.read_exact(&mut buf));
Ok(T::read_f32(&buf))
}
/// Reads a IEEE754 double-precision (8 bytes) floating point number from
/// the underlying reader.
#[inline]
fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
let mut buf = [0; 8];
try!(self.read_exact(&mut buf));
Ok(T::read_f64(&buf))
}
}
/// All types that implement `Read` get methods defined in `ReadBytesExt`
/// for free.
impl<R: io::Read + ?Sized> ReadBytesExt for R {}
/// Extends `Write` with methods for writing numbers. (For `std::io`.)
///
/// Most of the methods defined here have an unconstrained type parameter that
/// must be explicitly instantiated. Typically, it is instantiated with either
/// the `BigEndian` or `LittleEndian` types defined in this crate.
///
/// # Examples
///
/// Write unsigned 16 bit big-endian integers to a `Write`:
///
/// ```rust
/// use byteorder::{BigEndian, WriteBytesExt};
///
/// let mut wtr = vec![];
/// wtr.write_u16::<BigEndian>(517).unwrap();
/// wtr.write_u16::<BigEndian>(768).unwrap();
/// assert_eq!(wtr, vec![2, 5, 3, 0]);
/// ```
pub trait WriteBytesExt: io::Write {
/// Writes an unsigned 8 bit integer to the underlying writer.
///
/// Note that since this writes a single byte, no byte order conversions
/// are used. It is included for completeness.
#[inline]
fn write_u8(&mut self, n: u8) -> Result<()> {
self.write_all(&[n])
}
/// Writes a signed 8 bit integer to the underlying writer.
///
/// Note that since this writes a single byte, no byte order conversions
/// are used. It is included for completeness.
#[inline]
fn write_i8(&mut self, n: i8) -> Result<()> {
self.write_all(&[n as u8])
}
/// Writes an unsigned 16 bit integer to the underlying writer.
#[inline]
fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
let mut buf = [0; 2];
T::write_u16(&mut buf, n);
self.write_all(&buf)
}
/// Writes a signed 16 bit integer to the underlying writer.
#[inline]
fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
let mut buf = [0; 2];
T::write_i16(&mut buf, n);
self.write_all(&buf)
}
/// Writes an unsigned 32 bit integer to the underlying writer.
#[inline]
fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
let mut buf = [0; 4];
T::write_u32(&mut buf, n);
self.write_all(&buf)
}
/// Writes a signed 32 bit integer to the underlying writer.
#[inline]
fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
let mut buf = [0; 4];
T::write_i32(&mut buf, n);
self.write_all(&buf)
}
/// Writes an unsigned 64 bit integer to the underlying writer.
#[inline]
fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
let mut buf = [0; 8];
T::write_u64(&mut buf, n);
self.write_all(&buf)
}
/// Writes a signed 64 bit integer to the underlying writer.
#[inline]
fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
let mut buf = [0; 8];
T::write_i64(&mut buf, n);
self.write_all(&buf)
}
/// Writes an unsigned n-bytes integer to the underlying writer.
///
/// If the given integer is not representable in the given number of bytes,
/// this method panics. If `nbytes > 8`, this method panics.
#[inline]
fn write_uint<T: ByteOrder>(
&mut self,
n: u64,
nbytes: usize,
) -> Result<()> {
let mut buf = [0; 8];
T::write_uint(&mut buf, n, nbytes);
self.write_all(&buf[0..nbytes])
}
/// Writes a signed n-bytes integer to the underlying writer.
///
/// If the given integer is not representable in the given number of bytes,
/// this method panics. If `nbytes > 8`, this method panics.
#[inline]
fn write_int<T: ByteOrder>(
&mut self,
n: i64,
nbytes: usize,
) -> Result<()> {
let mut buf = [0; 8];
T::write_int(&mut buf, n, nbytes);
self.write_all(&buf[0..nbytes])
}
/// Writes a IEEE754 single-precision (4 bytes) floating point number to
/// the underlying writer.
#[inline]
fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
let mut buf = [0; 4];
T::write_f32(&mut buf, n);
self.write_all(&buf)
}
/// Writes a IEEE754 double-precision (8 bytes) floating point number to
/// the underlying writer.
#[inline]
fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
let mut buf = [0; 8];
T::write_f64(&mut buf, n);
self.write_all(&buf)
}
}
/// All types that implement `Write` get methods defined in `WriteBytesExt`
/// for free.
impl<W: io::Write + ?Sized> WriteBytesExt for W {}

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"944bf600c6230664922a011cbca026699969f2f89f6c7ff689835836ccd7b1de",".travis.yml":"ea512c9287deceaab4ee436a1246874c84e7a422a90cd3aa3e8f9d3121824674","COPYING":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"e651a297d1d1445870a6380de53f1fd33f4ac9c349ff4197d740e24c9a16ca47","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"5b2cad1e1bd53b9f986974a23dbcbd951270a567d6c661f3584707d7ad198e82","src/cgl.rs":"d41fea7f18c07912f485d041baeb99010023084b449af69c6c92dfdcaf1c96e8","src/lib.rs":"8a86ac23aaea868d951a1c51300670d1eda525681d0b144964a6c81737f485e6"},"package":"8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10"}

0
third_party/rust/cgl/.cargo-ok vendored Normal file
View File

2
third_party/rust/cgl/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
Cargo.lock
target

8
third_party/rust/cgl/.travis.yml vendored Normal file
View File

@ -0,0 +1,8 @@
os: osx
language: rust
sudo: false
branches:
except:
- master
notifications:
webhooks: http://build.servo.org:54856/travis

5
third_party/rust/cgl/COPYING vendored Normal file
View File

@ -0,0 +1,5 @@
Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
option. All files in the project carrying such notice may not be
copied, modified, or distributed except according to those terms.

11
third_party/rust/cgl/Cargo.toml vendored Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "cgl"
license = "MIT / Apache-2.0"
version = "0.1.5"
authors = ["The Servo Project Developers"]
description = "Rust bindings for CGL on Mac"
repository = "https://github.com/servo/cgl-rs"
[dependencies]
libc = "0.2"
gleam = "0.2"

201
third_party/rust/cgl/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
third_party/rust/cgl/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2012-2013 Mozilla Foundation
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.

4
third_party/rust/cgl/README.md vendored Normal file
View File

@ -0,0 +1,4 @@
rust-cgl
========
Rust bindings for CGL on Mac

196
third_party/rust/cgl/src/cgl.rs vendored Normal file
View File

@ -0,0 +1,196 @@
// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Mac-specific OpenGL bindings.
#![allow(non_upper_case_globals)]
use gleam::gl::{GLenum, GLint, GLsizei, GLuint};
use libc::{c_void, c_int, c_char};
pub type CGLPixelFormatAttribute = c_int;
pub type CGLContextParameter = c_int;
pub type CGLContextEnable = c_int;
pub type CGLGlobalOption = c_int;
pub type CGLError = c_int;
pub type CGLPixelFormatObj = *mut c_void;
pub type CGLContextObj = *mut c_void;
pub type CGLShareGroupObj = *mut c_void;
pub type IOSurfaceRef = *mut c_void;
pub const kCGLNoError: CGLError = 0;
pub const kCGLPFAAllRenderers: CGLPixelFormatAttribute = 1;
pub const kCGLPFADoubleBuffer: CGLPixelFormatAttribute = 5;
pub const kCGLPFAStereo: CGLPixelFormatAttribute = 6;
pub const kCGLPFAAuxBuffers: CGLPixelFormatAttribute = 7;
pub const kCGLPFAColorSize: CGLPixelFormatAttribute = 8;
pub const kCGLPFAAlphaSize: CGLPixelFormatAttribute = 11;
pub const kCGLPFADepthSize: CGLPixelFormatAttribute = 12;
pub const kCGLPFAStencilSize: CGLPixelFormatAttribute = 13;
pub const kCGLPFAAccumSize: CGLPixelFormatAttribute = 14;
pub const kCGLPFAMinimumPolicy: CGLPixelFormatAttribute = 51;
pub const kCGLPFAMaximumPolicy: CGLPixelFormatAttribute = 52;
pub const kCGLPFAOffScreen: CGLPixelFormatAttribute = 53;
pub const kCGLPFAFullScreen: CGLPixelFormatAttribute = 54;
pub const kCGLPFASampleBuffers: CGLPixelFormatAttribute = 55;
pub const kCGLPFASamples: CGLPixelFormatAttribute = 56;
pub const kCGLPFAAuxDepthStencil: CGLPixelFormatAttribute = 57;
pub const kCGLPFAColorFloat: CGLPixelFormatAttribute = 58;
pub const kCGLPFAMultisample: CGLPixelFormatAttribute = 59;
pub const kCGLPFASupersample: CGLPixelFormatAttribute = 60;
pub const kCGLPFASampleAlpha: CGLPixelFormatAttribute = 61;
pub const kCGLPFARendererID: CGLPixelFormatAttribute = 70;
pub const kCGLPFASingleRenderer: CGLPixelFormatAttribute = 71;
pub const kCGLPFANoRecovery: CGLPixelFormatAttribute = 72;
pub const kCGLPFAAccelerated: CGLPixelFormatAttribute = 73;
pub const kCGLPFAClosestPolicy: CGLPixelFormatAttribute = 74;
pub const kCGLPFARobust: CGLPixelFormatAttribute = 75;
pub const kCGLPFABackingStore: CGLPixelFormatAttribute = 76;
pub const kCGLPFAMPSafe: CGLPixelFormatAttribute = 78;
pub const kCGLPFAWindow: CGLPixelFormatAttribute = 80;
pub const kCGLPFAMultiScreen: CGLPixelFormatAttribute = 81;
pub const kCGLPFACompliant: CGLPixelFormatAttribute = 83;
pub const kCGLPFADisplayMask: CGLPixelFormatAttribute = 84;
pub const kCGLPFAPBuffer: CGLPixelFormatAttribute = 90;
pub const kCGLPFARemotePBuffer: CGLPixelFormatAttribute = 91;
pub const kCGLPFAAllowOfflineRenderers: CGLPixelFormatAttribute = 96;
pub const kCGLPFAAcceleratedCompute: CGLPixelFormatAttribute = 97;
pub const kCGLPFAOpenGLProfile: CGLPixelFormatAttribute = 99;
pub const kCGLPFAVirtualScreenCount: CGLPixelFormatAttribute = 128;
pub const kCGLCESwapRectangle: CGLContextEnable = 201;
pub const kCGLCESwapLimit: CGLContextEnable = 203;
pub const kCGLCERasterization: CGLContextEnable = 221;
pub const kCGLCEStateValidation: CGLContextEnable = 301;
pub const kCGLCESurfaceBackingSize: CGLContextEnable = 305;
pub const kCGLCEDisplayListOptimization: CGLContextEnable = 307;
pub const kCGLCEMPEngine: CGLContextEnable = 313;
pub const kCGLCECrashOnRemovedFunctions: CGLContextEnable = 316;
pub const kCGLCPSwapRectangle: CGLContextParameter = 200;
pub const kCGLCPSwapInterval: CGLContextParameter = 222;
pub const kCGLCPDispatchTableSize: CGLContextParameter = 224;
pub const kCGLCPClientStorage: CGLContextParameter = 226;
pub const kCGLCPSurfaceTexture: CGLContextParameter = 228;
pub const kCGLCPSurfaceOrder: CGLContextParameter = 235;
pub const kCGLCPSurfaceOpacity: CGLContextParameter = 236;
pub const kCGLCPSurfaceBackingSize: CGLContextParameter = 304;
pub const kCGLCPSurfaceSurfaceVolatile: CGLContextParameter = 306;
pub const kCGLCPReclaimResources: CGLContextParameter = 308;
pub const kCGLCPCurrentRendererID: CGLContextParameter = 309;
pub const kCGLCPGPUVertexProcessing: CGLContextParameter = 310;
pub const kCGLCPGPUFragmentProcessing: CGLContextParameter = 311;
pub const kCGLCPHasDrawable: CGLContextParameter = 314;
pub const kCGLCPMPSwapsInFlight: CGLContextParameter = 315;
pub const kCGLGOFormatCacheSize: CGLGlobalOption = 501;
pub const kCGLGOClearFormatCache: CGLGlobalOption = 502;
pub const kCGLGORetainRenderers: CGLGlobalOption = 503;
pub const kCGLGOResetLibrary: CGLGlobalOption = 504;
pub const kCGLGOUseErrorHandler: CGLGlobalOption = 505;
pub const kCGLGOUseBuildCache: CGLGlobalOption = 506;
pub const CORE_BOOLEAN_ATTRIBUTES: &'static [CGLPixelFormatAttribute] =
&[kCGLPFAAllRenderers,
kCGLPFADoubleBuffer,
kCGLPFAStereo,
kCGLPFAAuxBuffers,
kCGLPFAMinimumPolicy,
kCGLPFAMaximumPolicy,
kCGLPFAOffScreen,
kCGLPFAFullScreen,
kCGLPFAAuxDepthStencil,
kCGLPFAColorFloat,
kCGLPFAMultisample,
kCGLPFASupersample,
kCGLPFASampleAlpha,
kCGLPFASingleRenderer,
kCGLPFANoRecovery,
kCGLPFAAccelerated,
kCGLPFAClosestPolicy,
kCGLPFARobust,
kCGLPFABackingStore,
kCGLPFAMPSafe,
kCGLPFAWindow,
kCGLPFAMultiScreen,
kCGLPFACompliant,
kCGLPFAPBuffer,
kCGLPFARemotePBuffer,
kCGLPFAAllowOfflineRenderers,
kCGLPFAAcceleratedCompute];
pub const CORE_INTEGER_ATTRIBUTES: &'static [CGLPixelFormatAttribute] =
&[kCGLPFAColorSize,
kCGLPFAAlphaSize,
kCGLPFADepthSize,
kCGLPFAStencilSize,
kCGLPFAAccumSize,
kCGLPFASampleBuffers,
kCGLPFASamples,
kCGLPFARendererID,
kCGLPFADisplayMask,
kCGLPFAOpenGLProfile,
kCGLPFAVirtualScreenCount];
#[link(name = "OpenGL", kind = "framework")]
extern {
// CGLCurrent.h
pub fn CGLSetCurrentContext(ctx: CGLContextObj) -> CGLError;
pub fn CGLGetCurrentContext() -> CGLContextObj;
pub fn CGLGetShareGroup(context: CGLContextObj) -> CGLShareGroupObj;
// OpenGL.h
// Pixel format functions
pub fn CGLChoosePixelFormat(attribs: *const CGLPixelFormatAttribute,
pix: *mut CGLPixelFormatObj,
npix: *mut GLint) -> CGLError;
pub fn CGLDescribePixelFormat(pix: CGLPixelFormatObj,
pix_num: GLint,
attrib: CGLPixelFormatAttribute,
value: *mut GLint) -> CGLError;
pub fn CGLDestroyPixelFormat(pix: CGLPixelFormatObj) -> CGLError;
// Context functions
pub fn CGLCreateContext(pix: CGLPixelFormatObj, share: CGLContextObj, ctx: *mut CGLContextObj) ->
CGLError;
pub fn CGLDestroyContext(ctx: CGLContextObj) -> CGLError;
pub fn CGLGetPixelFormat(ctx: CGLContextObj) -> CGLPixelFormatObj;
// Getting and Setting Context Options
pub fn CGLEnable(ctx: CGLContextObj, pname: CGLContextEnable) -> CGLError;
pub fn CGLDisable(ctx: CGLContextObj, pname: CGLContextEnable) -> CGLError;
pub fn CGLIsEnabled(ctx: CGLContextObj, pname: CGLContextEnable, enable: &mut GLint) -> CGLError;
pub fn CGLSetParameter(ctx: CGLContextObj, pname: CGLContextParameter, params: &GLint) -> CGLError;
pub fn CGLGetParameter(ctx: CGLContextObj, pname: CGLContextParameter, params: &mut GLint) -> CGLError;
// Locking functions
pub fn CGLLockContext(ctx: CGLContextObj) -> CGLError;
pub fn CGLUnlockContext(ctx: CGLContextObj) -> CGLError;
// Getting and Setting Global Information
pub fn CGLSetOption(pname: CGLGlobalOption, param: &GLint) -> CGLError;
pub fn CGLGetOption(pname: CGLGlobalOption, param: &mut GLint) -> CGLError;
pub fn CGLSetGlobalOption(pname: CGLGlobalOption, param: &GLint) -> CGLError;
pub fn CGLGetGlobalOption(pname: CGLGlobalOption, param: &mut GLint) -> CGLError;
pub fn CGLGetVersion (major: &mut GLint, minor: &mut GLint) -> CGLError;
// CGLIOSurface.h
pub fn CGLTexImageIOSurface2D(ctx: CGLContextObj, target: GLenum, internal_format: GLenum,
width: GLsizei, height: GLsizei, format: GLenum, ty: GLenum,
ioSurface: IOSurfaceRef, plane: GLuint) -> CGLError;
// https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CGL_OpenGL/#//apple_ref/c/func/CGLErrorString
pub fn CGLErrorString(error: CGLError) -> *const c_char;
}

18
third_party/rust/cgl/src/lib.rs vendored Normal file
View File

@ -0,0 +1,18 @@
// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_name = "cgl"]
#![crate_type = "lib"]
extern crate libc;
extern crate gleam;
pub use cgl::*;
mod cgl;

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"f99593f6c99ed02fd0bd95592e27fd84e0e7508f5ad4c27a185d0c29c1bc38e2","build.rs":"4dbf3e5a423e5eba48fc7f11e4f7638c054e53a3750c888059a96d96f8923ef2","src/array.rs":"d648ed8cf0ccb72c3ca0d9e018a3db804edad9685739eba13f8f515e04f3708b","src/base.rs":"36e8ba1ef798331679972e532a61447a327c2af7697631cb25040b581839410c","src/bundle.rs":"ff5f5253f331b7fa054414a3f256d74760e3ce805b720cdb735a2e46cc66dce6","src/data.rs":"21e968951fe56e080d33474f4438de2dfb7e0c8af426a6dfb100efdd6c530eec","src/date.rs":"f6cdcb94658fafc5bacb83cfbd20ad97502b8ddf6bd1c0c0d6a2545a4f7b7420","src/dictionary.rs":"97c40c1afc719b970968179112ad76c3c89b6b4eb4ea18f7ac3f059d98cce736","src/error.rs":"61bc31a401ec6c8495668175eade9284e257da056fc666af74a5555af5daf33f","src/lib.rs":"8bdbc6ed8fcbbc5b69d7634031ff44d50b9ac789279eb89b80c280ea156c98b3","src/messageport.rs":"59ba92ca90bb9b3162b6df44188fac18cd979250f33a52361144c902e86529bd","src/number.rs":"8881c7cd1b510c654c445485de898f83abda91557fd3e6f9daccf2d1b9c4c57e","src/propertylist.rs":"cc2b27f8f8ebc80c03871b7b1ad50ee348539b016078ce721c86b8cd5f9d75bd","src/runloop.rs":"7feab3bbb9913c3b40285bc37b920f9fe4d937d1db08d8ae69a2ec9597713598","src/set.rs":"51e978fc81d4c55013dfc6df4e76c58daaf5deedf9aafda0f6a9e04e7575272c","src/string.rs":"27b92e8e5d3fc95a521dc6447ccfefd9eb28ec5f42bd8571defd124d950b133f","src/url.rs":"bd9f162e2e3e316267b0d36c4d0551dbf2435a40bd1e69bbe0efafd72d232432"},"package":"065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d"}

View File

View File

@ -0,0 +1,13 @@
[package]
name = "core-foundation-sys"
description = "Bindings to Core Foundation for OS X"
homepage = "https://github.com/servo/core-foundation-rs"
repository = "https://github.com/servo/core-foundation-rs"
version = "0.2.3"
authors = ["The Servo Project Developers"]
license = "MIT / Apache-2.0"
build = "build.rs"
links = "CoreFoundation.framework"
[dependencies]
libc = "0.2"

View File

@ -0,0 +1,12 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
println!("cargo:rustc-link-lib=framework=CoreFoundation");
}

View File

@ -0,0 +1,61 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::c_void;
use base::{CFRange, CFIndex, CFAllocatorRef, CFTypeID};
/// FIXME(pcwalton): This is wrong.
pub type CFArrayRetainCallBack = *const u8;
/// FIXME(pcwalton): This is wrong.
pub type CFArrayReleaseCallBack = *const u8;
/// FIXME(pcwalton): This is wrong.
pub type CFArrayCopyDescriptionCallBack = *const u8;
/// FIXME(pcwalton): This is wrong.
pub type CFArrayEqualCallBack = *const u8;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CFArrayCallBacks {
pub version: CFIndex,
pub retain: CFArrayRetainCallBack,
pub release: CFArrayReleaseCallBack,
pub copyDescription: CFArrayCopyDescriptionCallBack,
pub equal: CFArrayEqualCallBack,
}
#[repr(C)]
pub struct __CFArray(c_void);
pub type CFArrayRef = *const __CFArray;
extern {
/*
* CFArray.h
*/
pub static kCFTypeArrayCallBacks: CFArrayCallBacks;
pub fn CFArrayCreate(allocator: CFAllocatorRef, values: *const *const c_void,
numValues: CFIndex, callBacks: *const CFArrayCallBacks) -> CFArrayRef;
pub fn CFArrayCreateCopy(allocator: CFAllocatorRef , theArray: CFArrayRef) -> CFArrayRef;
// CFArrayBSearchValues
// CFArrayContainsValue
pub fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex;
// CFArrayGetCountOfValue
// CFArrayGetFirstIndexOfValue
// CFArrayGetLastIndexOfValue
pub fn CFArrayGetValues(theArray: CFArrayRef, range: CFRange, values: *mut *const c_void);
pub fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *const c_void;
// CFArrayApplyFunction
pub fn CFArrayGetTypeID() -> CFTypeID;
}

View File

@ -0,0 +1,75 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::{c_uint, c_long, c_ulong, c_void};
pub type Boolean = u8;
pub type CFIndex = c_long;
pub type mach_port_t = c_uint;
pub type CFAllocatorRef = *const c_void;
pub type CFNullRef = *const c_void;
pub type CFHashCode = c_ulong;
pub type CFTypeID = c_ulong;
pub type CFTypeRef = *const c_void;
pub type CFOptionFlags = u32;
pub type OSStatus = i32;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CFRange {
pub location: CFIndex,
pub length: CFIndex
}
// for back-compat
impl CFRange {
pub fn init(location: CFIndex, length: CFIndex) -> CFRange {
CFRange {
location: location,
length: length,
}
}
}
extern {
/*
* CFBase.h
*/
/* CFAllocator Reference */
// N.B. Many CFAllocator functions and constants are omitted here.
pub static kCFAllocatorDefault: CFAllocatorRef;
pub static kCFAllocatorSystemDefault: CFAllocatorRef;
pub static kCFAllocatorMalloc: CFAllocatorRef;
pub static kCFAllocatorMallocZone: CFAllocatorRef;
pub static kCFAllocatorNull: CFAllocatorRef;
pub static kCFAllocatorUseContext: CFAllocatorRef;
/* CFNull Reference */
pub static kCFNull: CFNullRef;
/* CFType Reference */
//fn CFCopyDescription
//fn CFCopyTypeIDDescription
//fn CFEqual
//fn CFGetAllocator
pub fn CFEqual(cf1: CFTypeRef, cf2: CFTypeRef) -> Boolean;
pub fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex;
pub fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID;
pub fn CFHash(cf: CFTypeRef) -> CFHashCode;
//fn CFMakeCollectable
pub fn CFRelease(cf: CFTypeRef);
pub fn CFRetain(cf: CFTypeRef) -> CFTypeRef;
pub fn CFShow(obj: CFTypeRef);
/* Base Utilities Reference */
// N.B. Some things missing here.
}

View File

@ -0,0 +1,31 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::c_void;
use base::CFTypeID;
use dictionary::CFDictionaryRef;
use string::CFStringRef;
#[repr(C)]
pub struct __CFBundle(c_void);
pub type CFBundleRef = *const __CFBundle;
extern {
/*
* CFBundle.h
*/
pub fn CFBundleGetBundleWithIdentifier(bundleID: CFStringRef) -> CFBundleRef;
pub fn CFBundleGetFunctionPointerForName(bundle: CFBundleRef, function_name: CFStringRef) -> *const c_void;
pub fn CFBundleGetMainBundle() -> CFBundleRef;
pub fn CFBundleGetInfoDictionary(bundle: CFBundleRef) -> CFDictionaryRef;
pub fn CFBundleGetTypeID() -> CFTypeID;
}

View File

@ -0,0 +1,22 @@
use libc::c_void;
use base::{CFAllocatorRef, CFTypeID, CFIndex};
#[repr(C)]
pub struct __CFData(c_void);
pub type CFDataRef = *const __CFData;
extern {
/*
* CFData.h
*/
pub fn CFDataCreate(allocator: CFAllocatorRef,
bytes: *const u8, length: CFIndex) -> CFDataRef;
//fn CFDataFind
pub fn CFDataGetBytePtr(theData: CFDataRef) -> *const u8;
pub fn CFDataGetLength(theData: CFDataRef) -> CFIndex;
pub fn CFDataGetTypeID() -> CFTypeID;
}

View File

@ -0,0 +1,15 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub type CFTimeInterval = f64;
pub type CFAbsoluteTime = CFTimeInterval;
extern {
pub fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime;
}

View File

@ -0,0 +1,79 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::{c_void};
use base::{CFAllocatorRef, CFIndex, CFTypeID, Boolean};
pub type CFDictionaryApplierFunction = extern "C" fn (key: *const c_void,
value: *const c_void,
context: *mut c_void);
pub type CFDictionaryCopyDescriptionCallBack = *const u8;
pub type CFDictionaryEqualCallBack = *const u8;
pub type CFDictionaryHashCallBack = *const u8;
pub type CFDictionaryReleaseCallBack = *const u8;
pub type CFDictionaryRetainCallBack = *const u8;
#[allow(dead_code)]
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CFDictionaryKeyCallBacks {
pub version: CFIndex,
pub retain: CFDictionaryRetainCallBack,
pub release: CFDictionaryReleaseCallBack,
pub copyDescription: CFDictionaryCopyDescriptionCallBack,
pub equal: CFDictionaryEqualCallBack,
pub hash: CFDictionaryHashCallBack
}
#[allow(dead_code)]
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CFDictionaryValueCallBacks {
pub version: CFIndex,
pub retain: CFDictionaryRetainCallBack,
pub release: CFDictionaryReleaseCallBack,
pub copyDescription: CFDictionaryCopyDescriptionCallBack,
pub equal: CFDictionaryEqualCallBack
}
#[repr(C)]
pub struct __CFDictionary(c_void);
pub type CFDictionaryRef = *const __CFDictionary;
pub type CFMutableDictionaryRef = *const __CFDictionary;
extern {
/*
* CFDictionary.h
*/
pub static kCFTypeDictionaryKeyCallBacks: CFDictionaryKeyCallBacks;
pub static kCFTypeDictionaryValueCallBacks: CFDictionaryValueCallBacks;
pub fn CFDictionaryContainsKey(theDict: CFDictionaryRef, key: *const c_void) -> Boolean;
pub fn CFDictionaryCreate(allocator: CFAllocatorRef, keys: *const *const c_void, values: *const *const c_void,
numValues: CFIndex, keyCallBacks: *const CFDictionaryKeyCallBacks,
valueCallBacks: *const CFDictionaryValueCallBacks)
-> CFDictionaryRef;
pub fn CFDictionaryGetCount(theDict: CFDictionaryRef) -> CFIndex;
pub fn CFDictionaryGetTypeID() -> CFTypeID;
pub fn CFDictionaryGetValueIfPresent(theDict: CFDictionaryRef, key: *const c_void, value: *mut *const c_void)
-> Boolean;
pub fn CFDictionaryApplyFunction(theDict: CFDictionaryRef,
applier: CFDictionaryApplierFunction,
context: *mut c_void);
pub fn CFDictionarySetValue(theDict: CFMutableDictionaryRef,
key: *const c_void,
value: *const c_void);
pub fn CFDictionaryGetKeysAndValues(theDict: CFDictionaryRef,
keys: *mut *const c_void,
values: *mut *const c_void);
}

View File

@ -0,0 +1,32 @@
// Copyright 2016 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::c_void;
use base::{CFTypeID, CFIndex};
use string::CFStringRef;
#[repr(C)]
pub struct __CFError(c_void);
pub type CFErrorRef = *mut __CFError;
extern "C" {
pub fn CFErrorGetTypeID() -> CFTypeID;
pub static kCFErrorDomainPOSIX: CFStringRef;
pub static kCFErrorDomainOSStatus: CFStringRef;
pub static kCFErrorDomainMach: CFStringRef;
pub static kCFErrorDomainCocoa: CFStringRef;
pub fn CFErrorGetDomain(err: CFErrorRef) -> CFStringRef;
pub fn CFErrorGetCode(err: CFErrorRef) -> CFIndex;
pub fn CFErrorCopyDescription(err: CFErrorRef) -> CFStringRef;
}

View File

@ -0,0 +1,26 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals, improper_ctypes)]
extern crate libc;
pub mod array;
pub mod base;
pub mod bundle;
pub mod data;
pub mod date;
pub mod dictionary;
pub mod error;
pub mod messageport;
pub mod number;
pub mod propertylist;
pub mod runloop;
pub mod set;
pub mod string;
pub mod url;

View File

@ -0,0 +1,79 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::c_void;
use base::{CFAllocatorRef, CFIndex, CFTypeID, Boolean};
use data::CFDataRef;
use date::CFTimeInterval;
use runloop::CFRunLoopSourceRef;
use string::CFStringRef;
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct CFMessagePortContext {
pub version: CFIndex,
pub info: *mut c_void,
pub retain: Option<unsafe extern fn(info: *const c_void) -> *const c_void>,
pub release: Option<unsafe extern fn(info: *const c_void)>,
pub copyDescription: Option<unsafe extern fn(info: *const c_void)
-> CFStringRef>,
}
pub type CFMessagePortCallBack = Option<
unsafe extern fn(local: CFMessagePortRef,
msgid: i32,
data: CFDataRef,
info: *mut c_void) -> CFDataRef>;
pub type CFMessagePortInvalidationCallBack = Option<
unsafe extern "C" fn(ms: CFMessagePortRef, info: *mut c_void)>;
#[repr(C)]
pub struct __CFMessagePort(c_void);
pub type CFMessagePortRef = *const __CFMessagePort;
extern {
/*
* CFMessagePort.h
*/
pub fn CFMessagePortGetTypeID() -> CFTypeID;
pub fn CFMessagePortCreateLocal(allocator: CFAllocatorRef,
name: CFStringRef,
callout: CFMessagePortCallBack,
context: *const CFMessagePortContext,
shouldFreeInfo: *mut Boolean)
-> CFMessagePortRef;
pub fn CFMessagePortCreateRemote(allocator: CFAllocatorRef,
name: CFStringRef) -> CFMessagePortRef;
pub fn CFMessagePortIsRemote(ms: CFMessagePortRef) -> Boolean;
pub fn CFMessagePortGetName(ms: CFMessagePortRef) -> CFStringRef;
pub fn CFMessagePortSetName(ms: CFMessagePortRef, newName: CFStringRef)
-> Boolean;
pub fn CFMessagePortGetContext(ms: CFMessagePortRef,
context: *mut CFMessagePortContext);
pub fn CFMessagePortInvalidate(ms: CFMessagePortRef);
pub fn CFMessagePortIsValid(ms: CFMessagePortRef) -> Boolean;
pub fn CFMessagePortGetInvalidationCallBack(ms: CFMessagePortRef)
-> CFMessagePortInvalidationCallBack;
pub fn CFMessagePortSetInvalidationCallBack(ms: CFMessagePortRef,
callout: CFMessagePortInvalidationCallBack);
pub fn CFMessagePortSendRequest(remote: CFMessagePortRef, msgid: i32,
data: CFDataRef,
sendTimeout: CFTimeInterval,
rcvTimeout: CFTimeInterval,
replyMode: CFStringRef,
returnData: *mut CFDataRef) -> i32;
pub fn CFMessagePortCreateRunLoopSource(allocator: CFAllocatorRef,
local: CFMessagePortRef,
order: CFIndex)
-> CFRunLoopSourceRef;
// CFMessagePortSetDispatchQueue
}

View File

@ -0,0 +1,59 @@
// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use libc::c_void;
use base::{CFAllocatorRef, CFTypeID};
#[repr(C)]
pub struct __CFBoolean(c_void);
pub type CFBooleanRef = *const __CFBoolean;
pub type CFNumberType = u32;
// members of enum CFNumberType
// static kCFNumberSInt8Type: CFNumberType = 1;
// static kCFNumberSInt16Type: CFNumberType = 2;
pub static kCFNumberSInt32Type: CFNumberType = 3;
pub static kCFNumberSInt64Type: CFNumberType = 4;
// static kCFNumberFloat32Type: CFNumberType = 5;
pub static kCFNumberFloat64Type: CFNumberType = 6;
// static kCFNumberCharType: CFNumberType = 7;
// static kCFNumberShortType: CFNumberType = 8;
// static kCFNumberIntType: CFNumberType = 9;
// static kCFNumberLongType: CFNumberType = 10;
// static kCFNumberLongLongType: CFNumberType = 11;
// static kCFNumberFloatType: CFNumberType = 12;
// static kCFNumberDoubleType: CFNumberType = 13;
// static kCFNumberCFIndexType: CFNumberType = 14;
// static kCFNumberNSIntegerType: CFNumberType = 15;
// static kCFNumberCGFloatType: CFNumberType = 16;
// static kCFNumberMaxType: CFNumberType = 16;
#[repr(C)]
pub struct __CFNumber;
pub type CFNumberRef = *const __CFNumber;
extern {
/*
* CFNumber.h
*/
pub static kCFBooleanTrue: CFBooleanRef;
pub static kCFBooleanFalse: CFBooleanRef;
pub fn CFBooleanGetTypeID() -> CFTypeID;
pub fn CFNumberCreate(allocator: CFAllocatorRef, theType: CFNumberType, valuePtr: *const c_void)
-> CFNumberRef;
//fn CFNumberGetByteSize
pub fn CFNumberGetValue(number: CFNumberRef, theType: CFNumberType, valuePtr: *mut c_void) -> bool;
//fn CFNumberCompare
pub fn CFNumberGetTypeID() -> CFTypeID;
}

Some files were not shown because too many files have changed in this diff Show More