mirror of
https://github.com/golang/go
synced 2024-11-20 02:54:39 -07:00
math/big: implement JSON un/marshaling support for Ints
Also: simplified some existing tests. No support for Rats for now because the precision-preserving default notation (fractions of the form a/b) is not a valid JSON value. Fixes #3657. R=golang-dev, bradfitz, rsc CC=golang-dev https://golang.org/cl/6211079
This commit is contained in:
parent
4f7c33cd5a
commit
13a59b8c6d
@ -894,3 +894,19 @@ func (z *Int) GobDecode(buf []byte) error {
|
|||||||
z.abs = z.abs.setBytes(buf[1:])
|
z.abs = z.abs.setBytes(buf[1:])
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements the json.Marshaler interface.
|
||||||
|
func (x *Int) MarshalJSON() ([]byte, error) {
|
||||||
|
// TODO(gri): get rid of the []byte/string conversions
|
||||||
|
return []byte(x.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||||
|
func (z *Int) UnmarshalJSON(x []byte) error {
|
||||||
|
// TODO(gri): get rid of the []byte/string conversions
|
||||||
|
_, ok := z.SetString(string(x), 0)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("math/big: cannot unmarshal %s into a *big.Int", x)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
@ -1368,8 +1369,12 @@ func TestModInverse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by TestIntGobEncoding and TestRatGobEncoding
|
var encodingTests = []string{
|
||||||
var gobEncodingTests = []string{
|
"-539345864568634858364538753846587364875430589374589",
|
||||||
|
"-678645873",
|
||||||
|
"-100",
|
||||||
|
"-2",
|
||||||
|
"-1",
|
||||||
"0",
|
"0",
|
||||||
"1",
|
"1",
|
||||||
"2",
|
"2",
|
||||||
@ -1383,26 +1388,37 @@ func TestIntGobEncoding(t *testing.T) {
|
|||||||
var medium bytes.Buffer
|
var medium bytes.Buffer
|
||||||
enc := gob.NewEncoder(&medium)
|
enc := gob.NewEncoder(&medium)
|
||||||
dec := gob.NewDecoder(&medium)
|
dec := gob.NewDecoder(&medium)
|
||||||
for i, test := range gobEncodingTests {
|
for _, test := range encodingTests {
|
||||||
for j := 0; j < 2; j++ {
|
medium.Reset() // empty buffer for each test case (in case of failures)
|
||||||
medium.Reset() // empty buffer for each test case (in case of failures)
|
var tx Int
|
||||||
stest := test
|
tx.SetString(test, 10)
|
||||||
if j != 0 {
|
if err := enc.Encode(&tx); err != nil {
|
||||||
// negative numbers
|
t.Errorf("encoding of %s failed: %s", &tx, err)
|
||||||
stest = "-" + test
|
}
|
||||||
}
|
var rx Int
|
||||||
var tx Int
|
if err := dec.Decode(&rx); err != nil {
|
||||||
tx.SetString(stest, 10)
|
t.Errorf("decoding of %s failed: %s", &tx, err)
|
||||||
if err := enc.Encode(&tx); err != nil {
|
}
|
||||||
t.Errorf("#%d%c: encoding failed: %s", i, 'a'+j, err)
|
if rx.Cmp(&tx) != 0 {
|
||||||
}
|
t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
|
||||||
var rx Int
|
}
|
||||||
if err := dec.Decode(&rx); err != nil {
|
}
|
||||||
t.Errorf("#%d%c: decoding failed: %s", i, 'a'+j, err)
|
}
|
||||||
}
|
|
||||||
if rx.Cmp(&tx) != 0 {
|
func TestIntJSONEncoding(t *testing.T) {
|
||||||
t.Errorf("#%d%c: transmission failed: got %s want %s", i, 'a'+j, &rx, &tx)
|
for _, test := range encodingTests {
|
||||||
}
|
var tx Int
|
||||||
|
tx.SetString(test, 10)
|
||||||
|
b, err := json.Marshal(&tx)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("marshaling of %s failed: %s", &tx, err)
|
||||||
|
}
|
||||||
|
var rx Int
|
||||||
|
if err := json.Unmarshal(b, &rx); err != nil {
|
||||||
|
t.Errorf("unmarshaling of %s failed: %s", &tx, err)
|
||||||
|
}
|
||||||
|
if rx.Cmp(&tx) != 0 {
|
||||||
|
t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,30 +387,19 @@ func TestRatGobEncoding(t *testing.T) {
|
|||||||
var medium bytes.Buffer
|
var medium bytes.Buffer
|
||||||
enc := gob.NewEncoder(&medium)
|
enc := gob.NewEncoder(&medium)
|
||||||
dec := gob.NewDecoder(&medium)
|
dec := gob.NewDecoder(&medium)
|
||||||
for i, test := range gobEncodingTests {
|
for _, test := range encodingTests {
|
||||||
for j := 0; j < 4; j++ {
|
medium.Reset() // empty buffer for each test case (in case of failures)
|
||||||
medium.Reset() // empty buffer for each test case (in case of failures)
|
var tx Rat
|
||||||
stest := test
|
tx.SetString(test + ".14159265")
|
||||||
if j&1 != 0 {
|
if err := enc.Encode(&tx); err != nil {
|
||||||
// negative numbers
|
t.Errorf("encoding of %s failed: %s", &tx, err)
|
||||||
stest = "-" + test
|
}
|
||||||
}
|
var rx Rat
|
||||||
if j%2 != 0 {
|
if err := dec.Decode(&rx); err != nil {
|
||||||
// fractions
|
t.Errorf("decoding of %s failed: %s", &tx, err)
|
||||||
stest = stest + "." + test
|
}
|
||||||
}
|
if rx.Cmp(&tx) != 0 {
|
||||||
var tx Rat
|
t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
|
||||||
tx.SetString(stest)
|
|
||||||
if err := enc.Encode(&tx); err != nil {
|
|
||||||
t.Errorf("#%d%c: encoding failed: %s", i, 'a'+j, err)
|
|
||||||
}
|
|
||||||
var rx Rat
|
|
||||||
if err := dec.Decode(&rx); err != nil {
|
|
||||||
t.Errorf("#%d%c: decoding failed: %s", i, 'a'+j, err)
|
|
||||||
}
|
|
||||||
if rx.Cmp(&tx) != 0 {
|
|
||||||
t.Errorf("#%d%c: transmission failed: got %s want %s", i, 'a'+j, &rx, &tx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user