From 7785cde5876d5e4241ff47f3cf964fc5a235b98d Mon Sep 17 00:00:00 2001
From: Ashley Mannix <ashleymannix@live.com.au>
Date: Tue, 19 Jun 2018 10:37:51 +1000
Subject: [PATCH] add support for 128bit numbers (#209)

---
 .travis.yml        |   3 ++
 Cargo.toml         |   8 +++-
 src/buf/buf.rs     |  92 +++++++++++++++++++++++++++++++++++++++
 src/buf/buf_mut.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 206 insertions(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index dbc744e..3deb61f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,6 +36,9 @@ matrix:
     # Serde implementation
     - env: EXTRA_ARGS="--features serde"
 
+    # 128 bit numbers
+    - env: EXTRA_ARGS="--features i128"
+
     # WASM support
     - rust: beta
       script:
diff --git a/Cargo.toml b/Cargo.toml
index c2e509b..fcc7397 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,10 +19,16 @@ exclude       = [
 ]
 categories = ["network-programming", "data-structures"]
 
+[package.metadata.docs.rs]
+features = ["i128"]
+
 [dependencies]
-byteorder = "1.0.0"
+byteorder = "1.1.0"
 iovec = "0.1"
 serde = { version = "1.0", optional = true }
 
 [dev-dependencies]
 serde_test = "1.0"
+
+[features]
+i128 = ["byteorder/i128"]
diff --git a/src/buf/buf.rs b/src/buf/buf.rs
index 73baeef..b72c8d9 100644
--- a/src/buf/buf.rs
+++ b/src/buf/buf.rs
@@ -605,6 +605,98 @@ pub trait Buf {
         buf_get_impl!(self, 8, LittleEndian::read_i64);
     }
 
+    /// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    /// use std::io::Cursor;
+    ///
+    /// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_be());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    #[cfg(feature = "i128")]
+    fn get_u128_be(&mut self) -> u128 {
+        buf_get_impl!(self, 16, BigEndian::read_u128);
+    }
+
+    /// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    /// use std::io::Cursor;
+    ///
+    /// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello");
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    #[cfg(feature = "i128")]
+    fn get_u128_le(&mut self) -> u128 {
+        buf_get_impl!(self, 16, LittleEndian::read_u128);
+    }
+
+    /// Gets a signed 128 bit integer from `self` in big-endian byte order.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    /// use std::io::Cursor;
+    ///
+    /// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello");
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_be());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    #[cfg(feature = "i128")]
+    fn get_i128_be(&mut self) -> i128 {
+        buf_get_impl!(self, 16, BigEndian::read_i128);
+    }
+
+    /// Gets a signed 128 bit integer from `self` in little-endian byte order.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    /// use std::io::Cursor;
+    ///
+    /// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello");
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    #[cfg(feature = "i128")]
+    fn get_i128_le(&mut self) -> i128 {
+        buf_get_impl!(self, 16, LittleEndian::read_i128);
+    }
+
     #[doc(hidden)]
     #[deprecated(note="use get_uint_be or get_uint_le")]
     fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 where Self: Sized {
diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs
index f9323ed..71dbda9 100644
--- a/src/buf/buf_mut.rs
+++ b/src/buf/buf_mut.rs
@@ -674,6 +674,110 @@ pub trait BufMut {
         self.put_slice(&buf)
     }
 
+    /// Writes an unsigned 128 bit integer to `self` in the big-endian byte order.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u128_be(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[cfg(feature = "i128")]
+    fn put_u128_be(&mut self, n: u128) {
+        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.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u128_le(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[cfg(feature = "i128")]
+    fn put_u128_le(&mut self, n: u128) {
+        let mut buf = [0; 16];
+        LittleEndian::write_u128(&mut buf, n);
+        self.put_slice(&buf)
+    }
+
+    /// Writes a signed 128 bit integer to `self` in the big-endian byte order.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i128_be(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[cfg(feature = "i128")]
+    fn put_i128_be(&mut self, n: i128) {
+        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.
+    ///
+    /// **NOTE:** This method requires the `i128` feature.
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i128_le(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[cfg(feature = "i128")]
+    fn put_i128_le(&mut self, n: i128) {
+        let mut buf = [0; 16];
+        LittleEndian::write_i128(&mut buf, n);
+        self.put_slice(&buf)
+    }
+
     #[doc(hidden)]
     #[deprecated(note="use put_uint_be or put_uint_le")]
     fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) where Self: Sized {
-- 
GitLab