]> Cypherpunks.ru repositories - gostls13.git/commitdiff
math/big: remove []byte/string conversions
authorMarvin Stenger <marvin.stenger94@gmail.com>
Thu, 21 Sep 2017 16:48:12 +0000 (18:48 +0200)
committerRobert Griesemer <gri@golang.org>
Wed, 4 Oct 2017 17:16:52 +0000 (17:16 +0000)
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>

src/math/big/int.go
src/math/big/intmarsh.go
src/math/big/ratconv.go
src/math/big/ratmarsh.go

index 63a750cb96907eee9fd8dfe12d9616718964a390..000eab50b787daa0ca6bd30779da23d4e12ad450 100644 (file)
@@ -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
index ee1e4143ed9c824648b9f5b5ee73e7a093db3c52..c1422e271072063f88254258673e50db92707e11 100644 (file)
@@ -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
index 3b43b19f0e3b0f656f1b72d044fb38b466662de0..7aed289218c156809342a80a1cc5a355b2e1c587 100644 (file)
@@ -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,
index b82e8d4ae8d9ed7b8a71afb82efa8fa505410f28..fbc7b6002d9509459d2c5bc7f5bf2b86564d4810 100644 (file)
@@ -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.