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
7package big
8
9import (
10	"bytes"
11	"fmt"
12)
13
14// Gob codec version. Permits backward-compatible changes to the encoding.
15const intGobVersion byte = 1
16
17// GobEncode implements the [encoding/gob.GobEncoder] interface.
18func (x *Int) GobEncode() ([]byte, error) {
19	if x == nil {
20		return nil, nil
21	}
22	buf := make([]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.
33func (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// MarshalText implements the [encoding.TextMarshaler] interface.
49func (x *Int) MarshalText() (text []byte, err error) {
50	if x == nil {
51		return []byte("<nil>"), nil
52	}
53	return x.abs.itoa(x.neg, 10), nil
54}
55
56// UnmarshalText implements the [encoding.TextUnmarshaler] interface.
57func (z *Int) UnmarshalText(text []byte) error {
58	if _, ok := z.setFromScanner(bytes.NewReader(text), 0); !ok {
59		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
60	}
61	return nil
62}
63
64// The JSON marshalers are only here for API backward compatibility
65// (programs that explicitly look for these two methods). JSON works
66// fine with the TextMarshaler only.
67
68// MarshalJSON implements the [encoding/json.Marshaler] interface.
69func (x *Int) MarshalJSON() ([]byte, error) {
70	if x == nil {
71		return []byte("null"), nil
72	}
73	return x.abs.itoa(x.neg, 10), nil
74}
75
76// UnmarshalJSON implements the [encoding/json.Unmarshaler] interface.
77func (z *Int) UnmarshalJSON(text []byte) error {
78	// Ignore null, like in the main JSON package.
79	if string(text) == "null" {
80		return nil
81	}
82	return z.UnmarshalText(text)
83}
84