diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/rust/podio/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/podio/Cargo.toml | 12 | ||||
-rw-r--r-- | third_party/rust/podio/LICENSE-APACHE | 202 | ||||
-rw-r--r-- | third_party/rust/podio/LICENSE-MIT | 19 | ||||
-rw-r--r-- | third_party/rust/podio/README.md | 56 | ||||
-rw-r--r-- | third_party/rust/podio/appveyor.yml | 49 | ||||
-rw-r--r-- | third_party/rust/podio/benches/benchmark.rs | 49 | ||||
-rw-r--r-- | third_party/rust/podio/script/doc-upload.cfg | 3 | ||||
-rw-r--r-- | third_party/rust/podio/src/lib.rs | 336 | ||||
-rw-r--r-- | third_party/rust/podio/tests/bytes.rs | 139 | ||||
-rw-r--r-- | third_party/rust/podio/tests/io.rs | 57 |
11 files changed, 923 insertions, 0 deletions
diff --git a/third_party/rust/podio/.cargo-checksum.json b/third_party/rust/podio/.cargo-checksum.json new file mode 100644 index 0000000000..c9962e7252 --- /dev/null +++ b/third_party/rust/podio/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"4dec40bd969f50f658bb49ffd1d311ecf9ab1424aeb45a15980d1461d560eb35","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"892ad0db8a971b86db947bae64542aa67d91cfae768b3ed3ea281c54844a4ae9","README.md":"4b66e3517754d9aabe44c17b224f1d1e72a6fb50507d49536e6825a3e4d0b347","appveyor.yml":"d89e888e666ae00cf5424db695254fb134829562156ca68c736ccc9b8ba36af2","benches/benchmark.rs":"0adade342f2046c8d6f669097209f23b4d8a35c6b5dc2c3687addf2f4444aa40","script/doc-upload.cfg":"273e9501d95820583705e9f4c4f84afefba4fd227223fc3d165dfb1aba91c5d1","src/lib.rs":"4e85226ca3aa902f1623bdc4ea9df4f9ec1f807ca61bc978f0a67d78f5d6023d","tests/bytes.rs":"1cb1979745f35086a785df207f3b0f660cf6720e123c3e0042fb924d5795aa37","tests/io.rs":"19e4699082d0a0432dfa23bda2a54ed426d23bf7f07a579ba4305a1926d952ec"},"package":"e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"}
\ No newline at end of file diff --git a/third_party/rust/podio/Cargo.toml b/third_party/rust/podio/Cargo.toml new file mode 100644 index 0000000000..e122cb7801 --- /dev/null +++ b/third_party/rust/podio/Cargo.toml @@ -0,0 +1,12 @@ +[package] + +name = "podio" +version = "0.1.5" +authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>"] +license = "MIT OR Apache-2.0" +keywords = ["byte", "byteorder", "io"] +repository = "https://github.com/mvdnes/podio.git" +documentation = "http://mvdnes.github.io/rust-docs/podio/podio/index.html" +description = """ +Additional trait for Read and Write to read and write Plain Old Data +""" diff --git a/third_party/rust/podio/LICENSE-APACHE b/third_party/rust/podio/LICENSE-APACHE new file mode 100644 index 0000000000..8f71f43fee --- /dev/null +++ b/third_party/rust/podio/LICENSE-APACHE @@ -0,0 +1,202 @@ + 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. + diff --git a/third_party/rust/podio/LICENSE-MIT b/third_party/rust/podio/LICENSE-MIT new file mode 100644 index 0000000000..964f1fe2f8 --- /dev/null +++ b/third_party/rust/podio/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright (c) 2015 The podio 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. diff --git a/third_party/rust/podio/README.md b/third_party/rust/podio/README.md new file mode 100644 index 0000000000..47c7a570ca --- /dev/null +++ b/third_party/rust/podio/README.md @@ -0,0 +1,56 @@ +podio +===== + +[![Build Status](https://travis-ci.org/mvdnes/podio.svg?branch=master)](https://travis-ci.org/mvdnes/podio) +[![Build status](https://ci.appveyor.com/api/projects/status/hjc3icfjob7mocc9/branch/master?svg=true)](https://ci.appveyor.com/project/mvdnes/podio/branch/master) +[![Crates.io version](https://img.shields.io/crates/v/podio.svg)](https://crates.io/crates/podio) + +[Documentation](http://mvdnes.github.io/rust-docs/podio/podio/index.html) + +Implementation for reading and writing POD (plain old data) values in Rust. The name stands for POD I/O. + +Keywords: byte, be, le, big-endian, little-endian + +Usage +----- + +Include the following code: + +```toml +[dependencies] +podio = "0.1" +``` + +Example +------- + +```rust +extern crate podio; + +use podio::{ReadPodExt, BigEndian}; + +fn main() { + let slice: &[u8] = &[0x10, 0x20, 0x30, 0x40]; + let mut reader = std::io::Cursor::new(slice); + + let value = reader.read_u32::<BigEndian>().unwrap(); + + assert_eq!(value, 0x10203040); +} +``` + +## License + +Licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally +submitted for inclusion in the work by you, as defined in the Apache-2.0 +license, shall be dual licensed as above, without any additional terms or +conditions. diff --git a/third_party/rust/podio/appveyor.yml b/third_party/rust/podio/appveyor.yml new file mode 100644 index 0000000000..7399b81123 --- /dev/null +++ b/third_party/rust/podio/appveyor.yml @@ -0,0 +1,49 @@ +environment: + matrix: + - RUST_INSTALL_TOOLCHAIN: gnu + RUST_CHANNEL: stable + - RUST_INSTALL_TOOLCHAIN: msvc + RUST_CHANNEL: nightly + +matrix: + allow_failures: + - RUST_CHANNEL: nightly + +platform: + - x86 + - x64 + +install: + - ps: Start-FileDownload "http://static.rust-lang.org/dist/channel-rust-${env:RUST_CHANNEL}" + - ps: | + if ($env:PLATFORM -eq "x86") { + $env:RUST_INSTALLER = Select-String "i686-pc-windows-${env:RUST_INSTALL_TOOLCHAIN}.*exe" "channel-rust-${env:RUST_CHANNEL}" | select -exp line + } else { + $env:RUST_INSTALLER = Select-String "x86_64-pc-windows-${env:RUST_INSTALL_TOOLCHAIN}.*exe" "channel-rust-${env:RUST_CHANNEL}" | select -exp line + } + - ps: Start-FileDownload "http://static.rust-lang.org/dist/${env:RUST_INSTALLER}" + - '%RUST_INSTALLER% /VERYSILENT /NORESTART /DIR="C:\Rust"' + - ps: $env:path = "C:\Rust\bin;" + $env:path + - ps: | + if ($env:RUST_INSTALL_TOOLCHAIN -eq "gnu" -And $env:PLATFORM -eq "x64") { + Start-FileDownload "http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/5.1.0/threads-win32/seh/x86_64-5.1.0-release-win32-seh-rt_v4-rev0.7z/download" -FileName mingw64.7z + 7z x -oC:\ mingw64.7z > $null + $env:path = "C:\mingw64\bin;" + $env:path + gcc --version + } + elseif ($env:RUST_INSTALL_TOOLCHAIN -eq "gnu") { + $env:path = "C:\mingw\bin;" + $env:path + gcc --version + } + - ps: | + if ($env:PLATFORM -eq "x64") { $env:vcargs = "amd64" } + else { $env:vcargs = "x86" } + - call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" %vcargs% + - rustc --version --verbose + - cargo --version + +build: false + +test_script: + - cargo build + - cargo test diff --git a/third_party/rust/podio/benches/benchmark.rs b/third_party/rust/podio/benches/benchmark.rs new file mode 100644 index 0000000000..81614e75ec --- /dev/null +++ b/third_party/rust/podio/benches/benchmark.rs @@ -0,0 +1,49 @@ +// bench.rs +#![feature(test)] + +extern crate podio; +extern crate test; + +use test::Bencher; +use podio::{Endianness, BigEndian, LittleEndian, WritePodExt, ReadPodExt}; + +// bench: find the `BENCH_SIZE` first terms of the fibonacci sequence +const BENCH_SIZE: usize = 2000; + +#[bench] +fn write_u64_be(b: &mut Bencher) { + write_u64::<BigEndian>(b); +} + +#[bench] +fn write_u64_le(b: &mut Bencher) { + write_u64::<LittleEndian>(b); +} + +fn write_u64<T: Endianness>(b: &mut Bencher) { + b.iter(|| { + let mut writer : &mut[u8] = &mut [0; BENCH_SIZE * 8]; + for _ in 0..BENCH_SIZE { + writer.write_u64::<T>(0x012345678u64).unwrap(); + } + }) +} + +#[bench] +fn read_u64_be(b: &mut Bencher) { + read_u64::<BigEndian>(b); +} + +#[bench] +fn read_u64_le(b: &mut Bencher) { + read_u64::<LittleEndian>(b); +} + +fn read_u64<T: Endianness>(b: &mut Bencher) { + b.iter(|| { + let mut reader : &[u8] = &[0; BENCH_SIZE * 8]; + for _ in 0..BENCH_SIZE { + reader.read_u64::<T>().unwrap(); + } + }) +} diff --git a/third_party/rust/podio/script/doc-upload.cfg b/third_party/rust/podio/script/doc-upload.cfg new file mode 100644 index 0000000000..ecaeb5363b --- /dev/null +++ b/third_party/rust/podio/script/doc-upload.cfg @@ -0,0 +1,3 @@ +PROJECT_NAME=podio +DOCS_REPO=mvdnes/rust-docs.git +DOC_RUST_VERSION=stable diff --git a/third_party/rust/podio/src/lib.rs b/third_party/rust/podio/src/lib.rs new file mode 100644 index 0000000000..f313eba398 --- /dev/null +++ b/third_party/rust/podio/src/lib.rs @@ -0,0 +1,336 @@ +//! Additional methods for Read and Write +//! +//! The additional methods implemented allow reading and writing integers and floats +//! in the specified endianness. +//! +//! # Usage +//! +//! Basically, you need to `use` the trait WritePodExt or ReadPodExt. +//! +//! # Examples +//! +//! ## Reading +//! +//! To read some value from a reader, import ReadPodExt and the needed endianness. +//! +//! ``` +//! use podio::{ReadPodExt, BigEndian}; +//! +//! let slice: &[u8] = &[0x10, 0x20, 0x30, 0x40]; +//! let mut reader = std::io::Cursor::new(slice); +//! +//! let value = reader.read_u32::<BigEndian>().unwrap(); +//! +//! assert_eq!(value, 0x10203040); +//! ``` +//! +//! ## Writing +//! +//! For writing, you need to import the trait WritePodExt. +//! +//! ``` +//! use podio::{WritePodExt, LittleEndian}; +//! +//! let slice: &mut [u8] = &mut [0; 2]; +//! let mut writer = std::io::Cursor::new(slice); +//! +//! writer.write_u16::<LittleEndian>(0x8802).unwrap(); +//! +//! assert_eq!(writer.into_inner(), &[0x02, 0x88]); +//! ``` +//! +//! ## Read exact +//! +//! One additional method, not really dealing with POD, is `read_exact`. +//! +//! ``` +//! use podio::ReadPodExt; +//! +//! let slice: &[u8] = &[0, 1, 2, 3]; +//! let mut reader = std::io::Cursor::new(slice); +//! +//! assert_eq!(reader.read_exact(1).unwrap(), [0]); +//! assert_eq!(reader.read_exact(2).unwrap(), [1,2]); +//! assert_eq!(reader.read_exact(0).unwrap(), []); +//! assert_eq!(reader.read_exact(1).unwrap(), [3]); +//! assert!(reader.read_exact(1).is_err()); + +#![warn(missing_docs)] + +use std::io; +use std::io::prelude::*; + +/// Little endian. The number `0xABCD` is stored `[0xCD, 0xAB]` +pub enum LittleEndian {} +/// Big endian. The number `0xABCD` is stored `[0xAB, 0xCD]` +pub enum BigEndian {} + +/// Trait implementing conversion methods for a specific endianness +pub trait Endianness { + /// Converts a value from the platform type to the specified endianness + fn int_to_target<T: EndianConvert>(val: T) -> T; + /// Converts a value from the sepcified endianness to the platform type + fn int_from_target<T: EndianConvert>(val: T) -> T; +} + +/// Generic trait for endian conversions on integers +pub trait EndianConvert { + /// Convert self to a big-endian value + fn to_be(self) -> Self; + /// Convert self to a little-endian value + fn to_le(self) -> Self; + /// Convert a big-endian value to the target endianness + fn from_be(x: Self) -> Self; + /// Convert a little-endian value to the target endiannes + fn from_le(x: Self) -> Self; +} + +/// Additional write methods for a io::Write +pub trait WritePodExt { + /// Write a u64 + fn write_u64<T: Endianness>(&mut self, u64) -> io::Result<()>; + /// Write a u32 + fn write_u32<T: Endianness>(&mut self, u32) -> io::Result<()>; + /// Write a u16 + fn write_u16<T: Endianness>(&mut self, u16) -> io::Result<()>; + /// Write a u8 + fn write_u8(&mut self, u8) -> io::Result<()>; + /// Write a i64 + fn write_i64<T: Endianness>(&mut self, i64) -> io::Result<()>; + /// Write a i32 + fn write_i32<T: Endianness>(&mut self, i32) -> io::Result<()>; + /// Write a i16 + fn write_i16<T: Endianness>(&mut self, i16) -> io::Result<()>; + /// Write a i8 + fn write_i8(&mut self, i8) -> io::Result<()>; + /// Write a f32 + fn write_f32<T: Endianness>(&mut self, f32) -> io::Result<()>; + /// Write a f64 + fn write_f64<T: Endianness>(&mut self, f64) -> io::Result<()>; +} + +/// Additional read methods for a io::Read +pub trait ReadPodExt { + /// Read a u64 + fn read_u64<T: Endianness>(&mut self) -> io::Result<u64>; + /// Read a u32 + fn read_u32<T: Endianness>(&mut self) -> io::Result<u32>; + /// Read a u16 + fn read_u16<T: Endianness>(&mut self) -> io::Result<u16>; + /// Read a u8 + fn read_u8(&mut self) -> io::Result<u8>; + /// Read a i64 + fn read_i64<T: Endianness>(&mut self) -> io::Result<i64>; + /// Read a i32 + fn read_i32<T: Endianness>(&mut self) -> io::Result<i32>; + /// Read a i16 + fn read_i16<T: Endianness>(&mut self) -> io::Result<i16>; + /// Read a i8 + fn read_i8(&mut self) -> io::Result<i8>; + /// Read a f32 + fn read_f32<T: Endianness>(&mut self) -> io::Result<f32>; + /// Read a f64 + fn read_f64<T: Endianness>(&mut self) -> io::Result<f64>; + /// Read a specific number of bytes + fn read_exact(&mut self, usize) -> io::Result<Vec<u8>>; +} + +impl Endianness for LittleEndian { + #[inline] + fn int_to_target<T: EndianConvert>(val: T) -> T { + val.to_le() + } + #[inline] + fn int_from_target<T: EndianConvert>(val: T) -> T { + <T as EndianConvert>::from_le(val) + } +} + +impl Endianness for BigEndian { + #[inline] + fn int_to_target<T: EndianConvert>(val: T) -> T { + val.to_be() + } + #[inline] + fn int_from_target<T: EndianConvert>(val: T) -> T { + <T as EndianConvert>::from_be(val) + } +} + +macro_rules! impl_platform_convert { + ($T:ty) => { + impl EndianConvert for $T { + #[inline] + fn to_be(self) -> $T { + self.to_be() + } + + #[inline] + fn to_le(self) -> $T { + self.to_le() + } + + #[inline] + fn from_be(x: $T) -> $T { + if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + } + + #[inline] + fn from_le(x: $T) -> $T { + if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + } + } + }; +} + +impl_platform_convert!(u8); +impl_platform_convert!(u16); +impl_platform_convert!(u32); +impl_platform_convert!(u64); + +macro_rules! val_to_buf { + ($val:ident, $T:expr) => { + { + let mut buf = [0; $T]; + for i in 0..buf.len() { + buf[i] = ($val >> (i * 8)) as u8; + } + buf + } + }; +} + +impl<W: Write> WritePodExt for W { + fn write_u64<T: Endianness>(&mut self, val: u64) -> io::Result<()> { + let tval = <T as Endianness>::int_to_target(val); + let buf = val_to_buf!(tval, 8); + self.write_all(&buf) + } + + fn write_u32<T: Endianness>(&mut self, val: u32) -> io::Result<()> { + let tval = <T as Endianness>::int_to_target(val); + let buf = val_to_buf!(tval, 4); + self.write_all(&buf) + } + + fn write_u16<T: Endianness>(&mut self, val: u16) -> io::Result<()> { + let tval = <T as Endianness>::int_to_target(val); + let buf = val_to_buf!(tval, 2); + self.write_all(&buf) + } + + fn write_u8(&mut self, val: u8) -> io::Result<()> { + self.write_all(&[val]) + } + + fn write_i64<T: Endianness>(&mut self, val: i64) -> io::Result<()> { + self.write_u64::<T>(val as u64) + } + + fn write_i32<T: Endianness>(&mut self, val: i32) -> io::Result<()> { + self.write_u32::<T>(val as u32) + } + + fn write_i16<T: Endianness>(&mut self, val: i16) -> io::Result<()> { + self.write_u16::<T>(val as u16) + } + + fn write_i8(&mut self, val: i8) -> io::Result<()> { + self.write_u8(val as u8) + } + + fn write_f32<T: Endianness>(&mut self, val: f32) -> io::Result<()> { + let tval: u32 = unsafe { std::mem::transmute::<f32, u32>(val) }; + self.write_u32::<T>(tval) + } + + fn write_f64<T: Endianness>(&mut self, val: f64) -> io::Result<()> { + let tval: u64 = unsafe { std::mem::transmute::<f64, u64>(val) }; + self.write_u64::<T>(tval) + } +} + +#[inline] +fn fill_buf<R: Read>(reader: &mut R, buf: &mut [u8]) -> io::Result<()> { + let mut idx = 0; + while idx != buf.len() { + match reader.read(&mut buf[idx..]) { + Ok(0) => return Err(io::Error::new(io::ErrorKind::Other, "Could not read enough bytes")), + Ok(v) => { idx += v; } + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + Ok(()) +} + +macro_rules! buf_to_val { + ($buf:ident, $T:ty) => { + { + let mut val: $T = 0; + for i in 0..$buf.len() { + val |= ($buf[i] as $T) << (i * 8); + } + val + } + }; +} + +impl<R: Read> ReadPodExt for R { + fn read_u64<T: Endianness>(&mut self) -> io::Result<u64> { + let buf = &mut [0u8; 8]; + try!(fill_buf(self, buf)); + let tval = buf_to_val!(buf, u64); + Ok(<T as Endianness>::int_from_target(tval)) + } + + fn read_u32<T: Endianness>(&mut self) -> io::Result<u32> { + let buf = &mut [0u8; 4]; + try!(fill_buf(self, buf)); + let tval = buf_to_val!(buf, u32); + Ok(<T as Endianness>::int_from_target(tval)) + } + + fn read_u16<T: Endianness>(&mut self) -> io::Result<u16> { + let buf = &mut [0u8; 2]; + try!(fill_buf(self, buf)); + let tval = buf_to_val!(buf, u16); + Ok(<T as Endianness>::int_from_target(tval)) + } + + fn read_u8(&mut self) -> io::Result<u8> { + let buf = &mut [0u8; 1]; + try!(fill_buf(self, buf)); + Ok(buf[0]) + } + + fn read_i64<T: Endianness>(&mut self) -> io::Result<i64> { + self.read_u64::<T>().map(|v| v as i64) + } + + fn read_i32<T: Endianness>(&mut self) -> io::Result<i32> { + self.read_u32::<T>().map(|v| v as i32) + } + + fn read_i16<T: Endianness>(&mut self) -> io::Result<i16> { + self.read_u16::<T>().map(|v| v as i16) + } + + fn read_i8(&mut self) -> io::Result<i8> { + self.read_u8().map(|v| v as i8) + } + + fn read_f64<T: Endianness>(&mut self) -> io::Result<f64> { + self.read_u64::<T>().map(|v| unsafe { std::mem::transmute::<u64, f64>(v) }) + } + + fn read_f32<T: Endianness>(&mut self) -> io::Result<f32> { + self.read_u32::<T>().map(|v| unsafe { std::mem::transmute::<u32, f32>(v) }) + } + + fn read_exact(&mut self, len: usize) -> io::Result<Vec<u8>> { + let mut res = vec![0; len]; + try!(fill_buf(self, &mut res)); + Ok(res) + } +} diff --git a/third_party/rust/podio/tests/bytes.rs b/third_party/rust/podio/tests/bytes.rs new file mode 100644 index 0000000000..493d2d47b0 --- /dev/null +++ b/third_party/rust/podio/tests/bytes.rs @@ -0,0 +1,139 @@ +extern crate podio; + +use std::io; +use podio::{LittleEndian, BigEndian}; +use podio::{ReadPodExt, WritePodExt}; + +#[test] +fn write_be() { + let buf: &mut [u8] = &mut [0u8; 8]; + let mut writer = io::Cursor::new(buf); + + writer.set_position(0); + writer.write_u64::<BigEndian>(0x01_23_45_67_89_ab_cd_ef).unwrap(); + assert_eq!(&writer.get_ref()[0..8], &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]); + + writer.set_position(0); + writer.write_u32::<BigEndian>(0x01_23_45_67).unwrap(); + assert_eq!(&writer.get_ref()[0..4], &[0x01, 0x23, 0x45, 0x67]); + + writer.set_position(0); + writer.write_u16::<BigEndian>(0x01_23).unwrap(); + assert_eq!(&writer.get_ref()[0..2], &[0x01, 0x23]); +} + +#[test] +fn write_le() { + let buf: &mut [u8] = &mut [0u8; 8]; + let mut writer = io::Cursor::new(buf); + + writer.set_position(0); + writer.write_u64::<LittleEndian>(0x01_23_45_67_89_ab_cd_ef).unwrap(); + assert_eq!(&writer.get_ref()[0..8], &[0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01]); + + writer.set_position(0); + writer.write_u32::<LittleEndian>(0x01_23_45_67).unwrap(); + assert_eq!(&writer.get_ref()[0..4], &[0x67, 0x45, 0x23, 0x01]); + + writer.set_position(0); + writer.write_u16::<LittleEndian>(0x01_23).unwrap(); + assert_eq!(&writer.get_ref()[0..2], &[0x23, 0x01]); +} + +#[test] +fn write_octet() { + let buf: &mut [u8] = &mut [0u8; 8]; + let mut writer = io::Cursor::new(buf); + + writer.set_position(0); + writer.write_u8(0x01).unwrap(); + assert_eq!(&writer.get_ref()[0..1], &[0x01]); +} + +#[test] +fn write_float() { + let buf: &mut [u8] = &mut [0u8; 8]; + let mut writer = io::Cursor::new(buf); + + writer.set_position(0); + writer.write_f32::<LittleEndian>(10.12f32).unwrap(); + assert_eq!(&writer.get_ref()[0..4], &[0x85, 0xEB, 0x21, 0x41]); + + writer.set_position(0); + writer.write_f32::<BigEndian>(10.12f32).unwrap(); + assert_eq!(&writer.get_ref()[0..4], &[0x41, 0x21, 0xEB, 0x85]); + + writer.set_position(0); + writer.write_f64::<LittleEndian>(10.12f64).unwrap(); + assert_eq!(&writer.get_ref()[0..8], &[0x3D, 0x0A, 0xD7, 0xA3, 0x70, 0x3D, 0x24, 0x40]); + + writer.set_position(0); + writer.write_f64::<BigEndian>(10.12f64).unwrap(); + assert_eq!(&writer.get_ref()[0..8], &[0x40, 0x24, 0x3D, 0x70, 0xA3, 0xD7, 0x0A, 0x3D]); +} + +#[test] +fn read_be() { + let buf: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]; + let mut reader = io::Cursor::new(buf); + + reader.set_position(0); + assert_eq!(reader.read_u64::<BigEndian>().unwrap(), 0x0123456789abcdef); + + reader.set_position(0); + assert_eq!(reader.read_u32::<BigEndian>().unwrap(), 0x01234567); + + reader.set_position(0); + assert_eq!(reader.read_u16::<BigEndian>().unwrap(), 0x0123); +} + +#[test] +fn read_le() { + let buf: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]; + let mut reader = io::Cursor::new(buf); + + reader.set_position(0); + assert_eq!(reader.read_u64::<LittleEndian>().unwrap(), 0xefcdab8967452301); + + reader.set_position(0); + assert_eq!(reader.read_u32::<LittleEndian>().unwrap(), 0x67452301); + + reader.set_position(0); + assert_eq!(reader.read_u16::<LittleEndian>().unwrap(), 0x2301); +} + +#[test] +fn read_octet() { + let buf: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]; + let mut reader = io::Cursor::new(buf); + + reader.set_position(0); + assert_eq!(reader.read_u8().unwrap(), 0x01); +} + +#[test] +fn read_float() { + let mut buf: &[u8] = &[0x41, 0x21, 0xEB, 0x85]; + assert_eq!(buf.read_f32::<BigEndian>().unwrap(), 10.12f32); + + let mut buf: &[u8] = &[0x85, 0xEB, 0x21, 0x41]; + assert_eq!(buf.read_f32::<LittleEndian>().unwrap(), 10.12f32); + + let mut buf: &[u8] = &[0x40, 0x24, 0x3D, 0x70, 0xA3, 0xD7, 0x0A, 0x3D]; + assert_eq!(buf.read_f64::<BigEndian>().unwrap(), 10.12f64); + + let mut buf: &[u8] = &[0x3D, 0x0A, 0xD7, 0xA3, 0x70, 0x3D, 0x24, 0x40]; + assert_eq!(buf.read_f64::<LittleEndian>().unwrap(), 10.12f64); +} + +#[test] +fn read_exact() { + let mut buf: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8]; + assert_eq!(buf.read_exact(2).unwrap(), [1,2]); + assert_eq!(buf.read_exact(1).unwrap(), [3]); + assert_eq!(buf.read_exact(0).unwrap(), []); + assert_eq!(buf.read_exact(5).unwrap(), [4,5,6,7,8]); + assert_eq!(buf.read_exact(0).unwrap(), []); + assert!(buf.read_exact(1).is_err()); + assert_eq!(buf.read_exact(0).unwrap(), []); +} diff --git a/third_party/rust/podio/tests/io.rs b/third_party/rust/podio/tests/io.rs new file mode 100644 index 0000000000..fba75625a4 --- /dev/null +++ b/third_party/rust/podio/tests/io.rs @@ -0,0 +1,57 @@ +extern crate podio; + +use std::io::{self, Read}; +use podio::ReadPodExt; + +struct TestReader { + state: Option<io::Result<usize>>, +} + +impl TestReader { + fn new(first_return: io::Result<usize>) -> TestReader { + TestReader { state: Some(first_return) } + } + + fn get(&mut self) -> io::Result<u32> { + self.read_u32::<podio::LittleEndian>() + } + + fn test(first_return: io::Result<usize>) -> io::Result<u32> { + TestReader::new(first_return).get() + } +} + +impl Read for TestReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + match self.state.take().unwrap_or(Ok(1)) { + Ok(n) => { + for i in buf.iter_mut().take(n) { + *i = 0xA5; + } + Ok(n) + }, + e @ Err(..) => e, + } + } +} + +#[test] +fn interrupted() { + // Getting an io::ErrorKind::Interrupted should be retried, and thus succeed + let first_read = Err(io::Error::new(io::ErrorKind::Interrupted, "Interrupted")); + assert_eq!(TestReader::test(first_read).unwrap(), 0xA5A5A5A5); +} + +#[test] +fn eof() { + // Getting a Ok(0) implies an unexpected EOF + let first_read = Ok(0); + assert!(TestReader::test(first_read).is_err()); +} + +#[test] +fn err() { + // Getting any other error is still an error + let first_read = Err(io::Error::new(io::ErrorKind::Other, "Other")); + assert!(TestReader::test(first_read).is_err()); +} |