github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/src/math/big/ratmarsh.go (about) 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 Rats. 6 7 package big 8 9 import ( 10 "encoding/binary" 11 "errors" 12 "fmt" 13 ) 14 15 // Gob codec version. Permits backward-compatible changes to the encoding. 16 const ratGobVersion byte = 1 17 18 // GobEncode implements the gob.GobEncoder interface. 19 func (x *Rat) GobEncode() ([]byte, error) { 20 if x == nil { 21 return nil, nil 22 } 23 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) 24 i := x.b.abs.bytes(buf) 25 j := x.a.abs.bytes(buf[:i]) 26 n := i - j 27 if int(uint32(n)) != n { 28 // this should never happen 29 return nil, errors.New("Rat.GobEncode: numerator too large") 30 } 31 binary.BigEndian.PutUint32(buf[j-4:j], uint32(n)) 32 j -= 1 + 4 33 b := ratGobVersion << 1 // make space for sign bit 34 if x.a.neg { 35 b |= 1 36 } 37 buf[j] = b 38 return buf[j:], nil 39 } 40 41 // GobDecode implements the gob.GobDecoder interface. 42 func (z *Rat) GobDecode(buf []byte) error { 43 if len(buf) == 0 { 44 // Other side sent a nil or default value. 45 *z = Rat{} 46 return nil 47 } 48 b := buf[0] 49 if b>>1 != ratGobVersion { 50 return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1) 51 } 52 const j = 1 + 4 53 i := j + binary.BigEndian.Uint32(buf[j-4:j]) 54 z.a.neg = b&1 != 0 55 z.a.abs = z.a.abs.setBytes(buf[j:i]) 56 z.b.abs = z.b.abs.setBytes(buf[i:]) 57 return nil 58 } 59 60 // MarshalText implements the encoding.TextMarshaler interface. 61 func (x *Rat) MarshalText() (text []byte, err error) { 62 // TODO(gri): get rid of the []byte/string conversion 63 return []byte(x.RatString()), nil 64 } 65 66 // UnmarshalText implements the encoding.TextUnmarshaler interface. 67 func (z *Rat) UnmarshalText(text []byte) error { 68 // TODO(gri): get rid of the []byte/string conversion 69 if _, ok := z.SetString(string(text)); !ok { 70 return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text) 71 } 72 return nil 73 }