aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Stenger <marvin.stenger94@gmail.com>2017-09-21 18:48:12 +0200
committerRobert Griesemer <gri@golang.org>2017-10-04 17:16:52 +0000
commitaa00c607e1c2e873ef0314eb3d029a4ab3bd7252 (patch)
treee9b0a6bcee747e47857e334e5717b0de86abb886
parent3a35e0253c8344ae4efb975e4bdc0cc53b841e0a (diff)
downloadgo-aa00c607e1c2e873ef0314eb3d029a4ab3bd7252.tar.gz
go-aa00c607e1c2e873ef0314eb3d029a4ab3bd7252.zip
math/big: remove []byte/string conversions
This removes some of the []byte/string conversions currently existing in the (un)marshaling methods of Int and Rat. For Int we introduce a new function (*Int).setFromScanner() essentially implementing the SetString method being given an io.ByteScanner instead of a string. So we can handle the string case in (*Int).SetString with a *strings.Reader and the []byte case in (*Int).UnmarshalText() with a *bytes.Reader now avoiding the []byte/string conversion here. For Rat we introduce a new function (*Rat).marshal() essentially implementing the String method outputting []byte instead of string. Using this new function and the same formatting rules as in (*Rat).RatString we can implement (*Rat).MarshalText() without the []byte/string conversion it used to have. Change-Id: Ic5ef246c1582c428a40f214b95a16671ef0a06d9 Reviewed-on: https://go-review.googlesource.com/65950 Reviewed-by: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/math/big/int.go11
-rw-r--r--src/math/big/intmarsh.go8
-rw-r--r--src/math/big/ratconv.go7
-rw-r--r--src/math/big/ratmarsh.go6
4 files changed, 23 insertions, 9 deletions
diff --git a/src/math/big/int.go b/src/math/big/int.go
index 63a750cb96..000eab50b7 100644
--- a/src/math/big/int.go
+++ b/src/math/big/int.go
@@ -390,15 +390,20 @@ func (x *Int) IsUint64() bool {
// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
//
func (z *Int) SetString(s string, base int) (*Int, bool) {
- r := strings.NewReader(s)
+ return z.setFromScanner(strings.NewReader(s), base)
+}
+
+// setFromScanner implements SetString given an io.BytesScanner.
+// For documentation see comments of SetString.
+func (z *Int) setFromScanner(r io.ByteScanner, base int) (*Int, bool) {
if _, _, err := z.scan(r, base); err != nil {
return nil, false
}
- // entire string must have been consumed
+ // entire content must have been consumed
if _, err := r.ReadByte(); err != io.EOF {
return nil, false
}
- return z, true // err == io.EOF => scan consumed all of s
+ return z, true // err == io.EOF => scan consumed all content of r
}
// SetBytes interprets buf as the bytes of a big-endian unsigned
diff --git a/src/math/big/intmarsh.go b/src/math/big/intmarsh.go
index ee1e4143ed..c1422e2710 100644
--- a/src/math/big/intmarsh.go
+++ b/src/math/big/intmarsh.go
@@ -6,7 +6,10 @@
package big
-import "fmt"
+import (
+ "bytes"
+ "fmt"
+)
// Gob codec version. Permits backward-compatible changes to the encoding.
const intGobVersion byte = 1
@@ -52,8 +55,7 @@ func (x *Int) MarshalText() (text []byte, err error) {
// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (z *Int) UnmarshalText(text []byte) error {
- // TODO(gri): get rid of the []byte/string conversion
- if _, ok := z.SetString(string(text), 0); !ok {
+ if _, ok := z.setFromScanner(bytes.NewReader(text), 0); !ok {
return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
}
return nil
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
index 3b43b19f0e..7aed289218 100644
--- a/src/math/big/ratconv.go
+++ b/src/math/big/ratconv.go
@@ -202,6 +202,11 @@ func scanExponent(r io.ByteScanner, binExpOk bool) (exp int64, base int, err err
// String returns a string representation of x in the form "a/b" (even if b == 1).
func (x *Rat) String() string {
+ return string(x.marshal())
+}
+
+// marshal implements String returning a slice of bytes
+func (x *Rat) marshal() []byte {
var buf []byte
buf = x.a.Append(buf, 10)
buf = append(buf, '/')
@@ -210,7 +215,7 @@ func (x *Rat) String() string {
} else {
buf = append(buf, '1')
}
- return string(buf)
+ return buf
}
// RatString returns a string representation of x in the form "a/b" if b != 1,
diff --git a/src/math/big/ratmarsh.go b/src/math/big/ratmarsh.go
index b82e8d4ae8..fbc7b6002d 100644
--- a/src/math/big/ratmarsh.go
+++ b/src/math/big/ratmarsh.go
@@ -59,8 +59,10 @@ func (z *Rat) GobDecode(buf []byte) error {
// MarshalText implements the encoding.TextMarshaler interface.
func (x *Rat) MarshalText() (text []byte, err error) {
- // TODO(gri): get rid of the []byte/string conversion
- return []byte(x.RatString()), nil
+ if x.IsInt() {
+ return x.a.MarshalText()
+ }
+ return x.marshal(), nil
}
// UnmarshalText implements the encoding.TextUnmarshaler interface.