Source file src/math/big/intmarsh.go

     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 := 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.
    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  // MarshalText implements the [encoding.TextMarshaler] interface.
    49  func (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.
    57  func (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.
    69  func (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.
    77  func (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  

View as plain text