From: Robert Griesemer Date: Fri, 25 Sep 2015 21:56:19 +0000 (-0700) Subject: math/big: move Int/Rat gob/json/xml functionality in separate files X-Git-Tag: go1.6beta1~975 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7fa5a11ea1e876bd9d72b0ed2e2821597f76a495;p=gostls13.git math/big: move Int/Rat gob/json/xml functionality in separate files Like int/rat/float conversions, move this functionality into separate implementation and test files. No implementation changes besides the move. Change-Id: If19c45f5a72a57b95cbce2329724693ae5a4807d Reviewed-on: https://go-review.googlesource.com/14997 Reviewed-by: Alan Donovan --- diff --git a/src/math/big/int.go b/src/math/big/int.go index 84485a2750..ac5c1f0224 100644 --- a/src/math/big/int.go +++ b/src/math/big/int.go @@ -929,65 +929,3 @@ func (z *Int) Not(x *Int) *Int { z.neg = true // z cannot be zero if x is positive return z } - -// Gob codec version. Permits backward-compatible changes to the encoding. -const intGobVersion byte = 1 - -// GobEncode implements the gob.GobEncoder interface. -func (x *Int) GobEncode() ([]byte, error) { - if x == nil { - return nil, nil - } - buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit - i := x.abs.bytes(buf) - 1 // i >= 0 - b := intGobVersion << 1 // make space for sign bit - if x.neg { - b |= 1 - } - buf[i] = b - return buf[i:], nil -} - -// GobDecode implements the gob.GobDecoder interface. -func (z *Int) GobDecode(buf []byte) error { - if len(buf) == 0 { - // Other side sent a nil or default value. - *z = Int{} - return nil - } - b := buf[0] - if b>>1 != intGobVersion { - return fmt.Errorf("Int.GobDecode: encoding version %d not supported", b>>1) - } - z.neg = b&1 != 0 - z.abs = z.abs.setBytes(buf[1:]) - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (z *Int) MarshalJSON() ([]byte, error) { - // TODO(gri): get rid of the []byte/string conversions - return []byte(z.String()), nil -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (z *Int) UnmarshalJSON(text []byte) error { - // TODO(gri): get rid of the []byte/string conversions - if _, ok := z.SetString(string(text), 0); !ok { - return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text) - } - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (z *Int) MarshalText() (text []byte, err error) { - return []byte(z.String()), nil -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (z *Int) UnmarshalText(text []byte) error { - if _, ok := z.SetString(string(text), 0); !ok { - return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text) - } - return nil -} diff --git a/src/math/big/int_test.go b/src/math/big/int_test.go index 5b80509a31..72c2c985c5 100644 --- a/src/math/big/int_test.go +++ b/src/math/big/int_test.go @@ -6,10 +6,7 @@ package big import ( "bytes" - "encoding/gob" "encoding/hex" - "encoding/json" - "encoding/xml" "fmt" "math/rand" "testing" @@ -1453,138 +1450,6 @@ func TestJacobiPanic(t *testing.T) { panic(failureMsg) } -var encodingTests = []string{ - "-539345864568634858364538753846587364875430589374589", - "-678645873", - "-100", - "-2", - "-1", - "0", - "1", - "2", - "10", - "42", - "1234567890", - "298472983472983471903246121093472394872319615612417471234712061", -} - -func TestIntGobEncoding(t *testing.T) { - var medium bytes.Buffer - enc := gob.NewEncoder(&medium) - dec := gob.NewDecoder(&medium) - for _, test := range encodingTests { - medium.Reset() // empty buffer for each test case (in case of failures) - var tx Int - tx.SetString(test, 10) - if err := enc.Encode(&tx); err != nil { - t.Errorf("encoding of %s failed: %s", &tx, err) - } - var rx Int - if err := dec.Decode(&rx); err != nil { - t.Errorf("decoding of %s failed: %s", &tx, err) - } - if rx.Cmp(&tx) != 0 { - t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx) - } - } -} - -// Sending a nil Int pointer (inside a slice) on a round trip through gob should yield a zero. -// TODO: top-level nils. -func TestGobEncodingNilIntInSlice(t *testing.T) { - buf := new(bytes.Buffer) - enc := gob.NewEncoder(buf) - dec := gob.NewDecoder(buf) - - var in = make([]*Int, 1) - err := enc.Encode(&in) - if err != nil { - t.Errorf("gob encode failed: %q", err) - } - var out []*Int - err = dec.Decode(&out) - if err != nil { - t.Fatalf("gob decode failed: %q", err) - } - if len(out) != 1 { - t.Fatalf("wrong len; want 1 got %d", len(out)) - } - var zero Int - if out[0].Cmp(&zero) != 0 { - t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out) - } -} - -func TestIntJSONEncoding(t *testing.T) { - 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) - } - } -} - -var intVals = []string{ - "-141592653589793238462643383279502884197169399375105820974944592307816406286", - "-1415926535897932384626433832795028841971", - "-141592653589793", - "-1", - "0", - "1", - "141592653589793", - "1415926535897932384626433832795028841971", - "141592653589793238462643383279502884197169399375105820974944592307816406286", -} - -func TestIntJSONEncodingTextMarshaller(t *testing.T) { - for _, num := range intVals { - var tx Int - tx.SetString(num, 0) - b, err := json.Marshal(&tx) - if err != nil { - t.Errorf("marshaling of %s failed: %s", &tx, err) - continue - } - var rx Int - if err := json.Unmarshal(b, &rx); err != nil { - t.Errorf("unmarshaling of %s failed: %s", &tx, err) - continue - } - if rx.Cmp(&tx) != 0 { - t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx) - } - } -} - -func TestIntXMLEncodingTextMarshaller(t *testing.T) { - for _, num := range intVals { - var tx Int - tx.SetString(num, 0) - b, err := xml.Marshal(&tx) - if err != nil { - t.Errorf("marshaling of %s failed: %s", &tx, err) - continue - } - var rx Int - if err := xml.Unmarshal(b, &rx); err != nil { - t.Errorf("unmarshaling of %s failed: %s", &tx, err) - continue - } - if rx.Cmp(&tx) != 0 { - t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx) - } - } -} - func TestIssue2607(t *testing.T) { // This code sequence used to hang. n := NewInt(10) diff --git a/src/math/big/intmarsh.go b/src/math/big/intmarsh.go new file mode 100644 index 0000000000..3c1efec8de --- /dev/null +++ b/src/math/big/intmarsh.go @@ -0,0 +1,71 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements encoding/decoding of Ints. + +package big + +import "fmt" + +// Gob codec version. Permits backward-compatible changes to the encoding. +const intGobVersion byte = 1 + +// GobEncode implements the gob.GobEncoder interface. +func (x *Int) GobEncode() ([]byte, error) { + if x == nil { + return nil, nil + } + buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit + i := x.abs.bytes(buf) - 1 // i >= 0 + b := intGobVersion << 1 // make space for sign bit + if x.neg { + b |= 1 + } + buf[i] = b + return buf[i:], nil +} + +// GobDecode implements the gob.GobDecoder interface. +func (z *Int) GobDecode(buf []byte) error { + if len(buf) == 0 { + // Other side sent a nil or default value. + *z = Int{} + return nil + } + b := buf[0] + if b>>1 != intGobVersion { + return fmt.Errorf("Int.GobDecode: encoding version %d not supported", b>>1) + } + z.neg = b&1 != 0 + z.abs = z.abs.setBytes(buf[1:]) + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (z *Int) MarshalJSON() ([]byte, error) { + // TODO(gri): get rid of the []byte/string conversions + return []byte(z.String()), nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (z *Int) UnmarshalJSON(text []byte) error { + // TODO(gri): get rid of the []byte/string conversions + if _, ok := z.SetString(string(text), 0); !ok { + return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text) + } + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (z *Int) MarshalText() (text []byte, err error) { + return []byte(z.String()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (z *Int) UnmarshalText(text []byte) error { + if _, ok := z.SetString(string(text), 0); !ok { + return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text) + } + return nil +} diff --git a/src/math/big/intmarsh_test.go b/src/math/big/intmarsh_test.go new file mode 100644 index 0000000000..c992f1c915 --- /dev/null +++ b/src/math/big/intmarsh_test.go @@ -0,0 +1,145 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package big + +import ( + "bytes" + "encoding/gob" + "encoding/json" + "encoding/xml" + "testing" +) + +var encodingTests = []string{ + "-539345864568634858364538753846587364875430589374589", + "-678645873", + "-100", + "-2", + "-1", + "0", + "1", + "2", + "10", + "42", + "1234567890", + "298472983472983471903246121093472394872319615612417471234712061", +} + +func TestIntGobEncoding(t *testing.T) { + var medium bytes.Buffer + enc := gob.NewEncoder(&medium) + dec := gob.NewDecoder(&medium) + for _, test := range encodingTests { + medium.Reset() // empty buffer for each test case (in case of failures) + var tx Int + tx.SetString(test, 10) + if err := enc.Encode(&tx); err != nil { + t.Errorf("encoding of %s failed: %s", &tx, err) + } + var rx Int + if err := dec.Decode(&rx); err != nil { + t.Errorf("decoding of %s failed: %s", &tx, err) + } + if rx.Cmp(&tx) != 0 { + t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx) + } + } +} + +// Sending a nil Int pointer (inside a slice) on a round trip through gob should yield a zero. +// TODO: top-level nils. +func TestGobEncodingNilIntInSlice(t *testing.T) { + buf := new(bytes.Buffer) + enc := gob.NewEncoder(buf) + dec := gob.NewDecoder(buf) + + var in = make([]*Int, 1) + err := enc.Encode(&in) + if err != nil { + t.Errorf("gob encode failed: %q", err) + } + var out []*Int + err = dec.Decode(&out) + if err != nil { + t.Fatalf("gob decode failed: %q", err) + } + if len(out) != 1 { + t.Fatalf("wrong len; want 1 got %d", len(out)) + } + var zero Int + if out[0].Cmp(&zero) != 0 { + t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out) + } +} + +func TestIntJSONEncoding(t *testing.T) { + 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) + } + } +} + +var intVals = []string{ + "-141592653589793238462643383279502884197169399375105820974944592307816406286", + "-1415926535897932384626433832795028841971", + "-141592653589793", + "-1", + "0", + "1", + "141592653589793", + "1415926535897932384626433832795028841971", + "141592653589793238462643383279502884197169399375105820974944592307816406286", +} + +func TestIntJSONEncodingTextMarshaller(t *testing.T) { + for _, num := range intVals { + var tx Int + tx.SetString(num, 0) + b, err := json.Marshal(&tx) + if err != nil { + t.Errorf("marshaling of %s failed: %s", &tx, err) + continue + } + var rx Int + if err := json.Unmarshal(b, &rx); err != nil { + t.Errorf("unmarshaling of %s failed: %s", &tx, err) + continue + } + if rx.Cmp(&tx) != 0 { + t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx) + } + } +} + +func TestIntXMLEncodingTextMarshaller(t *testing.T) { + for _, num := range intVals { + var tx Int + tx.SetString(num, 0) + b, err := xml.Marshal(&tx) + if err != nil { + t.Errorf("marshaling of %s failed: %s", &tx, err) + continue + } + var rx Int + if err := xml.Unmarshal(b, &rx); err != nil { + t.Errorf("unmarshaling of %s failed: %s", &tx, err) + continue + } + if rx.Cmp(&tx) != 0 { + t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx) + } + } +} diff --git a/src/math/big/rat.go b/src/math/big/rat.go index fb16f18a96..2cd9ed0938 100644 --- a/src/math/big/rat.go +++ b/src/math/big/rat.go @@ -7,8 +7,6 @@ package big import ( - "encoding/binary" - "errors" "fmt" "math" ) @@ -510,61 +508,3 @@ func (z *Rat) Quo(x, y *Rat) *Rat { z.a.neg = a.neg != b.neg return z.norm() } - -// Gob codec version. Permits backward-compatible changes to the encoding. -const ratGobVersion byte = 1 - -// GobEncode implements the gob.GobEncoder interface. -func (x *Rat) GobEncode() ([]byte, error) { - if x == nil { - return nil, nil - } - buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S) // extra bytes for version and sign bit (1), and numerator length (4) - i := x.b.abs.bytes(buf) - j := x.a.abs.bytes(buf[:i]) - n := i - j - if int(uint32(n)) != n { - // this should never happen - return nil, errors.New("Rat.GobEncode: numerator too large") - } - binary.BigEndian.PutUint32(buf[j-4:j], uint32(n)) - j -= 1 + 4 - b := ratGobVersion << 1 // make space for sign bit - if x.a.neg { - b |= 1 - } - buf[j] = b - return buf[j:], nil -} - -// GobDecode implements the gob.GobDecoder interface. -func (z *Rat) GobDecode(buf []byte) error { - if len(buf) == 0 { - // Other side sent a nil or default value. - *z = Rat{} - return nil - } - b := buf[0] - if b>>1 != ratGobVersion { - return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1) - } - const j = 1 + 4 - i := j + binary.BigEndian.Uint32(buf[j-4:j]) - z.a.neg = b&1 != 0 - z.a.abs = z.a.abs.setBytes(buf[j:i]) - z.b.abs = z.b.abs.setBytes(buf[i:]) - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (r *Rat) MarshalText() (text []byte, err error) { - return []byte(r.RatString()), nil -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (r *Rat) UnmarshalText(text []byte) error { - if _, ok := r.SetString(string(text)); !ok { - return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text) - } - return nil -} diff --git a/src/math/big/rat_test.go b/src/math/big/rat_test.go index 012d0c47ec..3a06fca3c3 100644 --- a/src/math/big/rat_test.go +++ b/src/math/big/rat_test.go @@ -5,10 +5,6 @@ package big import ( - "bytes" - "encoding/gob" - "encoding/json" - "encoding/xml" "math" "testing" ) @@ -280,116 +276,6 @@ func TestRatSetFrac64Rat(t *testing.T) { } } -func TestRatGobEncoding(t *testing.T) { - var medium bytes.Buffer - enc := gob.NewEncoder(&medium) - dec := gob.NewDecoder(&medium) - for _, test := range encodingTests { - medium.Reset() // empty buffer for each test case (in case of failures) - var tx Rat - tx.SetString(test + ".14159265") - if err := enc.Encode(&tx); err != nil { - t.Errorf("encoding of %s failed: %s", &tx, err) - } - var rx Rat - if err := dec.Decode(&rx); err != nil { - t.Errorf("decoding of %s failed: %s", &tx, err) - } - if rx.Cmp(&tx) != 0 { - t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx) - } - } -} - -// Sending a nil Rat pointer (inside a slice) on a round trip through gob should yield a zero. -// TODO: top-level nils. -func TestGobEncodingNilRatInSlice(t *testing.T) { - buf := new(bytes.Buffer) - enc := gob.NewEncoder(buf) - dec := gob.NewDecoder(buf) - - var in = make([]*Rat, 1) - err := enc.Encode(&in) - if err != nil { - t.Errorf("gob encode failed: %q", err) - } - var out []*Rat - err = dec.Decode(&out) - if err != nil { - t.Fatalf("gob decode failed: %q", err) - } - if len(out) != 1 { - t.Fatalf("wrong len; want 1 got %d", len(out)) - } - var zero Rat - if out[0].Cmp(&zero) != 0 { - t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out) - } -} - -var ratNums = []string{ - "-141592653589793238462643383279502884197169399375105820974944592307816406286", - "-1415926535897932384626433832795028841971", - "-141592653589793", - "-1", - "0", - "1", - "141592653589793", - "1415926535897932384626433832795028841971", - "141592653589793238462643383279502884197169399375105820974944592307816406286", -} - -var ratDenoms = []string{ - "1", - "718281828459045", - "7182818284590452353602874713526624977572", - "718281828459045235360287471352662497757247093699959574966967627724076630353", -} - -func TestRatJSONEncoding(t *testing.T) { - for _, num := range ratNums { - for _, denom := range ratDenoms { - var tx Rat - tx.SetString(num + "/" + denom) - b, err := json.Marshal(&tx) - if err != nil { - t.Errorf("marshaling of %s failed: %s", &tx, err) - continue - } - var rx Rat - if err := json.Unmarshal(b, &rx); err != nil { - t.Errorf("unmarshaling of %s failed: %s", &tx, err) - continue - } - if rx.Cmp(&tx) != 0 { - t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx) - } - } - } -} - -func TestRatXMLEncoding(t *testing.T) { - for _, num := range ratNums { - for _, denom := range ratDenoms { - var tx Rat - tx.SetString(num + "/" + denom) - b, err := xml.Marshal(&tx) - if err != nil { - t.Errorf("marshaling of %s failed: %s", &tx, err) - continue - } - var rx Rat - if err := xml.Unmarshal(b, &rx); err != nil { - t.Errorf("unmarshaling of %s failed: %s", &tx, err) - continue - } - if rx.Cmp(&tx) != 0 { - t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx) - } - } - } -} - func TestIssue2379(t *testing.T) { // 1) no aliasing q := NewRat(3, 2) diff --git a/src/math/big/ratmarsh.go b/src/math/big/ratmarsh.go new file mode 100644 index 0000000000..b79cbe6652 --- /dev/null +++ b/src/math/big/ratmarsh.go @@ -0,0 +1,71 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements encoding/decoding of Rats. + +package big + +import ( + "encoding/binary" + "errors" + "fmt" +) + +// Gob codec version. Permits backward-compatible changes to the encoding. +const ratGobVersion byte = 1 + +// GobEncode implements the gob.GobEncoder interface. +func (x *Rat) GobEncode() ([]byte, error) { + if x == nil { + return nil, nil + } + buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S) // extra bytes for version and sign bit (1), and numerator length (4) + i := x.b.abs.bytes(buf) + j := x.a.abs.bytes(buf[:i]) + n := i - j + if int(uint32(n)) != n { + // this should never happen + return nil, errors.New("Rat.GobEncode: numerator too large") + } + binary.BigEndian.PutUint32(buf[j-4:j], uint32(n)) + j -= 1 + 4 + b := ratGobVersion << 1 // make space for sign bit + if x.a.neg { + b |= 1 + } + buf[j] = b + return buf[j:], nil +} + +// GobDecode implements the gob.GobDecoder interface. +func (z *Rat) GobDecode(buf []byte) error { + if len(buf) == 0 { + // Other side sent a nil or default value. + *z = Rat{} + return nil + } + b := buf[0] + if b>>1 != ratGobVersion { + return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1) + } + const j = 1 + 4 + i := j + binary.BigEndian.Uint32(buf[j-4:j]) + z.a.neg = b&1 != 0 + z.a.abs = z.a.abs.setBytes(buf[j:i]) + z.b.abs = z.b.abs.setBytes(buf[i:]) + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (r *Rat) MarshalText() (text []byte, err error) { + return []byte(r.RatString()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (r *Rat) UnmarshalText(text []byte) error { + if _, ok := r.SetString(string(text)); !ok { + return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text) + } + return nil +} diff --git a/src/math/big/ratmarsh_test.go b/src/math/big/ratmarsh_test.go new file mode 100644 index 0000000000..2e91e38e11 --- /dev/null +++ b/src/math/big/ratmarsh_test.go @@ -0,0 +1,123 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package big + +import ( + "bytes" + "encoding/gob" + "encoding/json" + "encoding/xml" + "testing" +) + +func TestRatGobEncoding(t *testing.T) { + var medium bytes.Buffer + enc := gob.NewEncoder(&medium) + dec := gob.NewDecoder(&medium) + for _, test := range encodingTests { + medium.Reset() // empty buffer for each test case (in case of failures) + var tx Rat + tx.SetString(test + ".14159265") + if err := enc.Encode(&tx); err != nil { + t.Errorf("encoding of %s failed: %s", &tx, err) + } + var rx Rat + if err := dec.Decode(&rx); err != nil { + t.Errorf("decoding of %s failed: %s", &tx, err) + } + if rx.Cmp(&tx) != 0 { + t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx) + } + } +} + +// Sending a nil Rat pointer (inside a slice) on a round trip through gob should yield a zero. +// TODO: top-level nils. +func TestGobEncodingNilRatInSlice(t *testing.T) { + buf := new(bytes.Buffer) + enc := gob.NewEncoder(buf) + dec := gob.NewDecoder(buf) + + var in = make([]*Rat, 1) + err := enc.Encode(&in) + if err != nil { + t.Errorf("gob encode failed: %q", err) + } + var out []*Rat + err = dec.Decode(&out) + if err != nil { + t.Fatalf("gob decode failed: %q", err) + } + if len(out) != 1 { + t.Fatalf("wrong len; want 1 got %d", len(out)) + } + var zero Rat + if out[0].Cmp(&zero) != 0 { + t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out) + } +} + +var ratNums = []string{ + "-141592653589793238462643383279502884197169399375105820974944592307816406286", + "-1415926535897932384626433832795028841971", + "-141592653589793", + "-1", + "0", + "1", + "141592653589793", + "1415926535897932384626433832795028841971", + "141592653589793238462643383279502884197169399375105820974944592307816406286", +} + +var ratDenoms = []string{ + "1", + "718281828459045", + "7182818284590452353602874713526624977572", + "718281828459045235360287471352662497757247093699959574966967627724076630353", +} + +func TestRatJSONEncoding(t *testing.T) { + for _, num := range ratNums { + for _, denom := range ratDenoms { + var tx Rat + tx.SetString(num + "/" + denom) + b, err := json.Marshal(&tx) + if err != nil { + t.Errorf("marshaling of %s failed: %s", &tx, err) + continue + } + var rx Rat + if err := json.Unmarshal(b, &rx); err != nil { + t.Errorf("unmarshaling of %s failed: %s", &tx, err) + continue + } + if rx.Cmp(&tx) != 0 { + t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx) + } + } + } +} + +func TestRatXMLEncoding(t *testing.T) { + for _, num := range ratNums { + for _, denom := range ratDenoms { + var tx Rat + tx.SetString(num + "/" + denom) + b, err := xml.Marshal(&tx) + if err != nil { + t.Errorf("marshaling of %s failed: %s", &tx, err) + continue + } + var rx Rat + if err := xml.Unmarshal(b, &rx); err != nil { + t.Errorf("unmarshaling of %s failed: %s", &tx, err) + continue + } + if rx.Cmp(&tx) != 0 { + t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx) + } + } + } +}