Source file
src/math/big/ratmarsh.go
1
2
3
4
5
6
7 package big
8
9 import (
10 "errors"
11 "fmt"
12 "internal/byteorder"
13 "math"
14 )
15
16
17 const ratGobVersion byte = 1
18
19
20 func (x *Rat) GobEncode() ([]byte, error) {
21 if x == nil {
22 return nil, nil
23 }
24 buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S)
25 i := x.b.abs.bytes(buf)
26 j := x.a.abs.bytes(buf[:i])
27 n := i - j
28 if int(uint32(n)) != n {
29
30 return nil, errors.New("Rat.GobEncode: numerator too large")
31 }
32 byteorder.BePutUint32(buf[j-4:j], uint32(n))
33 j -= 1 + 4
34 b := ratGobVersion << 1
35 if x.a.neg {
36 b |= 1
37 }
38 buf[j] = b
39 return buf[j:], nil
40 }
41
42
43 func (z *Rat) GobDecode(buf []byte) error {
44 if len(buf) == 0 {
45
46 *z = Rat{}
47 return nil
48 }
49 if len(buf) < 5 {
50 return errors.New("Rat.GobDecode: buffer too small")
51 }
52 b := buf[0]
53 if b>>1 != ratGobVersion {
54 return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
55 }
56 const j = 1 + 4
57 ln := byteorder.BeUint32(buf[j-4 : j])
58 if uint64(ln) > math.MaxInt-j {
59 return errors.New("Rat.GobDecode: invalid length")
60 }
61 i := j + int(ln)
62 if len(buf) < i {
63 return errors.New("Rat.GobDecode: buffer too small")
64 }
65 z.a.neg = b&1 != 0
66 z.a.abs = z.a.abs.setBytes(buf[j:i])
67 z.b.abs = z.b.abs.setBytes(buf[i:])
68 return nil
69 }
70
71
72 func (x *Rat) AppendText(b []byte) ([]byte, error) {
73 if x.IsInt() {
74 return x.a.AppendText(b)
75 }
76 return x.marshal(b), nil
77 }
78
79
80 func (x *Rat) MarshalText() (text []byte, err error) {
81 return x.AppendText(nil)
82 }
83
84
85 func (z *Rat) UnmarshalText(text []byte) error {
86
87 if _, ok := z.SetString(string(text)); !ok {
88 return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text)
89 }
90 return nil
91 }
92
View as plain text