intmarsh.mx raw
1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file implements encoding/decoding of Ints.
6
7 package big
8
9 import (
10 "bytes"
11 "fmt"
12 )
13
14 // Gob codec version. Permits backward-compatible changes to the encoding.
15 const intGobVersion byte = 1
16
17 // GobEncode implements the [encoding/gob.GobEncoder] interface.
18 func (x *Int) GobEncode() ([]byte, error) {
19 if x == nil {
20 return nil, nil
21 }
22 buf := []byte{:1+len(x.abs)*_S} // extra byte for version and sign bit
23 i := x.abs.bytes(buf) - 1 // i >= 0
24 b := intGobVersion << 1 // make space for sign bit
25 if x.neg {
26 b |= 1
27 }
28 buf[i] = b
29 return buf[i:], nil
30 }
31
32 // GobDecode implements the [encoding/gob.GobDecoder] interface.
33 func (z *Int) GobDecode(buf []byte) error {
34 if len(buf) == 0 {
35 // Other side sent a nil or default value.
36 *z = Int{}
37 return nil
38 }
39 b := buf[0]
40 if b>>1 != intGobVersion {
41 return fmt.Errorf("Int.GobDecode: encoding version %d not supported", b>>1)
42 }
43 z.neg = b&1 != 0
44 z.abs = z.abs.setBytes(buf[1:])
45 return nil
46 }
47
48 // AppendText implements the [encoding.TextAppender] interface.
49 func (x *Int) AppendText(b []byte) (text []byte, err error) {
50 return x.Append(b, 10), nil
51 }
52
53 // MarshalText implements the [encoding.TextMarshaler] interface.
54 func (x *Int) MarshalText() (text []byte, err error) {
55 return x.AppendText(nil)
56 }
57
58 // UnmarshalText implements the [encoding.TextUnmarshaler] interface.
59 func (z *Int) UnmarshalText(text []byte) error {
60 if _, ok := z.setFromScanner(bytes.NewReader(text), 0); !ok {
61 return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
62 }
63 return nil
64 }
65
66 // The JSON marshalers are only here for API backward compatibility
67 // (programs that explicitly look for these two methods). JSON works
68 // fine with the TextMarshaler only.
69
70 // MarshalJSON implements the [encoding/json.Marshaler] interface.
71 func (x *Int) MarshalJSON() ([]byte, error) {
72 if x == nil {
73 return []byte("null"), nil
74 }
75 return x.abs.itoa(x.neg, 10), nil
76 }
77
78 // UnmarshalJSON implements the [encoding/json.Unmarshaler] interface.
79 func (z *Int) UnmarshalJSON(text []byte) error {
80 // Ignore null, like in the main JSON package.
81 if []byte(text) == "null" {
82 return nil
83 }
84 return z.UnmarshalText(text)
85 }
86