Browse Source

bigint: Refactor the `parse_bytes` and `from_str_radix`.

This follows the changes of "Separate string->integer implementation in strconv" (rust-lang/rust@138b76b).
This allows `parse_bytes` to be removed without breaking `libnum` code.
gifnksm 10 years ago
parent
commit
436f954627
1 changed files with 44 additions and 43 deletions
  1. 44 43
      src/bigint.rs

+ 44 - 43
src/bigint.rs

@@ -67,7 +67,7 @@ use std::num::{ToPrimitive, FromPrimitive};
 use std::num::{Zero, One, FromStrRadix};
 use std::str;
 use std::string::String;
-use std::{uint, i64, u64};
+use std::{i64, u64};
 
 /// A `BigDigit` is a `BigUint`'s composing element.
 pub type BigDigit = u32;
@@ -703,46 +703,18 @@ impl FromStrRadix for BigUint {
     /// Creates and initializes a `BigUint`.
     #[inline]
     fn from_str_radix(s: &str, radix: uint) -> Option<BigUint> {
-        BigUint::parse_bytes(s.as_bytes(), radix)
-    }
-}
-
-impl BigUint {
-    /// Creates and initializes a `BigUint`.
-    ///
-    /// The digits are be in base 2^32.
-    #[inline]
-    pub fn new(mut digits: Vec<BigDigit>) -> BigUint {
-        // omit trailing zeros
-        let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
-        digits.truncate(new_len);
-        BigUint { data: digits }
-    }
-
-    /// Creates and initializes a `BigUint`.
-    ///
-    /// The digits are be in base 2^32.
-    #[inline]
-    pub fn from_slice(slice: &[BigDigit]) -> BigUint {
-        BigUint::new(slice.to_vec())
-    }
-
-    /// Creates and initializes a `BigUint`.
-    pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
         let (base, unit_len) = get_radix_base(radix);
         let base_num = match base.to_biguint() {
             Some(base_num) => base_num,
             None => { return None; }
         };
 
-        let mut end             = buf.len();
-        let mut n: BigUint      = Zero::zero();
-        let mut power: BigUint  = One::one();
+        let mut end            = s.len();
+        let mut n: BigUint     = Zero::zero();
+        let mut power: BigUint = One::one();
         loop {
             let start = cmp::max(end, unit_len) - unit_len;
-            match str::from_utf8(buf.slice(start, end)).and_then(|s| {
-                FromStrRadix::from_str_radix(s, radix)
-            }) {
+            match FromStrRadix::from_str_radix(s.slice(start, end), radix) {
                 Some(d) => {
                     let d: Option<BigUint> = FromPrimitive::from_uint(d);
                     match d {
@@ -765,6 +737,33 @@ impl BigUint {
             power = power * base_num;
         }
     }
+}
+
+impl BigUint {
+    /// Creates and initializes a `BigUint`.
+    ///
+    /// The digits are be in base 2^32.
+    #[inline]
+    pub fn new(mut digits: Vec<BigDigit>) -> BigUint {
+        // omit trailing zeros
+        let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
+        digits.truncate(new_len);
+        BigUint { data: digits }
+    }
+
+    /// Creates and initializes a `BigUint`.
+    ///
+    /// The digits are be in base 2^32.
+    #[inline]
+    pub fn from_slice(slice: &[BigDigit]) -> BigUint {
+        BigUint::new(slice.to_vec())
+    }
+
+    /// Creates and initializes a `BigUint`.
+    #[inline]
+    pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
+        str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix))
+    }
 
     #[inline]
     fn shl_unit(&self, n_unit: uint) -> BigUint {
@@ -1280,7 +1279,15 @@ impl FromStrRadix for BigInt {
     /// Creates and initializes a BigInt.
     #[inline]
     fn from_str_radix(s: &str, radix: uint) -> Option<BigInt> {
-        BigInt::parse_bytes(s.as_bytes(), radix)
+        if s.is_empty() { return None; }
+        let mut sign  = Plus;
+        let mut start = 0;
+        if s.starts_with("-") {
+            sign  = Minus;
+            start = 1;
+        }
+        FromStrRadix::from_str_radix(s.slice_from(start), radix)
+            .map(|bu| BigInt::from_biguint(sign, bu))
     }
 }
 
@@ -1396,18 +1403,12 @@ impl BigInt {
     }
 
     /// Creates and initializes a `BigInt`.
+    #[inline]
     pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigInt> {
-        if buf.is_empty() { return None; }
-        let mut sign  = Plus;
-        let mut start = 0;
-        if buf[0] == b'-' {
-            sign  = Minus;
-            start = 1;
-        }
-        return BigUint::parse_bytes(buf.slice(start, buf.len()), radix)
-            .map(|bu| BigInt::from_biguint(sign, bu));
+        str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix))
     }
 
+
     /// Converts this `BigInt` into a `BigUint`, if it's not negative.
     #[inline]
     pub fn to_biguint(&self) -> Option<BigUint> {