From 436f95462784c3d7a9ac4302bc2b2e34478d8d7e Mon Sep 17 00:00:00 2001 From: gifnksm Date: Tue, 4 Nov 2014 23:20:37 +0900 Subject: [PATCH] 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. --- src/bigint.rs | 95 ++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/src/bigint.rs b/src/bigint.rs index 02bffaa..088672c 100644 --- a/src/bigint.rs +++ b/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,7 +703,39 @@ impl FromStrRadix for BigUint { /// Creates and initializes a `BigUint`. #[inline] fn from_str_radix(s: &str, radix: uint) -> Option { - BigUint::parse_bytes(s.as_bytes(), radix) + 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 = 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 FromStrRadix::from_str_radix(s.slice(start, end), radix) { + Some(d) => { + let d: Option = FromPrimitive::from_uint(d); + match d { + Some(d) => { + // FIXME(#5992): assignment operator overloads + // n += d * power; + n = n + d * power; + } + None => { return None; } + } + } + None => { return None; } + } + if end <= unit_len { + return Some(n); + } + end -= unit_len; + // FIXME(#5992): assignment operator overloads + // power *= base_num; + power = power * base_num; + } } } @@ -728,42 +760,9 @@ impl BigUint { } /// Creates and initializes a `BigUint`. + #[inline] pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { - 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(); - 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) - }) { - Some(d) => { - let d: Option = FromPrimitive::from_uint(d); - match d { - Some(d) => { - // FIXME(#5992): assignment operator overloads - // n += d * power; - n = n + d * power; - } - None => { return None; } - } - } - None => { return None; } - } - if end <= unit_len { - return Some(n); - } - end -= unit_len; - // FIXME(#5992): assignment operator overloads - // power *= base_num; - power = power * base_num; - } + str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix)) } #[inline] @@ -1280,7 +1279,15 @@ impl FromStrRadix for BigInt { /// Creates and initializes a BigInt. #[inline] fn from_str_radix(s: &str, radix: uint) -> Option { - 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 { - 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 {