mirror of
https://github.com/golang/go
synced 2024-11-20 07:44:41 -07:00
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>
This commit is contained in:
parent
3a35e0253c
commit
aa00c607e1
@ -390,15 +390,20 @@ func (x *Int) IsUint64() bool {
|
|||||||
// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
|
// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
|
||||||
//
|
//
|
||||||
func (z *Int) SetString(s string, base int) (*Int, bool) {
|
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 {
|
if _, _, err := z.scan(r, base); err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
// entire string must have been consumed
|
// entire content must have been consumed
|
||||||
if _, err := r.ReadByte(); err != io.EOF {
|
if _, err := r.ReadByte(); err != io.EOF {
|
||||||
return nil, false
|
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
|
// SetBytes interprets buf as the bytes of a big-endian unsigned
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
|
|
||||||
package big
|
package big
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
// Gob codec version. Permits backward-compatible changes to the encoding.
|
// Gob codec version. Permits backward-compatible changes to the encoding.
|
||||||
const intGobVersion byte = 1
|
const intGobVersion byte = 1
|
||||||
@ -52,8 +55,7 @@ func (x *Int) MarshalText() (text []byte, err error) {
|
|||||||
|
|
||||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||||
func (z *Int) UnmarshalText(text []byte) error {
|
func (z *Int) UnmarshalText(text []byte) error {
|
||||||
// TODO(gri): get rid of the []byte/string conversion
|
if _, ok := z.setFromScanner(bytes.NewReader(text), 0); !ok {
|
||||||
if _, ok := z.SetString(string(text), 0); !ok {
|
|
||||||
return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
|
return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -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).
|
// String returns a string representation of x in the form "a/b" (even if b == 1).
|
||||||
func (x *Rat) String() string {
|
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
|
var buf []byte
|
||||||
buf = x.a.Append(buf, 10)
|
buf = x.a.Append(buf, 10)
|
||||||
buf = append(buf, '/')
|
buf = append(buf, '/')
|
||||||
@ -210,7 +215,7 @@ func (x *Rat) String() string {
|
|||||||
} else {
|
} else {
|
||||||
buf = append(buf, '1')
|
buf = append(buf, '1')
|
||||||
}
|
}
|
||||||
return string(buf)
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
// RatString returns a string representation of x in the form "a/b" if b != 1,
|
// RatString returns a string representation of x in the form "a/b" if b != 1,
|
||||||
|
@ -59,8 +59,10 @@ func (z *Rat) GobDecode(buf []byte) error {
|
|||||||
|
|
||||||
// MarshalText implements the encoding.TextMarshaler interface.
|
// MarshalText implements the encoding.TextMarshaler interface.
|
||||||
func (x *Rat) MarshalText() (text []byte, err error) {
|
func (x *Rat) MarshalText() (text []byte, err error) {
|
||||||
// TODO(gri): get rid of the []byte/string conversion
|
if x.IsInt() {
|
||||||
return []byte(x.RatString()), nil
|
return x.a.MarshalText()
|
||||||
|
}
|
||||||
|
return x.marshal(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||||
|
Loading…
Reference in New Issue
Block a user