varint-0.9.0/.gitignore000064400000000000000000000000271260641373500132070ustar0000000000000000target/ Cargo.lock varint-0.9.0/.travis.yml000064400000000000000000000026031260717773000133350ustar0000000000000000language: rust sudo: false addons: apt: packages: - libcurl4-openssl-dev - libelf-dev - libdw-dev rust: - nightly - beta - stable before_script: - | pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: - | travis-cargo build -- --features io-operations && travis-cargo test -- --features io-operations && travis-cargo bench -- --features io-operations && travis-cargo --only stable doc -- --features io-operations after_success: - travis-cargo --only stable doc-upload - travis-cargo coveralls --no-sudo -- --features io-operations #You cheeky bugger env: global: - matrix: - TRAVIS_CARGO_NIGHTLY_FEATURE="nightly" - secure: On2QkVjG28RaQ1hcWMwUCVfTd2H7V8X+61E8h/wYXmpD9JAwGsS4SHbYC3SZMi7B5+yBXENtiXsWXRVfCP4fjTf0j/fMJIjtU4yE1WE+XRR7t3qBatD5KVZ5bR6g6RFsDJhsQOxRTQD31OCK0lGPbBA4uESaWx+9VtyVSH64jP0KCyycTSIM032cTUMqs7gSuMvhoHgNxSFjz5h9EkrxmiwBM0xb07sWskLp5v0+9LWaP8cgOWXMm67KnI8PQVajRi/8HXXm8vZrkTFx68CDm1YbLQQY0RDWyz79JW6rvV/GPpn6pJhhMLOZN9dj+UeFVY92ayDeHeFVY5ttnblinz3VBQLvBwoTj5DMvdwPyKRiOgEGkL6PTn6KzXUcHgOjrxsF5+jK2L+G3HajQ/8fZpCU+ujFxm/Wr6UgFeBV+bFIlPnDPtF7drhj89g/EfxN8PhOyPVoua1kgE2Tqq4YP5/txNkTeutVKqk5L31jozEhnCmDuuiHOKYVL0FW8RItuIXk9qOPuYLKvTTRmOn3IZg6+QhA4WAeIF0JPvjCVuWtXWiZWH6RE9z3NWB+tqXn/HnNluFaajw6i2NfepssaoySNefCQruyMH76sr5jnI/jg6sN+ftewOxfhgz583mrwIHPznMN4achc3owcfxctGiQmj7p1B977+8Mi8tjqGs= varint-0.9.0/Cargo.toml000064400000000000000000000017741261216037700131570ustar0000000000000000# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] name = "varint" version = "0.9.0" authors = ["Cruz Julian Bishop "] description = "A Rust implementation of Google Protobuf's Variable-Length Integers" documentation = "http://techern.github.io/Varint-rs" readme = "README.md" keywords = [ "Protobuf", "Google", "Varint", ] license = "MIT" repository = "https://github.com/Techern/Varint-rs" [dependencies.bit_utils] version = "0.1.0" [dependencies.io_operations] version = "0.2.0" optional = true [features] io-operations = ["io_operations"] nightly = [] varint-0.9.0/Cargo.toml.orig000064400000000000000000000010371261216037700141060ustar0000000000000000[package] name = "varint" version = "0.9.0" authors = ["Cruz Julian Bishop "] description = "A Rust implementation of Google Protobuf's Variable-Length Integers" repository = "https://github.com/Techern/Varint-rs" documentation = "http://techern.github.io/Varint-rs" readme = "README.md" keywords = ["Protobuf", "Google", "Varint"] license = "MIT" [dependencies] bit_utils = "0.1.0" io_operations = { version = "0.2.0", optional = true } [features] nightly = [] io-operations = [ "io_operations" ] varint-0.9.0/LICENSE000064400000000000000000000021111260641373500122200ustar0000000000000000The MIT License (MIT) Copyright (c) 2015 Techern 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. varint-0.9.0/README.md000064400000000000000000000035621261216025200124730ustar0000000000000000# Varint-rs [\[API Documentation\]](http://techern.github.io/Varint-rs) ##Variable-length integer implementation in Rust [![Build Status](https://travis-ci.org/Techern/Varint-rs.svg?branch=master)](https://travis-ci.org/Techern/Varint-rs) [![Crates.io](https://img.shields.io/crates/v/varint.svg)](https://crates.io/crates/varint) [![Coverage Status](https://coveralls.io/repos/Techern/Varint-rs/badge.svg?branch=master&service=github)](https://coveralls.io/github/Techern/Varint-rs?branch=master) ###Notes for 0.9 * Reading and writing 64-bit Varints is currently unsupported, but will be added in 1.0 after testing current functionality * If you're using the io-operations feature for IoOperations 0.2 integration, please note that it will be refactored in the next release. * Real-world tests are still in progress. Theoretically, however, everything **should** work. ###List of feature flags * ```io-operations``` - Preliminary integration with the IO-Operations library ###Examples ```rust extern crate varint; use varint::{ VarintRead, VarintWrite }; //Using IO-Operations? Replace with VarintReader and VarintWriter, the functions are the same use std::io::Cursor; //Currently supports Cursor> and TcpStream, but should be okay to implement in any Read/Write trait let mut vector = Cursor::new(vec![0u8; 0]); assert!(vector.write_signed_varint_32(2346784).is_ok()); //You can check this however you like. Try! could work. I'll check it out in Netherrack and update this by 1.0 //Do whatever you need to do. vector.set_position(0); //If you're using a TcpStream, you'd probably switch sides and into a different codebase. This is just a quick example before I fall asleep :) assert_eq!(2346784, vector.read_signed_varint_32().unwrap()); //You could also use try! here. Again, I'll test it in a real world project and update later ``` varint-0.9.0/src/iooperations.rs000064400000000000000000000120561261216010400150560ustar0000000000000000//! Integration with the IoOperations library use bit_utils::BitInformation; use io_operations::reader::Reader; use io_operations::writer::Writer; use std::io::Error; /// Extends the IoOperations Reader trait to provide functions to read (currently only 32-bit) Variable-Length Integers pub trait VarintReader : Reader { /// Reads a signed 32-bit Varint from this VarintReader fn read_signed_varint_32(&mut self) -> Result { use zigzag::ZigZag; match self.read_unsigned_varint_32() { Ok(value) => { return Ok(value.zigzag()); } Err(error) => { return Err(error); } } } /// Reads an unsigned 32-bit Varint from this VarintReader fn read_unsigned_varint_32(&mut self) -> Result { // The number of bits to shift by. <<0, <<7, <<14, etc let mut shift_amount: u32 = 0; // The decoded value let mut decoded_value: u32 = 0; loop { match self.read_unsigned_byte() { Err(error) => { return Err(error); } Ok(byte_value) => { decoded_value |= ((byte_value & 0b01111111) as u32) << shift_amount; // See if we're supposed to keep reading if byte_value.has_most_signifigant_bit() { shift_amount += 7; } else { return Ok(decoded_value); } } } } } } /// Extends the IoOperations Writer to provide functions for writing (currently only 32-bit) variable-length integers pub trait VarintWriter : Writer { /// Writes a signed varint 32 to this VarintWriter fn write_signed_varint_32(&mut self, value: i32) -> Result<(), Error> { use zigzag::ZigZag; self.write_unsigned_varint_32(value.zigzag()) } /// Writes an unsigned 32-bit Varint to this VarintWriter fn write_unsigned_varint_32(&mut self, value: u32) -> Result<(), Error> { let mut _value: u32 = value; if value == 0 { return self.write_unsigned_byte(0) } else { while _value >= 0b10000000 { let next_byte: u8 = ((_value & 0b01111111) as u8) | 0b10000000; _value = _value >> 7; let temp = self.write_unsigned_byte(next_byte); if temp.is_err() { return temp; } } return self.write_unsigned_byte((_value & 0b01111111) as u8); } } } impl VarintReader for ::std::io::Cursor> { } impl VarintReader for ::std::net::TcpStream { } impl VarintWriter for ::std::io::Cursor> { } impl VarintWriter for ::std::net::TcpStream { } #[cfg(test)] mod test { use super::{ VarintReader, VarintWriter }; use std::io::Cursor; #[test] fn test_read_write_unsigned_varint_32() { let mut vector = Cursor::new(vec![0u8; 0]); assert!(vector.write_unsigned_varint_32(15).is_ok()); assert!(vector.write_unsigned_varint_32(0).is_ok()); assert!(vector.write_unsigned_varint_32(2111111111).is_ok()); assert!(vector.write_unsigned_varint_32(3463465).is_ok()); vector.set_position(0); assert_eq!(15, vector.read_unsigned_varint_32().unwrap()); assert_eq!(0, vector.read_unsigned_varint_32().unwrap()); assert_eq!(2111111111, vector.read_unsigned_varint_32().unwrap()); assert_eq!(3463465, vector.read_unsigned_varint_32().unwrap()); } #[test] fn test_read_write_signed_varint_32() { let mut vector = Cursor::new(vec![0u8; 0]); assert!(vector.write_signed_varint_32(-4).is_ok()); assert!(vector.write_signed_varint_32(0).is_ok()); assert!(vector.write_signed_varint_32(2111111111).is_ok()); assert!(vector.write_signed_varint_32(-2111111111).is_ok()); assert!(vector.write_signed_varint_32(-3463465).is_ok()); vector.set_position(0); assert_eq!(-4, vector.read_signed_varint_32().unwrap()); assert_eq!(-0, vector.read_signed_varint_32().unwrap()); assert_eq!(2111111111, vector.read_signed_varint_32().unwrap()); assert_eq!(-2111111111, vector.read_signed_varint_32().unwrap()); assert_eq!(-3463465, vector.read_signed_varint_32().unwrap()); } #[test] fn test_read_write_lots_of_unsigned_varint_32() { let mut vector = Cursor::new(vec![0u8; 0]); let mut index = 0; while index < 123456 { index += 1; assert!(vector.write_unsigned_varint_32(index).is_ok()); } vector.set_position(0); index = 0; while index < 123456 { index += 1; assert_eq!(index, vector.read_unsigned_varint_32().unwrap()); } } } varint-0.9.0/src/lib.rs000064400000000000000000000014351261215430700131200ustar0000000000000000//! An implementation of Google Protobuf's Variable-Length Integers #![cfg_attr(feature = "nightly", feature(test))] extern crate bit_utils; mod zigzag; pub use zigzag::ZigZag; mod rawio; pub use rawio::VarintRead as VarintRead; pub use rawio::VarintWrite as VarintWrite; #[cfg(feature = "io-operations")] extern crate io_operations; #[cfg(feature = "io-operations")] mod iooperations; #[cfg(feature = "io-operations")] pub use iooperations::VarintReader as VarintReader; #[cfg(feature = "io-operations")] pub use iooperations::VarintWriter as VarintWriter; /// The maximum number of bytes used by a 32-bit Varint pub const VARINT_32_MAX_BYTES: usize = 5; /// The maximum number of bytes used by a 32-bit Varint pub const VARINT_64_MAX_BYTES: usize = 10; varint-0.9.0/src/rawio.rs000064400000000000000000000132611261215545000134730ustar0000000000000000//! Integration with the IoOperations library use bit_utils::BitInformation; use std::io::{ Error, Read, Write, ErrorKind }; /// Extends the I/O Read trait to provide functions to read (currently only 32-bit) Variable-Length Integers pub trait VarintRead : Read { /// Reads a signed 32-bit Varint from this VarintRead fn read_signed_varint_32(&mut self) -> Result { use zigzag::ZigZag; match self.read_unsigned_varint_32() { Ok(value) => { return Ok(value.zigzag()); } Err(error) => { return Err(error); } } } /// Reads an unsigned 32-bit Varint from this VarintReader fn read_unsigned_varint_32(&mut self) -> Result { // The number of bits to shift by. <<0, <<7, <<14, etc let mut shift_amount: u32 = 0; // The decoded value let mut decoded_value: u32 = 0; let mut raw_buffer = vec![0u8; 1]; let mut next_byte: u8 = 0; loop { match self.read(&mut raw_buffer) { Ok(count) => { if count == 1 { next_byte = raw_buffer[0]; } else { return Err(Error::new(ErrorKind::Other, "Could not read one byte (end of stream?)")); } }, Err(error) => { return Err(error); } } decoded_value |= ((next_byte & 0b01111111) as u32) << shift_amount; // See if we're supposed to keep reading if next_byte.has_most_signifigant_bit() { shift_amount += 7; } else { return Ok(decoded_value); } } } } /// Extends the I/O Write trait to provide functions for writing (currently only 32-bit) variable-length integers pub trait VarintWrite : Write { /// Writes a signed varint 32 to this VarintWrite fn write_signed_varint_32(&mut self, value: i32) -> Result<(), Error> { use zigzag::ZigZag; self.write_unsigned_varint_32(value.zigzag()) } /// Writes an unsigned 32-bit Varint to this VarintWrite fn write_unsigned_varint_32(&mut self, value: u32) -> Result<(), Error> { let mut _value: u32 = value; if value == 0 { let raw_buffer = vec![0]; // Reassign to a buffer of raw u8s let raw_buffer: &[u8] = &raw_buffer[..]; return self.write_all(raw_buffer); } else { while _value >= 0b10000000 { let next_byte: u8 = ((_value & 0b01111111) as u8) | 0b10000000; _value = _value >> 7; let raw_buffer = vec![next_byte]; // Reassign to a buffer of raw u8s let raw_buffer: &[u8] = &raw_buffer[..]; let temp = self.write_all(raw_buffer); if temp.is_err() { return temp; } } let raw_buffer = vec![(_value & 0b01111111) as u8]; // Reassign to a buffer of raw u8s let raw_buffer: &[u8] = &raw_buffer[..]; return self.write_all(raw_buffer); } } } impl VarintRead for ::std::io::Cursor> { } impl VarintRead for ::std::net::TcpStream { } impl VarintWrite for ::std::io::Cursor> { } impl VarintWrite for ::std::net::TcpStream { } #[cfg(test)] mod test { use super::{ VarintRead, VarintWrite }; use std::io::Cursor; #[test] fn test_read_write_unsigned_varint_32() { let mut vector = Cursor::new(vec![0u8; 0]); assert!(vector.write_unsigned_varint_32(15).is_ok()); assert!(vector.write_unsigned_varint_32(0).is_ok()); assert!(vector.write_unsigned_varint_32(2111111111).is_ok()); assert!(vector.write_unsigned_varint_32(3463465).is_ok()); vector.set_position(0); assert_eq!(15, vector.read_unsigned_varint_32().unwrap()); assert_eq!(0, vector.read_unsigned_varint_32().unwrap()); assert_eq!(2111111111, vector.read_unsigned_varint_32().unwrap()); assert_eq!(3463465, vector.read_unsigned_varint_32().unwrap()); } #[test] fn test_read_write_signed_varint_32() { let mut vector = Cursor::new(vec![0u8; 0]); assert!(vector.write_signed_varint_32(-4).is_ok()); assert!(vector.write_signed_varint_32(0).is_ok()); assert!(vector.write_signed_varint_32(2111111111).is_ok()); assert!(vector.write_signed_varint_32(-2111111111).is_ok()); assert!(vector.write_signed_varint_32(-3463465).is_ok()); vector.set_position(0); assert_eq!(-4, vector.read_signed_varint_32().unwrap()); assert_eq!(-0, vector.read_signed_varint_32().unwrap()); assert_eq!(2111111111, vector.read_signed_varint_32().unwrap()); assert_eq!(-2111111111, vector.read_signed_varint_32().unwrap()); assert_eq!(-3463465, vector.read_signed_varint_32().unwrap()); } #[test] fn test_read_write_lots_of_unsigned_varint_32() { let mut vector = Cursor::new(vec![0u8; 0]); let mut index = 0; while index < 123456 { index += 1; assert!(vector.write_unsigned_varint_32(index).is_ok()); } vector.set_position(0); index = 0; while index < 123456 { index += 1; assert_eq!(index, vector.read_unsigned_varint_32().unwrap()); } } } varint-0.9.0/src/zigzag.rs000064400000000000000000000111701260641373500136500ustar0000000000000000//! Zig-zag encoding of integral values /// A trait for enabling zig-zag encoding of various values pub trait ZigZag { /// Encodes this ZigZag-enabled type into the type specified by implementation fn zigzag(&self) -> T; } impl ZigZag for i8 { /// Encodes this i8 as a zigzagged u8 fn zigzag(&self) -> u8 { ((self << 1) ^ (self >> 7)) as u8 } } impl ZigZag for u8 { /// Encodes this u8 as a zigzagged i8 fn zigzag(&self) -> i8 { ((self >> 1) as i8) ^ (-((self & 1) as i8)) } } impl ZigZag for i16 { /// Encodes this i16 as a zigzagged u16 fn zigzag(&self) -> u16 { ((self << 1) ^ (self >> 15)) as u16 } } impl ZigZag for u16 { /// Encodes this u16 as a zigzagged i16 fn zigzag(&self) -> i16 { ((self >> 1) as i16) ^ (-((self & 1) as i16)) } } impl ZigZag for i32 { /// Encodes this i32 as a zigzagged u32 fn zigzag(&self) -> u32 { ((self << 1) ^ (self >> 31)) as u32 } } impl ZigZag for u32 { /// Encodes this u32 as a zigzagged i32 fn zigzag(&self) -> i32 { ((self >> 1) as i32) ^ (-((self & 1) as i32)) } } impl ZigZag for i64 { /// Encodes this i64 as a zigzagged u64 fn zigzag(&self) -> u64 { ((self << 1) ^ (self >> 63)) as u64 } } impl ZigZag for u64 { /// Encodes this u64 as a zigzagged i64 fn zigzag(&self) -> i64 { ((self >> 1) as i64) ^ (-((self & 1) as i64)) } } #[cfg(test)] mod tests { use super::ZigZag; #[test] fn test_u8_i8_zigzag() { let mut unsigned: u8 = 0u8; assert_eq!(0i8, unsigned.zigzag()); unsigned = 1; assert_eq!(-1i8, unsigned.zigzag()); unsigned = 2; assert_eq!(1i8, unsigned.zigzag()); let mut signed: i8 = 0i8; assert_eq!(0u8, signed.zigzag()); signed = -1i8; assert_eq!(1u8, signed.zigzag()); signed = 1i8; assert_eq!(2u8, signed.zigzag()); } #[test] fn test_u16_i16_zigzag() { let mut unsigned: u16 = 0u16; assert_eq!(0i16, unsigned.zigzag()); unsigned = 1; assert_eq!(-1i16, unsigned.zigzag()); unsigned = 2; assert_eq!(1i16, unsigned.zigzag()); let mut signed: i16 = 0i16; assert_eq!(0u16, signed.zigzag()); signed = -1i16; assert_eq!(1u16, signed.zigzag()); signed = 1i16; assert_eq!(2u16, signed.zigzag()); } #[test] fn test_u32_i32_zigzag() { let mut unsigned: u32 = 0u32; assert_eq!(0i32, unsigned.zigzag()); unsigned = 1; assert_eq!(-1i32, unsigned.zigzag()); unsigned = 2; assert_eq!(1i32, unsigned.zigzag()); let mut signed: i32 = 0i32; assert_eq!(0u32, signed.zigzag()); signed = -1i32; assert_eq!(1u32, signed.zigzag()); signed = 1i32; assert_eq!(2u32, signed.zigzag()); } #[test] fn test_u64_i64_zigzag() { let mut unsigned: u64 = 0u64; assert_eq!(0i64, unsigned.zigzag()); unsigned = 1; assert_eq!(-1i64, unsigned.zigzag()); unsigned = 2; assert_eq!(1i64, unsigned.zigzag()); let mut signed: i64 = 0i64; assert_eq!(0u64, signed.zigzag()); signed = -1i64; assert_eq!(1u64, signed.zigzag()); signed = 1i64; assert_eq!(2u64, signed.zigzag()); } } #[cfg(feature = "nightly")] #[cfg(test)] mod benchmarks { use super::ZigZag; extern crate test; use self::test::Bencher; #[bench] fn bench_i8_zigzag(b: &mut Bencher) { b.iter(|| (-15i8).zigzag()) } #[bench] fn bench_u8_zigzag(b: &mut Bencher) { b.iter(|| 224u8.zigzag()) } #[bench] fn bench_i16_zigzag(b: &mut Bencher) { b.iter(|| 27424i16.zigzag()) } #[bench] fn bench_u16_zigzag(b: &mut Bencher) { b.iter(|| 22447u16.zigzag()) } #[bench] fn bench_i32_zigzag(b: &mut Bencher) { b.iter(|| 22472745i32.zigzag()) } #[bench] fn bench_u32_zigzag(b: &mut Bencher) { b.iter(|| 22376257u32.zigzag()) } #[bench] fn bench_i64_zigzag(b: &mut Bencher) { b.iter(|| 234678386538365i64.zigzag()) } #[bench] fn bench_u64_zigzag(b: &mut Bencher) { b.iter(|| 254724572473468u64.zigzag()) } } varint-0.9.0/Cargo.toml000064400000000000000000000017741261216037700131570ustar0000000000000000# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] name = "varint" version = "0.9.0" authors = ["Cruz Julian Bishop "] description = "A Rust implementation of Google Protobuf's Variable-Length Integers" documentation = "http://techern.github.io/Varint-rs" readme = "README.md" keywords = [ "Protobuf", "Google", "Varint", ] license = "MIT" repository = "https://github.com/Techern/Varint-rs" [dependencies.bit_utils] version = "0.1.0" [dependencies.io_operations] version = "0.2.0" optional = true [features] io-operations = ["io_operations"] nightly = [] varint-0.9.0/Cargo.toml.orig000064400000000000000000000010371261216037700141060ustar0000000000000000[package] name = "varint" version = "0.9.0" authors = ["Cruz Julian Bishop "] description = "A Rust implementation of Google Protobuf's Variable-Length Integers" repository = "https://github.com/Techern/Varint-rs" documentation = "http://techern.github.io/Varint-rs" readme = "README.md" keywords = ["Protobuf", "Google", "Varint"] license = "MIT" [dependencies] bit_utils = "0.1.0" io_operations = { version = "0.2.0", optional = true } [features] nightly = [] io-operations = [ "io_operations" ]