DXR will be turned off on Tuesday, December 29th. It will redirect to Searchfox.
See the announcement on Discourse.

DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
#![deny(missing_docs)]

//! `bincode` is a crate for encoding and decoding using a tiny binary
//! serialization strategy.
//!
//! There are simple functions for encoding to `Vec<u8>` and decoding from
//! `&[u8]`, but the meat of the library is the `serialize_into` and `deserialize_from`
//! functions which respectively allow encoding into any `std::io::Write`
//! or decode from any `std::io::Read`.
//!
//! ## Modules
//! Until "default type parameters" lands, we have an extra module called `endian_choice`
//! that duplicates all of the core bincode functionality but with the option to choose
//! which endianness the integers are encoded using.
//!
//! The default endianness is little.
//!
//! ### Using Basic Functions
//!
//! ```rust
//! extern crate bincode;
//! use bincode::{serialize, deserialize, Bounded};
//! fn main() {
//!     // The object that we will serialize.
//!     let target = Some("hello world".to_string());
//!     // The maximum size of the encoded message.
//!     let limit = Bounded(20);
//!
//!     let encoded: Vec<u8>        = serialize(&target, limit).unwrap();
//!     let decoded: Option<String> = deserialize(&encoded[..]).unwrap();
//!     assert_eq!(target, decoded);
//! }
//! ```

#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

extern crate byteorder;
extern crate serde as serde_crate;

mod ser;
mod de;
pub mod internal;

pub mod read_types {
    //! The types that the deserializer uses for optimizations
    pub use ::de::read::{SliceReader, BincodeRead, IoReader};
}

use std::io::{Read, Write};

pub use internal::{ErrorKind, Error, Result, serialized_size, serialized_size_bounded};

/// A Deserializer that uses LittleEndian byteorder
pub type Deserializer<W, S> = internal::Deserializer<W, S, byteorder::LittleEndian>;
/// A Serializer that uses LittleEndian byteorder
pub type Serializer<W> = internal::Serializer<W, byteorder::LittleEndian>;

/// Deserializes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn deserialize<'a, T>(bytes: &'a [u8]) -> internal::Result<T>
    where T: serde_crate::de::Deserialize<'a>,
{
    internal::deserialize::<_, byteorder::LittleEndian>(bytes)
}

/// Deserializes an object directly from a `Buffer`ed Reader.
///
/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `Error`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn deserialize_from<R: ?Sized, T, S>(reader: &mut R, size_limit: S) -> internal::Result<T>
    where R: Read, T: serde_crate::de::DeserializeOwned, S: SizeLimit
{
    internal::deserialize_from::<_, _, _, byteorder::LittleEndian>(reader, size_limit)
}

/// Serializes an object directly into a `Writer`.
///
/// If the serialization would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `Error` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// serializing.
pub fn serialize_into<W: ?Sized, T: ?Sized, S>(writer: &mut W, value: &T, size_limit: S) -> internal::Result<()>
    where W: Write, T: serde_crate::Serialize, S: SizeLimit
{
    internal::serialize_into::<_, _, _, byteorder::LittleEndian>(writer, value, size_limit)
}

/// Serializes a serializable object into a `Vec` of bytes.
///
/// If the serialization would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn serialize<T: ?Sized, S>(value: &T, size_limit: S) -> internal::Result<Vec<u8>>
    where T: serde_crate::Serialize, S: SizeLimit
{
    internal::serialize::<_, _, byteorder::LittleEndian>(value, size_limit)
}

/// A limit on the amount of bytes that can be read or written.
///
/// Size limits are an incredibly important part of both encoding and decoding.
///
/// In order to prevent DOS attacks on a decoder, it is important to limit the
/// amount of bytes that a single encoded message can be; otherwise, if you
/// are decoding bytes right off of a TCP stream for example, it would be
/// possible for an attacker to flood your server with a 3TB vec, causing the
/// decoder to run out of memory and crash your application!
/// Because of this, you can provide a maximum-number-of-bytes that can be read
/// during decoding, and the decoder will explicitly fail if it has to read
/// any more than that.
///
/// On the other side, you want to make sure that you aren't encoding a message
/// that is larger than your decoder expects.  By supplying a size limit to an
/// encoding function, the encoder will verify that the structure can be encoded
/// within that limit.  This verification occurs before any bytes are written to
/// the Writer, so recovering from an error is easy.
pub trait SizeLimit: private::Sealed {
    /// Tells the SizeLimit that a certain number of bytes has been
    /// read or written.  Returns Err if the limit has been exceeded.
    fn add(&mut self, n: u64) -> Result<()>;
    /// Returns the hard limit (if one exists)
    fn limit(&self) -> Option<u64>;
}

/// A SizeLimit that restricts serialized or deserialized messages from
/// exceeding a certain byte length.
#[derive(Copy, Clone)]
pub struct Bounded(pub u64);

/// A SizeLimit without a limit!
/// Use this if you don't care about the size of encoded or decoded messages.
#[derive(Copy, Clone)]
pub struct Infinite;

struct CountSize {
    total: u64,
    limit: Option<u64>,
}

impl SizeLimit for Bounded {
    #[inline(always)]
    fn add(&mut self, n: u64) -> Result<()> {
        if self.0 >= n {
            self.0 -= n;
            Ok(())
        } else {
            Err(Box::new(ErrorKind::SizeLimit))
        }
    }

    #[inline(always)]
    fn limit(&self) -> Option<u64> { Some(self.0) }
}

impl SizeLimit for Infinite {
    #[inline(always)]
    fn add(&mut self, _: u64) -> Result<()> { Ok (()) }

    #[inline(always)]
    fn limit(&self) -> Option<u64> { None }
}

mod private {
    pub trait Sealed {}

    impl<'a> Sealed for super::de::read::SliceReader<'a> {}
    impl<R> Sealed for super::de::read::IoReader<R> {}
    impl Sealed for super::Infinite {}
    impl Sealed for super::Bounded {}
    impl Sealed for super::CountSize {}
}