-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Buf::get_int()
implementation for Bytes
returns positive number instead of negative when nbytes
< 8.
#730
Comments
It looks like this has been caused by 234d814 / #280, as demonstrated by the revert: See the revertFrom 4a9b9a4ea0538dff7d9ae57070c98f6ad4afd708 Mon Sep 17 00:00:00 2001
From: Paolo Barbolini <[email protected]>
Date: Mon, 19 Aug 2024 06:08:47 +0200
Subject: [PATCH] Revert "Remove byteorder dependency (#280)"
This reverts commit 234d814122d6445bdfb15f635290bfc4dd36c2eb.
---
Cargo.toml | 1 +
src/buf/buf_impl.rs | 126 ++++++++++++++++++--------------------------
src/buf/buf_mut.rs | 119 +++++++++++++++++++++++++----------------
3 files changed, 127 insertions(+), 119 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index e072539..a49d681 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,6 +24,7 @@ std = []
[dependencies]
serde = { version = "1.0.60", optional = true, default-features = false, features = ["alloc"] }
+byteorder = "1.3"
[dev-dependencies]
serde_test = "1.0"
diff --git a/src/buf/buf_impl.rs b/src/buf/buf_impl.rs
index c44d4fb..5817f41 100644
--- a/src/buf/buf_impl.rs
+++ b/src/buf/buf_impl.rs
@@ -1,68 +1,46 @@
#[cfg(feature = "std")]
use crate::buf::{reader, Reader};
use crate::buf::{take, Chain, Take};
+use crate::panic_advance;
#[cfg(feature = "std")]
use crate::{min_u64_usize, saturating_sub_usize_u64};
-use crate::{panic_advance, panic_does_not_fit};
#[cfg(feature = "std")]
use std::io::IoSlice;
use alloc::boxed::Box;
-macro_rules! buf_get_impl {
- ($this:ident, $typ:tt::$conv:tt) => {{
- const SIZE: usize = core::mem::size_of::<$typ>();
-
- if $this.remaining() < SIZE {
- panic_advance(SIZE, $this.remaining());
- }
+use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian};
+macro_rules! buf_get_impl {
+ ($this:ident, $size:expr, $conv:path) => {{
// try to convert directly from the bytes
- // this Option<ret> trick is to avoid keeping a borrow on self
- // when advance() is called (mut borrow) and to call bytes() only once
- let ret = $this
- .chunk()
- .get(..SIZE)
- .map(|src| unsafe { $typ::$conv(*(src as *const _ as *const [_; SIZE])) });
-
+ let ret = {
+ // this Option<ret> trick is to avoid keeping a borrow on self
+ // when advance() is called (mut borrow) and to call bytes() only once
+ if let Some(src) = $this.chunk().get(..($size)) {
+ Some($conv(src))
+ } else {
+ None
+ }
+ };
if let Some(ret) = ret {
// if the direct conversion was possible, advance and return
- $this.advance(SIZE);
+ $this.advance($size);
return ret;
} else {
// if not we copy the bytes in a temp buffer then convert
- let mut buf = [0; SIZE];
+ let mut buf = [0; ($size)];
$this.copy_to_slice(&mut buf); // (do the advance)
- return $typ::$conv(buf);
+ return $conv(&buf);
}
}};
- (le => $this:ident, $typ:tt, $len_to_read:expr) => {{
- const SIZE: usize = core::mem::size_of::<$typ>();
-
+ ($this:ident, $buf_size:expr, $conv:path, $len_to_read:expr) => {{
// The same trick as above does not improve the best case speed.
// It seems to be linked to the way the method is optimised by the compiler
- let mut buf = [0; SIZE];
-
- let subslice = match buf.get_mut(..$len_to_read) {
- Some(subslice) => subslice,
- None => panic_does_not_fit(SIZE, $len_to_read),
- };
-
- $this.copy_to_slice(subslice);
- return $typ::from_le_bytes(buf);
- }};
- (be => $this:ident, $typ:tt, $len_to_read:expr) => {{
- const SIZE: usize = core::mem::size_of::<$typ>();
-
- let slice_at = match SIZE.checked_sub($len_to_read) {
- Some(slice_at) => slice_at,
- None => panic_does_not_fit(SIZE, $len_to_read),
- };
-
- let mut buf = [0; SIZE];
- $this.copy_to_slice(&mut buf[slice_at..]);
- return $typ::from_be_bytes(buf);
+ let mut buf = [0; ($buf_size)];
+ $this.copy_to_slice(&mut buf[..($len_to_read)]);
+ return $conv(&buf[..($len_to_read)], $len_to_read);
}};
}
@@ -350,7 +328,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u16(&mut self) -> u16 {
- buf_get_impl!(self, u16::from_be_bytes);
+ buf_get_impl!(self, 2, BigEndian::read_u16);
}
/// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
@@ -370,7 +348,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u16_le(&mut self) -> u16 {
- buf_get_impl!(self, u16::from_le_bytes);
+ buf_get_impl!(self, 2, LittleEndian::read_u16);
}
/// Gets an unsigned 16 bit integer from `self` in native-endian byte order.
@@ -393,7 +371,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u16_ne(&mut self) -> u16 {
- buf_get_impl!(self, u16::from_ne_bytes);
+ buf_get_impl!(self, 2, NativeEndian::read_u16);
}
/// Gets a signed 16 bit integer from `self` in big-endian byte order.
@@ -413,7 +391,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i16(&mut self) -> i16 {
- buf_get_impl!(self, i16::from_be_bytes);
+ buf_get_impl!(self, 2, BigEndian::read_i16);
}
/// Gets a signed 16 bit integer from `self` in little-endian byte order.
@@ -433,7 +411,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i16_le(&mut self) -> i16 {
- buf_get_impl!(self, i16::from_le_bytes);
+ buf_get_impl!(self, 2, LittleEndian::read_i16);
}
/// Gets a signed 16 bit integer from `self` in native-endian byte order.
@@ -456,7 +434,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i16_ne(&mut self) -> i16 {
- buf_get_impl!(self, i16::from_ne_bytes);
+ buf_get_impl!(self, 2, NativeEndian::read_i16);
}
/// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
@@ -476,7 +454,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u32(&mut self) -> u32 {
- buf_get_impl!(self, u32::from_be_bytes);
+ buf_get_impl!(self, 4, BigEndian::read_u32);
}
/// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
@@ -496,7 +474,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u32_le(&mut self) -> u32 {
- buf_get_impl!(self, u32::from_le_bytes);
+ buf_get_impl!(self, 4, LittleEndian::read_u32);
}
/// Gets an unsigned 32 bit integer from `self` in native-endian byte order.
@@ -519,7 +497,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u32_ne(&mut self) -> u32 {
- buf_get_impl!(self, u32::from_ne_bytes);
+ buf_get_impl!(self, 4, NativeEndian::read_u32);
}
/// Gets a signed 32 bit integer from `self` in big-endian byte order.
@@ -539,7 +517,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i32(&mut self) -> i32 {
- buf_get_impl!(self, i32::from_be_bytes);
+ buf_get_impl!(self, 4, BigEndian::read_i32);
}
/// Gets a signed 32 bit integer from `self` in little-endian byte order.
@@ -559,7 +537,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i32_le(&mut self) -> i32 {
- buf_get_impl!(self, i32::from_le_bytes);
+ buf_get_impl!(self, 4, LittleEndian::read_i32);
}
/// Gets a signed 32 bit integer from `self` in native-endian byte order.
@@ -582,7 +560,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i32_ne(&mut self) -> i32 {
- buf_get_impl!(self, i32::from_ne_bytes);
+ buf_get_impl!(self, 4, NativeEndian::read_i32);
}
/// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
@@ -602,7 +580,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64(&mut self) -> u64 {
- buf_get_impl!(self, u64::from_be_bytes);
+ buf_get_impl!(self, 8, BigEndian::read_u64);
}
/// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
@@ -622,7 +600,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64_le(&mut self) -> u64 {
- buf_get_impl!(self, u64::from_le_bytes);
+ buf_get_impl!(self, 8, LittleEndian::read_u64);
}
/// Gets an unsigned 64 bit integer from `self` in native-endian byte order.
@@ -645,7 +623,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64_ne(&mut self) -> u64 {
- buf_get_impl!(self, u64::from_ne_bytes);
+ buf_get_impl!(self, 8, NativeEndian::read_u64);
}
/// Gets a signed 64 bit integer from `self` in big-endian byte order.
@@ -665,7 +643,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64(&mut self) -> i64 {
- buf_get_impl!(self, i64::from_be_bytes);
+ buf_get_impl!(self, 8, BigEndian::read_i64);
}
/// Gets a signed 64 bit integer from `self` in little-endian byte order.
@@ -685,7 +663,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64_le(&mut self) -> i64 {
- buf_get_impl!(self, i64::from_le_bytes);
+ buf_get_impl!(self, 8, LittleEndian::read_i64);
}
/// Gets a signed 64 bit integer from `self` in native-endian byte order.
@@ -708,7 +686,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64_ne(&mut self) -> i64 {
- buf_get_impl!(self, i64::from_ne_bytes);
+ buf_get_impl!(self, 8, NativeEndian::read_i64);
}
/// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
@@ -728,7 +706,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u128(&mut self) -> u128 {
- buf_get_impl!(self, u128::from_be_bytes);
+ buf_get_impl!(self, 16, BigEndian::read_u128);
}
/// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
@@ -748,7 +726,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u128_le(&mut self) -> u128 {
- buf_get_impl!(self, u128::from_le_bytes);
+ buf_get_impl!(self, 16, LittleEndian::read_u128);
}
/// Gets an unsigned 128 bit integer from `self` in native-endian byte order.
@@ -771,7 +749,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u128_ne(&mut self) -> u128 {
- buf_get_impl!(self, u128::from_ne_bytes);
+ buf_get_impl!(self, 16, NativeEndian::read_u128);
}
/// Gets a signed 128 bit integer from `self` in big-endian byte order.
@@ -791,7 +769,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i128(&mut self) -> i128 {
- buf_get_impl!(self, i128::from_be_bytes);
+ buf_get_impl!(self, 16, BigEndian::read_i128);
}
/// Gets a signed 128 bit integer from `self` in little-endian byte order.
@@ -811,7 +789,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i128_le(&mut self) -> i128 {
- buf_get_impl!(self, i128::from_le_bytes);
+ buf_get_impl!(self, 16, LittleEndian::read_i128);
}
/// Gets a signed 128 bit integer from `self` in native-endian byte order.
@@ -834,7 +812,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i128_ne(&mut self) -> i128 {
- buf_get_impl!(self, i128::from_ne_bytes);
+ buf_get_impl!(self, 16, NativeEndian::read_i128);
}
/// Gets an unsigned n-byte integer from `self` in big-endian byte order.
@@ -854,7 +832,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_uint(&mut self, nbytes: usize) -> u64 {
- buf_get_impl!(be => self, u64, nbytes);
+ buf_get_impl!(self, 8, BigEndian::read_uint, nbytes);
}
/// Gets an unsigned n-byte integer from `self` in little-endian byte order.
@@ -874,7 +852,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_uint_le(&mut self, nbytes: usize) -> u64 {
- buf_get_impl!(le => self, u64, nbytes);
+ buf_get_impl!(self, 8, LittleEndian::read_uint, nbytes);
}
/// Gets an unsigned n-byte integer from `self` in native-endian byte order.
@@ -923,7 +901,7 @@ pub trait Buf {
/// This function panics if there is not enough remaining data in `self`, or
/// if `nbytes` is greater than 8.
fn get_int(&mut self, nbytes: usize) -> i64 {
- buf_get_impl!(be => self, i64, nbytes);
+ buf_get_impl!(self, 8, BigEndian::read_int, nbytes);
}
/// Gets a signed n-byte integer from `self` in little-endian byte order.
@@ -944,7 +922,7 @@ pub trait Buf {
/// This function panics if there is not enough remaining data in `self`, or
/// if `nbytes` is greater than 8.
fn get_int_le(&mut self, nbytes: usize) -> i64 {
- buf_get_impl!(le => self, i64, nbytes);
+ buf_get_impl!(self, 8, LittleEndian::read_int, nbytes);
}
/// Gets a signed n-byte integer from `self` in native-endian byte order.
@@ -993,7 +971,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f32(&mut self) -> f32 {
- f32::from_bits(self.get_u32())
+ buf_get_impl!(self, 4, BigEndian::read_f32);
}
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
@@ -1038,7 +1016,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f32_ne(&mut self) -> f32 {
- f32::from_bits(self.get_u32_ne())
+ buf_get_impl!(self, 4, LittleEndian::read_f32);
}
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
@@ -1059,7 +1037,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f64(&mut self) -> f64 {
- f64::from_bits(self.get_u64())
+ buf_get_impl!(self, 8, BigEndian::read_f64);
}
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
@@ -1080,7 +1058,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f64_le(&mut self) -> f64 {
- f64::from_bits(self.get_u64_le())
+ buf_get_impl!(self, 8, LittleEndian::read_f64);
}
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs
index e13278d..73baa1e 100644
--- a/src/buf/buf_mut.rs
+++ b/src/buf/buf_mut.rs
@@ -3,9 +3,10 @@ use crate::buf::{limit, Chain, Limit, UninitSlice};
use crate::buf::{writer, Writer};
use crate::{panic_advance, panic_does_not_fit};
-use core::{mem, ptr, usize};
+use core::{ptr, usize};
use alloc::{boxed::Box, vec::Vec};
+use byteorder::{BigEndian, ByteOrder, LittleEndian};
/// A trait for values that provide sequential write access to bytes.
///
@@ -367,7 +368,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u16(&mut self, n: u16) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 2];
+ BigEndian::write_u16(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 16 bit integer to `self` in little-endian byte order.
@@ -390,7 +393,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u16_le(&mut self, n: u16) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 2];
+ LittleEndian::write_u16(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 16 bit integer to `self` in native-endian byte order.
@@ -440,7 +445,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i16(&mut self, n: i16) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 2];
+ BigEndian::write_i16(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 16 bit integer to `self` in little-endian byte order.
@@ -463,7 +470,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i16_le(&mut self, n: i16) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 2];
+ LittleEndian::write_i16(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 16 bit integer to `self` in native-endian byte order.
@@ -513,7 +522,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u32(&mut self, n: u32) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 4];
+ BigEndian::write_u32(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 32 bit integer to `self` in little-endian byte order.
@@ -536,7 +547,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u32_le(&mut self, n: u32) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 4];
+ LittleEndian::write_u32(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 32 bit integer to `self` in native-endian byte order.
@@ -586,7 +599,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i32(&mut self, n: i32) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 4];
+ BigEndian::write_i32(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 32 bit integer to `self` in little-endian byte order.
@@ -609,7 +624,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i32_le(&mut self, n: i32) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 4];
+ LittleEndian::write_i32(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 32 bit integer to `self` in native-endian byte order.
@@ -659,7 +676,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u64(&mut self, n: u64) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 8];
+ BigEndian::write_u64(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 64 bit integer to `self` in little-endian byte order.
@@ -682,7 +701,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u64_le(&mut self, n: u64) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 8];
+ LittleEndian::write_u64(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 64 bit integer to `self` in native-endian byte order.
@@ -732,7 +753,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i64(&mut self, n: i64) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 8];
+ BigEndian::write_i64(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 64 bit integer to `self` in little-endian byte order.
@@ -755,7 +778,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i64_le(&mut self, n: i64) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 8];
+ LittleEndian::write_i64(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 64 bit integer to `self` in native-endian byte order.
@@ -805,7 +830,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u128(&mut self, n: u128) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 16];
+ BigEndian::write_u128(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 128 bit integer to `self` in little-endian byte order.
@@ -828,7 +855,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_u128_le(&mut self, n: u128) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 16];
+ LittleEndian::write_u128(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an unsigned 128 bit integer to `self` in native-endian byte order.
@@ -878,7 +907,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i128(&mut self, n: i128) {
- self.put_slice(&n.to_be_bytes())
+ let mut buf = [0; 16];
+ BigEndian::write_i128(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 128 bit integer to `self` in little-endian byte order.
@@ -901,7 +932,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_i128_le(&mut self, n: i128) {
- self.put_slice(&n.to_le_bytes())
+ let mut buf = [0; 16];
+ LittleEndian::write_i128(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes a signed 128 bit integer to `self` in native-endian byte order.
@@ -951,12 +984,9 @@ pub unsafe trait BufMut {
/// `self` or if `nbytes` is greater than 8.
#[inline]
fn put_uint(&mut self, n: u64, nbytes: usize) {
- let start = match mem::size_of_val(&n).checked_sub(nbytes) {
- Some(start) => start,
- None => panic_does_not_fit(nbytes, mem::size_of_val(&n)),
- };
-
- self.put_slice(&n.to_be_bytes()[start..]);
+ let mut buf = [0; 8];
+ BigEndian::write_uint(&mut buf, n, nbytes);
+ self.put_slice(&buf[0..nbytes])
}
/// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
@@ -979,13 +1009,9 @@ pub unsafe trait BufMut {
/// `self` or if `nbytes` is greater than 8.
#[inline]
fn put_uint_le(&mut self, n: u64, nbytes: usize) {
- let slice = n.to_le_bytes();
- let slice = match slice.get(..nbytes) {
- Some(slice) => slice,
- None => panic_does_not_fit(nbytes, slice.len()),
- };
-
- self.put_slice(slice);
+ let mut buf = [0; 8];
+ LittleEndian::write_uint(&mut buf, n, nbytes);
+ self.put_slice(&buf[0..nbytes])
}
/// Writes an unsigned n-byte integer to `self` in the native-endian byte order.
@@ -1039,12 +1065,9 @@ pub unsafe trait BufMut {
/// `self` or if `nbytes` is greater than 8.
#[inline]
fn put_int(&mut self, n: i64, nbytes: usize) {
- let start = match mem::size_of_val(&n).checked_sub(nbytes) {
- Some(start) => start,
- None => panic_does_not_fit(nbytes, mem::size_of_val(&n)),
- };
-
- self.put_slice(&n.to_be_bytes()[start..]);
+ let mut buf = [0; 8];
+ BigEndian::write_int(&mut buf, n, nbytes);
+ self.put_slice(&buf[0..nbytes])
}
/// Writes low `nbytes` of a signed integer to `self` in little-endian byte order.
@@ -1100,11 +1123,9 @@ pub unsafe trait BufMut {
/// `self` or if `nbytes` is greater than 8.
#[inline]
fn put_int_ne(&mut self, n: i64, nbytes: usize) {
- if cfg!(target_endian = "big") {
- self.put_int(n, nbytes)
- } else {
- self.put_int_le(n, nbytes)
- }
+ let mut buf = [0; 8];
+ LittleEndian::write_int(&mut buf, n, nbytes);
+ self.put_slice(&buf[0..nbytes])
}
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
@@ -1128,7 +1149,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_f32(&mut self, n: f32) {
- self.put_u32(n.to_bits());
+ let mut buf = [0; 4];
+ BigEndian::write_f32(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
@@ -1152,7 +1175,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_f32_le(&mut self, n: f32) {
- self.put_u32_le(n.to_bits());
+ let mut buf = [0; 4];
+ LittleEndian::write_f32(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
@@ -1204,7 +1229,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_f64(&mut self, n: f64) {
- self.put_u64(n.to_bits());
+ let mut buf = [0; 8];
+ BigEndian::write_f64(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
@@ -1228,7 +1255,9 @@ pub unsafe trait BufMut {
/// `self`.
#[inline]
fn put_f64_le(&mut self, n: f64) {
- self.put_u64_le(n.to_bits());
+ let mut buf = [0; 8];
+ LittleEndian::write_f64(&mut buf, n);
+ self.put_slice(&buf)
}
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
--
2.46.0 |
Thank you, we should fix this. Anyone willing to submit a PR? |
I'm looking into it |
paolobarbolini
added a commit
to paolobarbolini/bytes
that referenced
this issue
Aug 19, 2024
Should be fixed in #732 |
paolobarbolini
added a commit
to paolobarbolini/bytes
that referenced
this issue
Aug 19, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Steps to reproduce:
Run the following program, using
bytes
version 1.7.1Expected outcome:
Assertion passes and program terminates successfully, due to the symmetry of the
put_int
andget_int
calls.Actual outcome:
Assertion fails:
Additional information:
nbytes
parameter is < 8.put_i8()
/get_i8()
orput_i16()
/get_i16()
work as intended.The text was updated successfully, but these errors were encountered: