| 1 | // Copyright (c) 2015 Andrew Gallant |
|---|---|
| 2 | |
| 3 | use std::io; |
| 4 | use std::io::Result; |
| 5 | use std::ptr::copy_nonoverlapping; |
| 6 | |
| 7 | #[derive(Copy, Clone)] |
| 8 | pub struct LittleEndian; |
| 9 | |
| 10 | #[derive(Copy, Clone)] |
| 11 | pub struct BigEndian; |
| 12 | |
| 13 | #[cfg(target_endian = "little")] |
| 14 | pub type NativeEndian = LittleEndian; |
| 15 | |
| 16 | #[cfg(target_endian = "big")] |
| 17 | pub type NativeEndian = BigEndian; |
| 18 | |
| 19 | macro_rules! read_num_bytes { |
| 20 | ($ty:ty, $size:expr, $src:expr, $which:ident) => {{ |
| 21 | assert!($size == ::std::mem::size_of::<$ty>()); |
| 22 | assert!($size <= $src.len()); |
| 23 | let mut data: $ty = 0; |
| 24 | unsafe { |
| 25 | copy_nonoverlapping($src.as_ptr(), &mut data as *mut $ty as *mut u8, $size); |
| 26 | } |
| 27 | data.$which() |
| 28 | }}; |
| 29 | } |
| 30 | |
| 31 | macro_rules! write_num_bytes { |
| 32 | ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => {{ |
| 33 | assert!($size <= $dst.len()); |
| 34 | unsafe { |
| 35 | // N.B. https://github.com/rust-lang/rust/issues/22776 |
| 36 | let bytes = *(&$n.$which() as *const _ as *const [u8; $size]); |
| 37 | copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size); |
| 38 | } |
| 39 | }}; |
| 40 | } |
| 41 | |
| 42 | impl ByteOrder for LittleEndian { |
| 43 | #[inline] |
| 44 | fn read_u16(buf: &[u8]) -> u16 { |
| 45 | read_num_bytes!(u16, 2, buf, to_le) |
| 46 | } |
| 47 | |
| 48 | #[inline] |
| 49 | fn read_u32(buf: &[u8]) -> u32 { |
| 50 | read_num_bytes!(u32, 4, buf, to_le) |
| 51 | } |
| 52 | |
| 53 | #[inline] |
| 54 | fn read_u64(buf: &[u8]) -> u64 { |
| 55 | read_num_bytes!(u64, 8, buf, to_le) |
| 56 | } |
| 57 | |
| 58 | #[inline] |
| 59 | fn write_u16(buf: &mut [u8], n: u16) { |
| 60 | write_num_bytes!(u16, 2, n, buf, to_le); |
| 61 | } |
| 62 | |
| 63 | #[inline] |
| 64 | fn write_u32(buf: &mut [u8], n: u32) { |
| 65 | write_num_bytes!(u32, 4, n, buf, to_le); |
| 66 | } |
| 67 | |
| 68 | #[inline] |
| 69 | fn write_u64(buf: &mut [u8], n: u64) { |
| 70 | write_num_bytes!(u64, 8, n, buf, to_le); |
| 71 | } |
| 72 | |
| 73 | serde_if_integer128! { |
| 74 | #[inline] |
| 75 | fn write_u128(buf: &mut [u8], n: u128) { |
| 76 | write_num_bytes!(u128, 16, n, buf, to_le); |
| 77 | } |
| 78 | |
| 79 | #[inline] |
| 80 | fn read_u128(buf: &[u8]) -> u128 { |
| 81 | read_num_bytes!(u128, 16, buf, to_le) |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | impl ByteOrder for BigEndian { |
| 87 | #[inline] |
| 88 | fn read_u16(buf: &[u8]) -> u16 { |
| 89 | read_num_bytes!(u16, 2, buf, to_be) |
| 90 | } |
| 91 | |
| 92 | #[inline] |
| 93 | fn read_u32(buf: &[u8]) -> u32 { |
| 94 | read_num_bytes!(u32, 4, buf, to_be) |
| 95 | } |
| 96 | |
| 97 | #[inline] |
| 98 | fn read_u64(buf: &[u8]) -> u64 { |
| 99 | read_num_bytes!(u64, 8, buf, to_be) |
| 100 | } |
| 101 | |
| 102 | #[inline] |
| 103 | fn write_u16(buf: &mut [u8], n: u16) { |
| 104 | write_num_bytes!(u16, 2, n, buf, to_be); |
| 105 | } |
| 106 | |
| 107 | #[inline] |
| 108 | fn write_u32(buf: &mut [u8], n: u32) { |
| 109 | write_num_bytes!(u32, 4, n, buf, to_be); |
| 110 | } |
| 111 | |
| 112 | #[inline] |
| 113 | fn write_u64(buf: &mut [u8], n: u64) { |
| 114 | write_num_bytes!(u64, 8, n, buf, to_be); |
| 115 | } |
| 116 | |
| 117 | serde_if_integer128! { |
| 118 | #[inline] |
| 119 | fn write_u128(buf: &mut [u8], n: u128) { |
| 120 | write_num_bytes!(u128, 16, n, buf, to_be); |
| 121 | } |
| 122 | |
| 123 | #[inline] |
| 124 | fn read_u128(buf: &[u8]) -> u128 { |
| 125 | read_num_bytes!(u128, 16, buf, to_be) |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | pub trait ByteOrder: Clone + Copy { |
| 131 | fn read_u16(buf: &[u8]) -> u16; |
| 132 | |
| 133 | fn read_u32(buf: &[u8]) -> u32; |
| 134 | |
| 135 | fn read_u64(buf: &[u8]) -> u64; |
| 136 | |
| 137 | fn write_u16(buf: &mut [u8], n: u16); |
| 138 | |
| 139 | fn write_u32(buf: &mut [u8], n: u32); |
| 140 | |
| 141 | fn write_u64(buf: &mut [u8], n: u64); |
| 142 | |
| 143 | #[inline] |
| 144 | fn read_i16(buf: &[u8]) -> i16 { |
| 145 | Self::read_u16(buf) as i16 |
| 146 | } |
| 147 | |
| 148 | #[inline] |
| 149 | fn read_i32(buf: &[u8]) -> i32 { |
| 150 | Self::read_u32(buf) as i32 |
| 151 | } |
| 152 | |
| 153 | #[inline] |
| 154 | fn read_i64(buf: &[u8]) -> i64 { |
| 155 | Self::read_u64(buf) as i64 |
| 156 | } |
| 157 | |
| 158 | #[inline] |
| 159 | fn read_f32(buf: &[u8]) -> f32 { |
| 160 | unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) } |
| 161 | } |
| 162 | |
| 163 | #[inline] |
| 164 | fn read_f64(buf: &[u8]) -> f64 { |
| 165 | unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) } |
| 166 | } |
| 167 | |
| 168 | #[inline] |
| 169 | fn write_i16(buf: &mut [u8], n: i16) { |
| 170 | Self::write_u16(buf, n as u16) |
| 171 | } |
| 172 | |
| 173 | #[inline] |
| 174 | fn write_i32(buf: &mut [u8], n: i32) { |
| 175 | Self::write_u32(buf, n as u32) |
| 176 | } |
| 177 | |
| 178 | #[inline] |
| 179 | fn write_i64(buf: &mut [u8], n: i64) { |
| 180 | Self::write_u64(buf, n as u64) |
| 181 | } |
| 182 | |
| 183 | #[inline] |
| 184 | fn write_f32(buf: &mut [u8], n: f32) { |
| 185 | let n = unsafe { *(&n as *const f32 as *const u32) }; |
| 186 | Self::write_u32(buf, n) |
| 187 | } |
| 188 | |
| 189 | #[inline] |
| 190 | fn write_f64(buf: &mut [u8], n: f64) { |
| 191 | let n = unsafe { *(&n as *const f64 as *const u64) }; |
| 192 | Self::write_u64(buf, n) |
| 193 | } |
| 194 | |
| 195 | serde_if_integer128! { |
| 196 | fn read_u128(buf: &[u8]) -> u128; |
| 197 | fn write_u128(buf: &mut [u8], n: u128); |
| 198 | |
| 199 | #[inline] |
| 200 | fn read_i128(buf: &[u8]) -> i128 { |
| 201 | Self::read_u128(buf) as i128 |
| 202 | } |
| 203 | |
| 204 | #[inline] |
| 205 | fn write_i128(buf: &mut [u8], n: i128) { |
| 206 | Self::write_u128(buf, n as u128) |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | pub trait ReadBytesExt: io::Read { |
| 212 | #[inline] |
| 213 | fn read_u8(&mut self) -> Result<u8> { |
| 214 | let mut buf = [0; 1]; |
| 215 | try!(self.read_exact(&mut buf)); |
| 216 | Ok(buf[0]) |
| 217 | } |
| 218 | |
| 219 | #[inline] |
| 220 | fn read_i8(&mut self) -> Result<i8> { |
| 221 | let mut buf = [0; 1]; |
| 222 | try!(self.read_exact(&mut buf)); |
| 223 | Ok(buf[0] as i8) |
| 224 | } |
| 225 | |
| 226 | #[inline] |
| 227 | fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> { |
| 228 | let mut buf = [0; 2]; |
| 229 | try!(self.read_exact(&mut buf)); |
| 230 | Ok(T::read_u16(&buf)) |
| 231 | } |
| 232 | |
| 233 | #[inline] |
| 234 | fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> { |
| 235 | let mut buf = [0; 2]; |
| 236 | try!(self.read_exact(&mut buf)); |
| 237 | Ok(T::read_i16(&buf)) |
| 238 | } |
| 239 | |
| 240 | #[inline] |
| 241 | fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> { |
| 242 | let mut buf = [0; 4]; |
| 243 | try!(self.read_exact(&mut buf)); |
| 244 | Ok(T::read_u32(&buf)) |
| 245 | } |
| 246 | |
| 247 | #[inline] |
| 248 | fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> { |
| 249 | let mut buf = [0; 4]; |
| 250 | try!(self.read_exact(&mut buf)); |
| 251 | Ok(T::read_i32(&buf)) |
| 252 | } |
| 253 | |
| 254 | #[inline] |
| 255 | fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> { |
| 256 | let mut buf = [0; 8]; |
| 257 | try!(self.read_exact(&mut buf)); |
| 258 | Ok(T::read_u64(&buf)) |
| 259 | } |
| 260 | |
| 261 | #[inline] |
| 262 | fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> { |
| 263 | let mut buf = [0; 8]; |
| 264 | try!(self.read_exact(&mut buf)); |
| 265 | Ok(T::read_i64(&buf)) |
| 266 | } |
| 267 | |
| 268 | #[inline] |
| 269 | fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> { |
| 270 | let mut buf = [0; 4]; |
| 271 | try!(self.read_exact(&mut buf)); |
| 272 | Ok(T::read_f32(&buf)) |
| 273 | } |
| 274 | |
| 275 | #[inline] |
| 276 | fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> { |
| 277 | let mut buf = [0; 8]; |
| 278 | try!(self.read_exact(&mut buf)); |
| 279 | Ok(T::read_f64(&buf)) |
| 280 | } |
| 281 | |
| 282 | serde_if_integer128! { |
| 283 | #[inline] |
| 284 | fn read_u128<T: ByteOrder>(&mut self) -> Result<u128> { |
| 285 | let mut buf = [0; 16]; |
| 286 | try!(self.read_exact(&mut buf)); |
| 287 | Ok(T::read_u128(&buf)) |
| 288 | } |
| 289 | |
| 290 | #[inline] |
| 291 | fn read_i128<T: ByteOrder>(&mut self) -> Result<i128> { |
| 292 | let mut buf = [0; 16]; |
| 293 | try!(self.read_exact(&mut buf)); |
| 294 | Ok(T::read_i128(&buf)) |
| 295 | } |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | impl<R: io::Read + ?Sized> ReadBytesExt for R {} |
| 300 | |
| 301 | pub trait WriteBytesExt: io::Write { |
| 302 | #[inline] |
| 303 | fn write_u8(&mut self, n: u8) -> Result<()> { |
| 304 | self.write_all(&[n]) |
| 305 | } |
| 306 | |
| 307 | #[inline] |
| 308 | fn write_i8(&mut self, n: i8) -> Result<()> { |
| 309 | self.write_all(&[n as u8]) |
| 310 | } |
| 311 | |
| 312 | #[inline] |
| 313 | fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> { |
| 314 | let mut buf = [0; 2]; |
| 315 | T::write_u16(&mut buf, n); |
| 316 | self.write_all(&buf) |
| 317 | } |
| 318 | |
| 319 | #[inline] |
| 320 | fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> { |
| 321 | let mut buf = [0; 2]; |
| 322 | T::write_i16(&mut buf, n); |
| 323 | self.write_all(&buf) |
| 324 | } |
| 325 | |
| 326 | #[inline] |
| 327 | fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> { |
| 328 | let mut buf = [0; 4]; |
| 329 | T::write_u32(&mut buf, n); |
| 330 | self.write_all(&buf) |
| 331 | } |
| 332 | |
| 333 | #[inline] |
| 334 | fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> { |
| 335 | let mut buf = [0; 4]; |
| 336 | T::write_i32(&mut buf, n); |
| 337 | self.write_all(&buf) |
| 338 | } |
| 339 | |
| 340 | #[inline] |
| 341 | fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> { |
| 342 | let mut buf = [0; 8]; |
| 343 | T::write_u64(&mut buf, n); |
| 344 | self.write_all(&buf) |
| 345 | } |
| 346 | |
| 347 | #[inline] |
| 348 | fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> { |
| 349 | let mut buf = [0; 8]; |
| 350 | T::write_i64(&mut buf, n); |
| 351 | self.write_all(&buf) |
| 352 | } |
| 353 | |
| 354 | #[inline] |
| 355 | fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> { |
| 356 | let mut buf = [0; 4]; |
| 357 | T::write_f32(&mut buf, n); |
| 358 | self.write_all(&buf) |
| 359 | } |
| 360 | |
| 361 | #[inline] |
| 362 | fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> { |
| 363 | let mut buf = [0; 8]; |
| 364 | T::write_f64(&mut buf, n); |
| 365 | self.write_all(&buf) |
| 366 | } |
| 367 | |
| 368 | serde_if_integer128! { |
| 369 | #[inline] |
| 370 | fn write_u128<T: ByteOrder>(&mut self, n: u128) -> Result<()> { |
| 371 | let mut buf = [0; 16]; |
| 372 | T::write_u128(&mut buf, n); |
| 373 | self.write_all(&buf) |
| 374 | } |
| 375 | |
| 376 | #[inline] |
| 377 | fn write_i128<T: ByteOrder>(&mut self, n: i128) -> Result<()> { |
| 378 | let mut buf = [0; 16]; |
| 379 | T::write_i128(&mut buf, n); |
| 380 | self.write_all(&buf) |
| 381 | } |
| 382 | } |
| 383 | } |
| 384 | |
| 385 | impl<W: io::Write + ?Sized> WriteBytesExt for W {} |
| 386 |
Definitions
- LittleEndian
- BigEndian
- NativeEndian
- read_num_bytes
- write_num_bytes
- read_u16
- read_u32
- read_u64
- write_u16
- write_u32
- write_u64
- write_u128
- read_u128
- read_u16
- read_u32
- read_u64
- write_u16
- write_u32
- write_u64
- write_u128
- read_u128
- ByteOrder
- read_u16
- read_u32
- read_u64
- write_u16
- write_u32
- write_u64
- read_i16
- read_i32
- read_i64
- read_f32
- read_f64
- write_i16
- write_i32
- write_i64
- write_f32
- write_f64
- read_u128
- write_u128
- read_i128
- write_i128
- ReadBytesExt
- read_u8
- read_i8
- read_u16
- read_i16
- read_u32
- read_i32
- read_u64
- read_i64
- read_f32
- read_f64
- read_u128
- read_i128
- WriteBytesExt
- write_u8
- write_i8
- write_u16
- write_i16
- write_u32
- write_i32
- write_u64
- write_i64
- write_f32
- write_f64
- write_u128
Learn Rust with the experts
Find out more
