github.com/gagliardetto/binary@v0.7.9/u128.go (about)

     1  // Copyright 2021 github.com/gagliardetto
     2  // This file has been modified by github.com/gagliardetto
     3  //
     4  // Copyright 2020 dfuse Platform Inc.
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License");
     7  // you may not use this file except in compliance with the License.
     8  // You may obtain a copy of the License at
     9  //
    10  //      http://www.apache.org/licenses/LICENSE-2.0
    11  //
    12  // Unless required by applicable law or agreed to in writing, software
    13  // distributed under the License is distributed on an "AS IS" BASIS,
    14  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  package bin
    19  
    20  import (
    21  	"encoding/binary"
    22  	"encoding/hex"
    23  	"encoding/json"
    24  	"fmt"
    25  	"math/big"
    26  	"strings"
    27  )
    28  
    29  // Uint128
    30  type Uint128 struct {
    31  	Lo         uint64
    32  	Hi         uint64
    33  	Endianness binary.ByteOrder
    34  }
    35  
    36  func NewUint128BigEndian() *Uint128 {
    37  	return &Uint128{
    38  		Endianness: binary.BigEndian,
    39  	}
    40  }
    41  
    42  func NewUint128LittleEndian() *Uint128 {
    43  	return &Uint128{
    44  		Endianness: binary.LittleEndian,
    45  	}
    46  }
    47  
    48  func (i Uint128) getByteOrder() binary.ByteOrder {
    49  	if i.Endianness == nil {
    50  		return defaultByteOrder
    51  	}
    52  	return i.Endianness
    53  }
    54  
    55  func (i Int128) getByteOrder() binary.ByteOrder {
    56  	return Uint128(i).getByteOrder()
    57  }
    58  func (i Float128) getByteOrder() binary.ByteOrder {
    59  	return Uint128(i).getByteOrder()
    60  }
    61  
    62  func (i Uint128) Bytes() []byte {
    63  	buf := make([]byte, 16)
    64  	order := i.getByteOrder()
    65  	if order == binary.LittleEndian {
    66  		order.PutUint64(buf[:8], i.Lo)
    67  		order.PutUint64(buf[8:], i.Hi)
    68  		ReverseBytes(buf)
    69  	} else {
    70  		order.PutUint64(buf[:8], i.Hi)
    71  		order.PutUint64(buf[8:], i.Lo)
    72  	}
    73  	return buf
    74  }
    75  
    76  func (i Uint128) BigInt() *big.Int {
    77  	buf := i.Bytes()
    78  	value := (&big.Int{}).SetBytes(buf)
    79  	return value
    80  }
    81  
    82  func (i Uint128) String() string {
    83  	//Same for Int128, Float128
    84  	return i.DecimalString()
    85  }
    86  
    87  func (i Uint128) DecimalString() string {
    88  	return i.BigInt().String()
    89  }
    90  
    91  func (i Uint128) HexString() string {
    92  	number := i.Bytes()
    93  	return fmt.Sprintf("0x%s", hex.EncodeToString(number))
    94  }
    95  
    96  func (i Uint128) MarshalJSON() (data []byte, err error) {
    97  	return []byte(`"` + i.String() + `"`), nil
    98  }
    99  
   100  func ReverseBytes(s []byte) {
   101  	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
   102  		s[i], s[j] = s[j], s[i]
   103  	}
   104  }
   105  
   106  func (i *Uint128) UnmarshalJSON(data []byte) error {
   107  	if string(data) == "null" {
   108  		return nil
   109  	}
   110  
   111  	var s string
   112  	if err := json.Unmarshal(data, &s); err != nil {
   113  		return err
   114  	}
   115  
   116  	if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") {
   117  		return i.unmarshalJSON_hex(s)
   118  	}
   119  
   120  	return i.unmarshalJSON_decimal(s)
   121  }
   122  
   123  func (i *Uint128) unmarshalJSON_decimal(s string) error {
   124  	parsed, ok := (&big.Int{}).SetString(s, 0)
   125  	if !ok {
   126  		return fmt.Errorf("could not parse %q", s)
   127  	}
   128  	oo := parsed.FillBytes(make([]byte, 16))
   129  	ReverseBytes(oo)
   130  
   131  	dec := NewBinDecoder(oo)
   132  
   133  	out, err := dec.ReadUint128(i.getByteOrder())
   134  	if err != nil {
   135  		return err
   136  	}
   137  	i.Lo = out.Lo
   138  	i.Hi = out.Hi
   139  
   140  	return nil
   141  }
   142  
   143  func (i *Uint128) unmarshalJSON_hex(s string) error {
   144  	truncatedVal := s[2:]
   145  	if len(truncatedVal) != 16 {
   146  		return fmt.Errorf("uint128 expects 16 characters after 0x, had %v", len(truncatedVal))
   147  	}
   148  
   149  	data, err := hex.DecodeString(truncatedVal)
   150  	if err != nil {
   151  		return err
   152  	}
   153  
   154  	order := i.getByteOrder()
   155  	if order == binary.LittleEndian {
   156  		i.Lo = order.Uint64(data[:8])
   157  		i.Hi = order.Uint64(data[8:])
   158  	} else {
   159  		i.Hi = order.Uint64(data[:8])
   160  		i.Lo = order.Uint64(data[8:])
   161  	}
   162  
   163  	return nil
   164  }
   165  
   166  func (i *Uint128) UnmarshalWithDecoder(dec *Decoder) error {
   167  	var order binary.ByteOrder
   168  	if dec != nil && dec.currentFieldOpt != nil {
   169  		order = dec.currentFieldOpt.Order
   170  	} else {
   171  		order = i.getByteOrder()
   172  	}
   173  	value, err := dec.ReadUint128(order)
   174  	if err != nil {
   175  		return err
   176  	}
   177  
   178  	*i = value
   179  	return nil
   180  }
   181  
   182  func (i Uint128) MarshalWithEncoder(enc *Encoder) error {
   183  	var order binary.ByteOrder
   184  	if enc != nil && enc.currentFieldOpt != nil {
   185  		order = enc.currentFieldOpt.Order
   186  	} else {
   187  		order = i.getByteOrder()
   188  	}
   189  	return enc.WriteUint128(i, order)
   190  }
   191  
   192  // Int128
   193  type Int128 Uint128
   194  
   195  func (i Int128) BigInt() *big.Int {
   196  	comp := byte(0x80)
   197  	buf := Uint128(i).Bytes()
   198  
   199  	var value *big.Int
   200  	if (buf[0] & comp) == comp {
   201  		buf = twosComplement(buf)
   202  		value = (&big.Int{}).SetBytes(buf)
   203  		value = value.Neg(value)
   204  	} else {
   205  		value = (&big.Int{}).SetBytes(buf)
   206  	}
   207  	return value
   208  }
   209  
   210  func (i Int128) String() string {
   211  	return Uint128(i).String()
   212  }
   213  
   214  func (i Int128) DecimalString() string {
   215  	return i.BigInt().String()
   216  }
   217  
   218  func (i Int128) MarshalJSON() (data []byte, err error) {
   219  	return []byte(`"` + Uint128(i).String() + `"`), nil
   220  }
   221  
   222  func (i *Int128) UnmarshalJSON(data []byte) error {
   223  	var el Uint128
   224  	if err := json.Unmarshal(data, &el); err != nil {
   225  		return err
   226  	}
   227  
   228  	out := Int128(el)
   229  	*i = out
   230  
   231  	return nil
   232  }
   233  
   234  func (i *Int128) UnmarshalWithDecoder(dec *Decoder) error {
   235  	var order binary.ByteOrder
   236  	if dec != nil && dec.currentFieldOpt != nil {
   237  		order = dec.currentFieldOpt.Order
   238  	} else {
   239  		order = i.getByteOrder()
   240  	}
   241  	value, err := dec.ReadInt128(order)
   242  	if err != nil {
   243  		return err
   244  	}
   245  
   246  	*i = value
   247  	return nil
   248  }
   249  
   250  func (i Int128) MarshalWithEncoder(enc *Encoder) error {
   251  	var order binary.ByteOrder
   252  	if enc != nil && enc.currentFieldOpt != nil {
   253  		order = enc.currentFieldOpt.Order
   254  	} else {
   255  		order = i.getByteOrder()
   256  	}
   257  	return enc.WriteInt128(i, order)
   258  }
   259  
   260  type Float128 Uint128
   261  
   262  func (i Float128) MarshalJSON() (data []byte, err error) {
   263  	return []byte(`"` + Uint128(i).String() + `"`), nil
   264  }
   265  
   266  func (i *Float128) UnmarshalJSON(data []byte) error {
   267  	var el Uint128
   268  	if err := json.Unmarshal(data, &el); err != nil {
   269  		return err
   270  	}
   271  
   272  	out := Float128(el)
   273  	*i = out
   274  
   275  	return nil
   276  }
   277  
   278  func (i *Float128) UnmarshalWithDecoder(dec *Decoder) error {
   279  	var order binary.ByteOrder
   280  	if dec != nil && dec.currentFieldOpt != nil {
   281  		order = dec.currentFieldOpt.Order
   282  	} else {
   283  		order = i.getByteOrder()
   284  	}
   285  	value, err := dec.ReadFloat128(order)
   286  	if err != nil {
   287  		return err
   288  	}
   289  
   290  	*i = Float128(value)
   291  	return nil
   292  }
   293  
   294  func (i Float128) MarshalWithEncoder(enc *Encoder) error {
   295  	var order binary.ByteOrder
   296  	if enc != nil && enc.currentFieldOpt != nil {
   297  		order = enc.currentFieldOpt.Order
   298  	} else {
   299  		order = i.getByteOrder()
   300  	}
   301  	return enc.WriteUint128(Uint128(i), order)
   302  }