github.com/onosproject/onos-api/go@v0.10.32/onos/config/v2/typedvalue.go (about)

     1  // SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package v2
     6  
     7  import (
     8  	"encoding/base64"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"math"
    12  	"math/big"
    13  	"strconv"
    14  	"strings"
    15  )
    16  
    17  const (
    18  	isPositiveTypeOpt = int32(0)
    19  	isNegativeTypeOpt = int32(1)
    20  )
    21  
    22  type Width int
    23  
    24  const (
    25  	WidthUnknown Width = 1 << (iota + 2)
    26  	WidthEight
    27  	WidthSixteen
    28  	WidthThirtyTwo
    29  	WidthSixtyFour
    30  )
    31  
    32  // TypedValueMap is an alias for a map of paths and values
    33  type TypedValueMap map[string]*TypedValue
    34  
    35  // ValueToString is the String calculated as a Native type
    36  // There is already a String() in the protobuf generated code that can't be
    37  // overridden
    38  func (tv *TypedValue) ValueToString() string {
    39  	switch tv.Type {
    40  	case ValueType_EMPTY:
    41  		return ""
    42  	case ValueType_STRING:
    43  		return (*TypedString)(tv).String()
    44  	case ValueType_INT:
    45  		return (*TypedInt)(tv).String()
    46  	case ValueType_UINT:
    47  		return (*TypedUint)(tv).String()
    48  	case ValueType_BOOL:
    49  		return (*TypedBool)(tv).String()
    50  	case ValueType_DECIMAL:
    51  		return (*TypedDecimal)(tv).String()
    52  	case ValueType_FLOAT:
    53  		return (*TypedFloat)(tv).String()
    54  	case ValueType_DOUBLE:
    55  		return (*TypedDouble)(tv).String()
    56  	case ValueType_BYTES:
    57  		return (*TypedBytes)(tv).String()
    58  	case ValueType_LEAFLIST_STRING:
    59  		return (*TypedLeafListString)(tv).String()
    60  	case ValueType_LEAFLIST_INT:
    61  		return (*TypedLeafListInt)(tv).String()
    62  	case ValueType_LEAFLIST_UINT:
    63  		return (*TypedLeafListUint)(tv).String()
    64  	case ValueType_LEAFLIST_BOOL:
    65  		return (*TypedLeafListBool)(tv).String()
    66  	case ValueType_LEAFLIST_DECIMAL:
    67  		return (*TypedLeafListDecimal)(tv).String()
    68  	case ValueType_LEAFLIST_FLOAT:
    69  		return (*TypedLeafListFloat)(tv).String()
    70  	case ValueType_LEAFLIST_BYTES:
    71  		return (*TypedLeafListBytes)(tv).String()
    72  	}
    73  
    74  	return ""
    75  }
    76  
    77  // NewTypedValue creates a TypeValue from a byte[] and type - used in changes.go
    78  // For Int and Uint both the width and sign must be given in type opts e.g. [32, 1]
    79  func NewTypedValue(bytes []byte, valueType ValueType, typeOpts []uint8) (*TypedValue, error) {
    80  	switch valueType {
    81  	case ValueType_EMPTY:
    82  		return NewTypedValueEmpty(), nil
    83  	case ValueType_STRING:
    84  		return NewTypedValueString(string(bytes)), nil
    85  	case ValueType_INT:
    86  		if len(typeOpts) != 2 {
    87  			return nil, fmt.Errorf("number width AND sign must be given for INT as type opts. %v", typeOpts)
    88  		}
    89  		if typeOpts[0]/8 < uint8(len(bytes)) {
    90  			return nil, fmt.Errorf("number width %d must match number of bytes %d for INT", typeOpts[0], len(bytes))
    91  		}
    92  		var bigInt big.Int
    93  		bigInt.SetBytes(bytes)
    94  		if len(typeOpts) == 2 && typeOpts[1] != uint8(isPositiveTypeOpt) {
    95  			// Negative value
    96  			bigInt.Neg(&bigInt)
    97  		}
    98  		return NewTypedValueInt(int(bigInt.Int64()), Width(typeOpts[0])), nil
    99  	case ValueType_UINT:
   100  		if len(typeOpts) != 1 {
   101  			return nil, fmt.Errorf("number width must be given for UINT as type opts. %v", typeOpts)
   102  		}
   103  		if typeOpts[0]/8 < uint8(len(bytes)) {
   104  			return nil, fmt.Errorf("number width %d must match number of bytes %d for INT", typeOpts[0], len(bytes))
   105  		}
   106  		var bigInt big.Int
   107  		bigInt.SetBytes(bytes)
   108  
   109  		return NewTypedValueUint(uint(bigInt.Uint64()), Width(typeOpts[0])), nil
   110  	case ValueType_BOOL:
   111  		if len(bytes) != 1 {
   112  			return nil, fmt.Errorf("expecting 1 byte for BOOL. Got %d", len(bytes))
   113  		}
   114  		value := false
   115  		if bytes[0] == 1 {
   116  			value = true
   117  		}
   118  		return NewTypedValueBool(value), nil
   119  	case ValueType_DECIMAL:
   120  		if len(typeOpts) != 2 {
   121  			return nil, fmt.Errorf("precision AND sign must be given for DECIMAL as type opts. %v", typeOpts)
   122  		}
   123  		precision := typeOpts[0]
   124  		var bigInt big.Int
   125  		bigInt.SetBytes(bytes)
   126  		if len(typeOpts) == 2 && typeOpts[1] != uint8(isPositiveTypeOpt) {
   127  			// Negative value
   128  			bigInt.Neg(&bigInt)
   129  		}
   130  		return NewTypedValueDecimal(bigInt.Int64(), precision), nil
   131  	case ValueType_FLOAT:
   132  		if len(bytes) != 8 {
   133  			return nil, fmt.Errorf("expecting 8 bytes for FLOAT. Got %d", len(bytes))
   134  		}
   135  		return NewTypedValueFloat(float64(math.Float64frombits(binary.LittleEndian.Uint64(bytes)))), nil
   136  	case ValueType_DOUBLE:
   137  		return NewTypedValueDouble(float64(math.Float64frombits(binary.LittleEndian.Uint64(bytes)))), nil
   138  	case ValueType_BYTES:
   139  		return NewTypedValueBytes(bytes), nil
   140  	case ValueType_LEAFLIST_STRING:
   141  		return caseValueTypeLeafListSTRING(bytes)
   142  	case ValueType_LEAFLIST_INT:
   143  		return caseValueTypeLeafListINT(bytes, typeOpts)
   144  	case ValueType_LEAFLIST_UINT:
   145  		return caseValueTypeLeafListUINT(bytes, typeOpts)
   146  	case ValueType_LEAFLIST_BOOL:
   147  		return caseValueTypeLeafListBOOL(bytes)
   148  	case ValueType_LEAFLIST_DECIMAL:
   149  		return caseValueTypeLeafListDECIMAL(bytes, typeOpts)
   150  	case ValueType_LEAFLIST_FLOAT:
   151  		return caseValueTypeLeafListFLOAT(bytes)
   152  	case ValueType_LEAFLIST_DOUBLE:
   153  		return caseValueTypeLeafListDOUBLE(bytes)
   154  	case ValueType_LEAFLIST_BYTES:
   155  		return caseValueTypeLeafListBYTES(bytes, typeOpts)
   156  	}
   157  
   158  	return nil, fmt.Errorf("unexpected type %d", valueType)
   159  }
   160  
   161  // caseValueTypeLeafListSTRING is moved out of NewTypedValue because of gocyclo
   162  func caseValueTypeLeafListSTRING(bytes []byte) (*TypedValue, error) {
   163  	stringList := make([]string, 0)
   164  	buf := make([]byte, 0)
   165  	for _, b := range bytes {
   166  		if b != 0x1D {
   167  			buf = append(buf, b)
   168  		} else {
   169  			stringList = append(stringList, string(buf))
   170  			buf = make([]byte, 0)
   171  		}
   172  	}
   173  	stringList = append(stringList, string(buf))
   174  	return NewLeafListStringTv(stringList), nil
   175  }
   176  
   177  // caseValueTypeLeafListINT is moved out of NewTypedValue because of gocyclo
   178  func caseValueTypeLeafListINT(bytes []byte, typeOpts []uint8) (*TypedValue, error) {
   179  	count := (len(typeOpts) - 1) / 2
   180  	if count < 1 {
   181  		return nil, fmt.Errorf("unexpected #type opts. Expect 1 for width and then a pair per entry [len bytes, negative]")
   182  	}
   183  	intList := make([]int64, 0)
   184  	width := Width(typeOpts[0])
   185  	var byteCounter uint32 = 0
   186  	for i := 0; i < count; i++ {
   187  		v := bytes[byteCounter : byteCounter+uint32(typeOpts[1+i*2])]
   188  		byteCounter += uint32(typeOpts[1+i*2])
   189  		var bigInt big.Int
   190  		bigInt.SetBytes(v)
   191  		negative := typeOpts[1+i*2+1]
   192  		if negative != uint8(isPositiveTypeOpt) {
   193  			bigInt.Neg(&bigInt)
   194  		}
   195  		intList = append(intList, bigInt.Int64())
   196  	}
   197  	return NewLeafListIntTv(intList, width), nil
   198  }
   199  
   200  // caseValueTypeLeafListUINT is moved out of NewTypedValue because of gocyclo
   201  func caseValueTypeLeafListUINT(bytes []byte, typeOpts []uint8) (*TypedValue, error) {
   202  	count := (len(typeOpts) - 1)
   203  	if count < 1 {
   204  		return nil, fmt.Errorf("unexpected #type opts. Expect 1 for width and then a value per entry [len bytes]")
   205  	}
   206  	uintList := make([]uint64, 0)
   207  	width := Width(typeOpts[0])
   208  	var byteCounter uint32 = 0
   209  	for i := 0; i < count; i++ {
   210  		v := bytes[byteCounter : byteCounter+uint32(typeOpts[1+i])]
   211  		byteCounter += uint32(typeOpts[1+i])
   212  		var bigInt big.Int
   213  		bigInt.SetBytes(v)
   214  		uintList = append(uintList, bigInt.Uint64())
   215  	}
   216  
   217  	return NewLeafListUintTv(uintList, width), nil
   218  }
   219  
   220  // caseValueTypeLeafListBOOL is moved out of NewTypedValue because of gocyclo
   221  func caseValueTypeLeafListBOOL(bytes []byte) (*TypedValue, error) {
   222  	count := len(bytes)
   223  	bools := make([]bool, count)
   224  	for i, v := range bytes {
   225  		if v == 1 {
   226  			bools[i] = true
   227  		}
   228  	}
   229  	return NewLeafListBoolTv(bools), nil
   230  }
   231  
   232  // caseValueTypeLeafListDECIMAL is moved out of NewTypedValue because of gocyclo
   233  // First typeOpt is precision. Expect a pair of type opts per entry [len bytes, negative]
   234  func caseValueTypeLeafListDECIMAL(bytes []byte, typeOpts []uint8) (*TypedValue, error) {
   235  	count := (len(typeOpts) - 1) / 2
   236  	if count < 1 {
   237  		return nil, fmt.Errorf("unexpected #type opts. Expect 1 for precision and then a pair per entry [len bytes, negative]")
   238  	}
   239  	digitsList := make([]int64, 0)
   240  	precision := typeOpts[0]
   241  	var byteCounter uint32 = 0
   242  	for i := 0; i < count; i++ {
   243  		v := bytes[byteCounter : byteCounter+uint32(typeOpts[1+i*2])]
   244  		byteCounter += uint32(typeOpts[1+i*2])
   245  		var bigInt big.Int
   246  		bigInt.SetBytes(v)
   247  		negative := typeOpts[1+i*2+1]
   248  		if negative != uint8(isPositiveTypeOpt) {
   249  			bigInt.Neg(&bigInt)
   250  		}
   251  		digitsList = append(digitsList, bigInt.Int64())
   252  	}
   253  	return NewLeafListDecimalTv(digitsList, precision), nil
   254  }
   255  
   256  // caseValueTypeLeafListFLOAT is moved out of NewTypedValue because of gocyclo
   257  func caseValueTypeLeafListFLOAT(bytes []byte) (*TypedValue, error) {
   258  	count := len(bytes) / 8
   259  	float32s := make([]float32, 0)
   260  
   261  	for i := 0; i < count; i++ {
   262  		v := bytes[i*8 : i*8+8]
   263  		float32s = append(float32s, float32(math.Float64frombits(binary.LittleEndian.Uint64(v))))
   264  	}
   265  	return NewLeafListFloatTv(float32s), nil
   266  }
   267  
   268  // caseValueTypeLeafListDOUBLE is moved out of NewTypedValue because of gocyclo
   269  func caseValueTypeLeafListDOUBLE(bytes []byte) (*TypedValue, error) {
   270  	count := len(bytes) / 8
   271  	doubles := make([]float64, 0)
   272  
   273  	for i := 0; i < count; i++ {
   274  		v := bytes[i*8 : i*8+8]
   275  		doubles = append(doubles, float64(math.Float64frombits(binary.LittleEndian.Uint64(v))))
   276  	}
   277  	return NewLeafListDoubleTv(doubles), nil
   278  }
   279  
   280  // caseValueTypeLeafListBYTES is moved out of NewTypedValue because of gocyclo
   281  func caseValueTypeLeafListBYTES(bytes []byte, typeOpts []uint8) (*TypedValue, error) {
   282  	if len(typeOpts) < 1 {
   283  		return nil, fmt.Errorf("expecting 1 typeopt for LeafListBytes. Got %d", len(typeOpts))
   284  	}
   285  	byteArrays := make([][]byte, 0)
   286  	buf := make([]byte, 0)
   287  	idx := 0
   288  	startAt := 0
   289  	for i, b := range bytes {
   290  		valueLen := typeOpts[idx]
   291  		if i-startAt == int(valueLen) {
   292  			byteArrays = append(byteArrays, buf)
   293  			buf = make([]byte, 0)
   294  			idx = idx + 1
   295  			if idx >= len(typeOpts) {
   296  				return nil, fmt.Errorf("not enough typeOpts provided - found %d need at least %d", len(typeOpts), idx+1)
   297  			}
   298  			startAt = startAt + int(valueLen)
   299  		}
   300  		buf = append(buf, b)
   301  	}
   302  	byteArrays = append(byteArrays, buf)
   303  	return NewLeafListBytesTv(byteArrays), nil
   304  }
   305  
   306  ////////////////////////////////////////////////////////////////////////////////
   307  // TypedEmpty
   308  ////////////////////////////////////////////////////////////////////////////////
   309  
   310  // TypedEmpty for an empty value
   311  type TypedEmpty TypedValue
   312  
   313  // NewTypedValueEmpty decodes an empty object
   314  func NewTypedValueEmpty() *TypedValue {
   315  	return (*TypedValue)(newEmpty())
   316  }
   317  
   318  // newEmpty creates an instance of the Empty type
   319  func newEmpty() *TypedEmpty {
   320  	typedEmpty := TypedEmpty{
   321  		Bytes: make([]byte, 0),
   322  		Type:  ValueType_EMPTY,
   323  	}
   324  	return &typedEmpty
   325  }
   326  
   327  // ValueType gives the value type
   328  func (tv *TypedEmpty) ValueType() ValueType {
   329  	return tv.Type
   330  }
   331  
   332  func (tv *TypedEmpty) String() string {
   333  	return ""
   334  }
   335  
   336  ////////////////////////////////////////////////////////////////////////////////
   337  // TypedString
   338  ////////////////////////////////////////////////////////////////////////////////
   339  
   340  // TypedString for a string value
   341  type TypedString TypedValue
   342  
   343  // NewTypedValueString decodes string value in to an object
   344  func NewTypedValueString(value string) *TypedValue {
   345  	return (*TypedValue)(newString(value))
   346  }
   347  
   348  // newString decodes string value in to a String type
   349  func newString(value string) *TypedString {
   350  	typedString := TypedString{
   351  		Bytes: []byte(value),
   352  		Type:  ValueType_STRING,
   353  	}
   354  	return &typedString
   355  }
   356  
   357  // ValueType gives the value type
   358  func (tv *TypedString) ValueType() ValueType {
   359  	return tv.Type
   360  }
   361  
   362  func (tv *TypedString) String() string {
   363  	return string(tv.Bytes)
   364  }
   365  
   366  ////////////////////////////////////////////////////////////////////////////////
   367  // TypedInt
   368  ////////////////////////////////////////////////////////////////////////////////
   369  
   370  // TypedInt for an int value
   371  type TypedInt TypedValue
   372  
   373  // NewTypedValueInt decodes an int value in to an object
   374  func NewTypedValueInt(value int, width Width) *TypedValue {
   375  	return (*TypedValue)(newInt(big.NewInt(int64(value)), width))
   376  }
   377  
   378  func newInt(value *big.Int, width Width) *TypedInt {
   379  	var isNegative int32 = isPositiveTypeOpt
   380  	if value.Sign() < 0 {
   381  		isNegative = isNegativeTypeOpt
   382  	}
   383  	typedInt := TypedInt{
   384  		Bytes:    value.Bytes(),
   385  		Type:     ValueType_INT,
   386  		TypeOpts: []int32{int32(width), isNegative},
   387  	}
   388  	return &typedInt
   389  }
   390  
   391  // ValueType gives the value type
   392  func (tv *TypedInt) ValueType() ValueType {
   393  	return tv.Type
   394  }
   395  
   396  func (tv *TypedInt) String() string {
   397  	return fmt.Sprintf("%d", tv.Int())
   398  }
   399  
   400  // Int extracts the integer value
   401  func (tv *TypedInt) Int() int {
   402  	var x big.Int
   403  	x.SetBytes(tv.Bytes)
   404  	if len(tv.TypeOpts) > 1 && tv.TypeOpts[1] == 1 {
   405  		x.Neg(&x)
   406  	}
   407  	return int(x.Int64())
   408  }
   409  
   410  ////////////////////////////////////////////////////////////////////////////////
   411  // TypedUint
   412  ////////////////////////////////////////////////////////////////////////////////
   413  
   414  // TypedUint for a uint value
   415  type TypedUint TypedValue
   416  
   417  // NewTypedValueUint decodes a uint value in to an object
   418  func NewTypedValueUint(value uint, width Width) *TypedValue {
   419  	var bigInt big.Int
   420  	bigInt.SetUint64(uint64(value))
   421  	return (*TypedValue)(newUint(&bigInt, width))
   422  }
   423  
   424  // newUint decodes a uint value in to a Uint type
   425  func newUint(value *big.Int, width Width) *TypedUint {
   426  	typedUint64 := TypedUint{
   427  		Bytes:    value.Bytes(),
   428  		Type:     ValueType_UINT,
   429  		TypeOpts: []int32{int32(width)},
   430  	}
   431  	return &typedUint64
   432  }
   433  
   434  // ValueType gives the value type
   435  func (tv *TypedUint) ValueType() ValueType {
   436  	return tv.Type
   437  }
   438  
   439  func (tv *TypedUint) String() string {
   440  	return fmt.Sprintf("%d", tv.Uint())
   441  }
   442  
   443  // Uint extracts the unsigned integer value
   444  func (tv *TypedUint) Uint() uint {
   445  	var bigInt big.Int
   446  	bigInt.SetBytes(tv.Bytes)
   447  	return uint(bigInt.Uint64())
   448  }
   449  
   450  ////////////////////////////////////////////////////////////////////////////////
   451  // TypedBool
   452  ////////////////////////////////////////////////////////////////////////////////
   453  
   454  // TypedBool for an int value
   455  type TypedBool TypedValue
   456  
   457  // NewTypedValueBool decodes a bool value in to an object
   458  func NewTypedValueBool(value bool) *TypedValue {
   459  	return (*TypedValue)(newBool(value))
   460  }
   461  
   462  // newBool decodes a bool value in to an object
   463  func newBool(value bool) *TypedBool {
   464  	buf := make([]byte, 1)
   465  	if value {
   466  		buf[0] = 1
   467  	}
   468  	typedBool := TypedBool{
   469  		Bytes: buf,
   470  		Type:  ValueType_BOOL,
   471  	}
   472  	return &typedBool
   473  }
   474  
   475  // ValueType gives the value type
   476  func (tv *TypedBool) ValueType() ValueType {
   477  	return tv.Type
   478  }
   479  
   480  func (tv *TypedBool) String() string {
   481  	if tv.Bytes[0] == 1 {
   482  		return "true"
   483  	}
   484  	return "false"
   485  }
   486  
   487  // Bool extracts the unsigned bool value
   488  func (tv *TypedBool) Bool() bool {
   489  	return tv.Bytes[0] == 1
   490  }
   491  
   492  ////////////////////////////////////////////////////////////////////////////////
   493  // TypedDecimal
   494  ////////////////////////////////////////////////////////////////////////////////
   495  
   496  // TypedDecimal for a decimal64 value
   497  type TypedDecimal TypedValue
   498  
   499  // NewTypedValueDecimal decodes a decimal value in to an object
   500  func NewTypedValueDecimal(digits int64, precision uint8) *TypedValue {
   501  	return (*TypedValue)(newDecimal(big.NewInt(digits), precision))
   502  }
   503  
   504  // newDecimal decodes a decimal value in to a Decimal type
   505  func newDecimal(digits *big.Int, precision uint8) *TypedDecimal {
   506  	var isNegative int32 = isPositiveTypeOpt
   507  	if digits.Sign() < 0 {
   508  		isNegative = isNegativeTypeOpt
   509  	}
   510  	typedDecimal64 := TypedDecimal{
   511  		Bytes:    digits.Bytes(),
   512  		Type:     ValueType_DECIMAL,
   513  		TypeOpts: []int32{int32(precision), isNegative},
   514  	}
   515  	return &typedDecimal64
   516  }
   517  
   518  // ValueType gives the value type
   519  func (tv *TypedDecimal) ValueType() ValueType {
   520  	return tv.Type
   521  }
   522  
   523  func (tv *TypedDecimal) String() string {
   524  	return strDecimal64(tv.Decimal64())
   525  }
   526  
   527  // Decimal64 extracts the unsigned decimal value
   528  func (tv *TypedDecimal) Decimal64() (int64, uint8) {
   529  	if len(tv.TypeOpts) > 0 {
   530  		precision := tv.TypeOpts[0]
   531  		var positiveMultiplier int64 = 1
   532  		if len(tv.TypeOpts) > 1 && tv.TypeOpts[1] == 1 {
   533  			positiveMultiplier = -1
   534  		}
   535  		var value big.Int
   536  		value.SetBytes(tv.Bytes)
   537  		return value.Int64() * positiveMultiplier, uint8(precision)
   538  	}
   539  	return 0, 0
   540  }
   541  
   542  // Float extracts the unsigned decimal value as a float
   543  func (tv *TypedDecimal) Float() float64 {
   544  	floatVal, _ := strconv.ParseFloat(strDecimal64(tv.Decimal64()), 64)
   545  	return floatVal
   546  }
   547  
   548  ////////////////////////////////////////////////////////////////////////////////
   549  // TypedFloat
   550  ////////////////////////////////////////////////////////////////////////////////
   551  
   552  // TypedFloat for a float value
   553  type TypedFloat TypedValue
   554  
   555  // NewTypedValueFloat decodes a decimal value in to an object
   556  func NewTypedValueFloat(value float64) *TypedValue {
   557  	return (*TypedValue)(newFloat(big.NewFloat(value)))
   558  }
   559  
   560  // newFloat decodes a decimal value in to a Bool type
   561  func newFloat(value *big.Float) *TypedFloat {
   562  	bytes, _ := value.GobEncode()
   563  	typedFloat := TypedFloat{
   564  		Bytes: bytes,
   565  		Type:  ValueType_FLOAT,
   566  	}
   567  	return &typedFloat
   568  }
   569  
   570  // ValueType gives the value type
   571  func (tv *TypedFloat) ValueType() ValueType {
   572  	return tv.Type
   573  }
   574  
   575  func (tv *TypedFloat) String() string {
   576  	return fmt.Sprintf("%f", tv.Float32())
   577  }
   578  
   579  // Float32 extracts the float value
   580  func (tv *TypedFloat) Float32() float32 {
   581  	if len(tv.Bytes) == 0 {
   582  		return 0.0
   583  	}
   584  	var value big.Float
   585  	_ = value.GobDecode(tv.Bytes)
   586  	flt32, _ := value.Float32()
   587  	return flt32
   588  }
   589  
   590  ////////////////////////////////////////////////////////////////////////////////
   591  // TypedDouble
   592  ////////////////////////////////////////////////////////////////////////////////
   593  
   594  // TypedDouble for a float value
   595  type TypedDouble TypedValue
   596  
   597  // NewTypedValueDouble decodes a decimal value in to an object
   598  func NewTypedValueDouble(value float64) *TypedValue {
   599  	return (*TypedValue)(newDouble(big.NewFloat(value)))
   600  }
   601  
   602  // newDouble decodes a decimal value in to a Bool type
   603  func newDouble(value *big.Float) *TypedDouble {
   604  	bytes, _ := value.GobEncode()
   605  	typedDouble := TypedDouble{
   606  		Bytes: bytes,
   607  		Type:  ValueType_DOUBLE,
   608  	}
   609  	return &typedDouble
   610  }
   611  
   612  // ValueType gives the value type
   613  func (tv *TypedDouble) ValueType() ValueType {
   614  	return tv.Type
   615  }
   616  
   617  func (tv *TypedDouble) String() string {
   618  	return fmt.Sprintf("%f", tv.Double())
   619  }
   620  
   621  // Double extracts the float value
   622  func (tv *TypedDouble) Double() float64 {
   623  	if len(tv.Bytes) == 0 {
   624  		return 0.0
   625  	}
   626  	var value big.Float
   627  	_ = value.GobDecode(tv.Bytes)
   628  	double, _ := value.Float64()
   629  	return double
   630  }
   631  
   632  ////////////////////////////////////////////////////////////////////////////////
   633  // TypedBytes
   634  ////////////////////////////////////////////////////////////////////////////////
   635  
   636  // TypedBytes for a float value
   637  type TypedBytes TypedValue
   638  
   639  // NewTypedValueBytes decodes an array of bytes in to an object
   640  func NewTypedValueBytes(value []byte) *TypedValue {
   641  	return (*TypedValue)(newBytes(value))
   642  }
   643  
   644  // newBytes decodes an array of bytes in to a Bytes type
   645  func newBytes(value []byte) *TypedBytes {
   646  	typedFloat := TypedBytes{
   647  		Bytes:    value,
   648  		Type:     ValueType_BYTES,
   649  		TypeOpts: []int32{int32(len(value))},
   650  	}
   651  	return &typedFloat
   652  }
   653  
   654  // ValueType gives the value type
   655  func (tv *TypedBytes) ValueType() ValueType {
   656  	return tv.Type
   657  }
   658  
   659  func (tv *TypedBytes) String() string {
   660  	return base64.StdEncoding.EncodeToString(tv.Bytes)
   661  }
   662  
   663  // ByteArray extracts the bytes value
   664  func (tv *TypedBytes) ByteArray() []byte {
   665  	return tv.Bytes
   666  }
   667  
   668  ////////////////////////////////////////////////////////////////////////////////
   669  // TypedLeafListString
   670  ////////////////////////////////////////////////////////////////////////////////
   671  
   672  // TypedLeafListString for a string leaf list
   673  type TypedLeafListString TypedValue
   674  
   675  // NewLeafListStringTv decodes string values in to an object
   676  func NewLeafListStringTv(values []string) *TypedValue {
   677  	return (*TypedValue)(newLeafListString(values))
   678  }
   679  
   680  // newLeafListString decodes string values in to an Leaf list type
   681  func newLeafListString(values []string) *TypedLeafListString {
   682  	first := true
   683  	bytes := make([]byte, 0)
   684  	for _, v := range values {
   685  		if first {
   686  			first = false
   687  		} else {
   688  			bytes = append(bytes, 0x1D) // Group separator
   689  		}
   690  		bytes = append(bytes, []byte(v)...)
   691  	}
   692  	typedLeafListString := TypedLeafListString{
   693  		Bytes: bytes,
   694  		Type:  ValueType_LEAFLIST_STRING,
   695  	}
   696  	return &typedLeafListString
   697  }
   698  
   699  // ValueType gives the value type
   700  func (tv *TypedLeafListString) ValueType() ValueType {
   701  	return tv.Type
   702  }
   703  
   704  func (tv *TypedLeafListString) String() string {
   705  	return strings.Join(tv.List(), ",")
   706  }
   707  
   708  // List extracts the leaf list values
   709  func (tv *TypedLeafListString) List() []string {
   710  	stringList := make([]string, 0)
   711  	buf := make([]byte, 0)
   712  	for _, b := range tv.Bytes {
   713  		if b != 0x1D {
   714  			buf = append(buf, b)
   715  		} else {
   716  			stringList = append(stringList, string(buf))
   717  			buf = make([]byte, 0)
   718  		}
   719  	}
   720  	stringList = append(stringList, string(buf))
   721  	return stringList
   722  }
   723  
   724  ////////////////////////////////////////////////////////////////////////////////
   725  // TypedLeafListInt
   726  ////////////////////////////////////////////////////////////////////////////////
   727  
   728  // TypedLeafListInt for an int leaf list
   729  type TypedLeafListInt TypedValue
   730  
   731  // NewLeafListIntTv decodes int values in to an object
   732  func NewLeafListIntTv(values []int64, width Width) *TypedValue {
   733  	valuesBi := make([]*big.Int, 0)
   734  	for _, v := range values {
   735  		valuesBi = append(valuesBi, big.NewInt(v))
   736  	}
   737  	return (*TypedValue)(newLeafListInt(valuesBi, width))
   738  }
   739  
   740  // newLeafListInt decodes int values in to a Leaf list type
   741  func newLeafListInt(values []*big.Int, width Width) *TypedLeafListInt {
   742  	bytes := make([]byte, 0)
   743  	typeOpts := make([]int32, 0)
   744  	typeOpts = append(typeOpts, int32(width))
   745  	for _, v := range values {
   746  		var isNegative int32 = isPositiveTypeOpt
   747  		if v.Sign() < 0 {
   748  			isNegative = isNegativeTypeOpt
   749  		}
   750  		typeOpts = append(typeOpts, int32(len(v.Bytes())))
   751  		typeOpts = append(typeOpts, isNegative)
   752  		bytes = append(bytes, v.Bytes()...)
   753  	}
   754  	typedLeafListInt := TypedLeafListInt{
   755  		Bytes:    bytes,
   756  		Type:     ValueType_LEAFLIST_INT,
   757  		TypeOpts: typeOpts,
   758  	}
   759  	return &typedLeafListInt
   760  }
   761  
   762  // ValueType gives the value type
   763  func (tv *TypedLeafListInt) ValueType() ValueType {
   764  	return tv.Type
   765  }
   766  
   767  func (tv *TypedLeafListInt) String() string {
   768  	intValues, width := tv.List()
   769  	return fmt.Sprintf("%v %d", intValues, width)
   770  }
   771  
   772  // List extracts the leaf list values
   773  func (tv *TypedLeafListInt) List() ([]int64, Width) {
   774  	count := (len(tv.TypeOpts) - 1) / 2
   775  
   776  	intList := make([]int64, 0)
   777  	width := tv.TypeOpts[0]
   778  	var byteCounter int32 = 0
   779  	for i := 0; i < count; i++ {
   780  		v := tv.Bytes[byteCounter : byteCounter+tv.TypeOpts[1+i*2]]
   781  		byteCounter = byteCounter + tv.TypeOpts[1+i*2]
   782  		var bigInt big.Int
   783  		bigInt.SetBytes(v)
   784  		negative := tv.TypeOpts[1+i*2+1]
   785  		if negative != isPositiveTypeOpt {
   786  			bigInt.Neg(&bigInt)
   787  		}
   788  		intList = append(intList, bigInt.Int64())
   789  	}
   790  
   791  	return intList, Width(width)
   792  }
   793  
   794  ////////////////////////////////////////////////////////////////////////////////
   795  // TypedLeafListUint
   796  ////////////////////////////////////////////////////////////////////////////////
   797  
   798  // TypedLeafListUint for an uint leaf list
   799  type TypedLeafListUint TypedValue
   800  
   801  // NewLeafListUintTv decodes uint values in to a Leaf list
   802  func NewLeafListUintTv(values []uint64, width Width) *TypedValue {
   803  	valuesBi := make([]*big.Int, 0)
   804  	for _, v := range values {
   805  		var bigUint big.Int
   806  		bigUint.SetUint64(v)
   807  		valuesBi = append(valuesBi, &bigUint)
   808  	}
   809  
   810  	return (*TypedValue)(newLeafListUint(valuesBi, width))
   811  }
   812  
   813  // newLeafListUint decodes uint values in to a Leaf list type
   814  func newLeafListUint(values []*big.Int, width Width) *TypedLeafListUint {
   815  	bytes := make([]byte, 0)
   816  	typeOpts := make([]int32, 0)
   817  	typeOpts = append(typeOpts, int32(width))
   818  	for _, v := range values {
   819  		typeOpts = append(typeOpts, int32(len(v.Bytes())))
   820  		bytes = append(bytes, v.Bytes()...)
   821  	}
   822  	typedLeafListUint := TypedLeafListUint{
   823  		Bytes:    bytes,
   824  		Type:     ValueType_LEAFLIST_UINT,
   825  		TypeOpts: typeOpts,
   826  	}
   827  	return &typedLeafListUint
   828  }
   829  
   830  // ValueType gives the value type
   831  func (tv *TypedLeafListUint) ValueType() ValueType {
   832  	return tv.Type
   833  }
   834  
   835  func (tv *TypedLeafListUint) String() string {
   836  	intValues, width := tv.List()
   837  	return fmt.Sprintf("%v %d", intValues, width)
   838  }
   839  
   840  // List extracts the leaf list values
   841  func (tv *TypedLeafListUint) List() ([]uint64, Width) {
   842  	count := len(tv.TypeOpts) - 1
   843  
   844  	uintList := make([]uint64, 0)
   845  	width := tv.TypeOpts[0]
   846  	var byteCounter int32 = 0
   847  	for i := 0; i < count; i++ {
   848  		v := tv.Bytes[byteCounter : byteCounter+tv.TypeOpts[1+i]]
   849  		byteCounter = byteCounter + tv.TypeOpts[1+i]
   850  		var bigInt big.Int
   851  		bigInt.SetBytes(v)
   852  		uintList = append(uintList, bigInt.Uint64())
   853  	}
   854  
   855  	return uintList, Width(width)
   856  }
   857  
   858  ////////////////////////////////////////////////////////////////////////////////
   859  // TypedLeafListBool
   860  ////////////////////////////////////////////////////////////////////////////////
   861  
   862  // TypedLeafListBool for an bool leaf list
   863  type TypedLeafListBool TypedValue
   864  
   865  // NewLeafListBoolTv decodes bool values in to an object
   866  func NewLeafListBoolTv(values []bool) *TypedValue {
   867  	return (*TypedValue)(newLeafListBool(values))
   868  }
   869  
   870  // newLeafListBool decodes bool values in to a Leaf list type
   871  func newLeafListBool(values []bool) *TypedLeafListBool {
   872  	count := len(values)
   873  	bytes := make([]byte, count)
   874  	for i, b := range values {
   875  		// just use one byte per bool - inefficient but not worth the hassle
   876  		var intval uint8
   877  		if b {
   878  			intval = 1
   879  		}
   880  		bytes[i] = intval
   881  	}
   882  	typedLeafListBool := TypedLeafListBool{
   883  		Bytes: bytes,
   884  		Type:  ValueType_LEAFLIST_BOOL,
   885  	}
   886  	return &typedLeafListBool
   887  }
   888  
   889  // ValueType gives the value type
   890  func (tv *TypedLeafListBool) ValueType() ValueType {
   891  	return tv.Type
   892  }
   893  
   894  func (tv *TypedLeafListBool) String() string {
   895  	return fmt.Sprintf("%v", tv.List())
   896  }
   897  
   898  // List extracts the leaf list values
   899  func (tv *TypedLeafListBool) List() []bool {
   900  	count := len(tv.Bytes)
   901  	bools := make([]bool, count)
   902  	for i, v := range tv.Bytes {
   903  		if v == 1 {
   904  			bools[i] = true
   905  		}
   906  	}
   907  
   908  	return bools
   909  }
   910  
   911  ////////////////////////////////////////////////////////////////////////////////
   912  // TypedLeafListDecimal
   913  ////////////////////////////////////////////////////////////////////////////////
   914  
   915  // TypedLeafListDecimal for a decimal leaf list
   916  type TypedLeafListDecimal TypedValue
   917  
   918  // NewLeafListDecimalTv decodes decimal values in to a Leaf list
   919  func NewLeafListDecimalTv(digits []int64, precision uint8) *TypedValue {
   920  	digitsBi := make([]*big.Int, 0)
   921  	for _, d := range digits {
   922  		digitsBi = append(digitsBi, big.NewInt(d))
   923  	}
   924  	return (*TypedValue)(newLeafListDecimal(digitsBi, precision))
   925  }
   926  
   927  // newLeafListDecimal decodes decimal values in to a Leaf list type
   928  func newLeafListDecimal(digits []*big.Int, precision uint8) *TypedLeafListDecimal {
   929  	bytes := make([]byte, 0)
   930  	typeOpts := make([]int32, 0)
   931  	typeOpts = append(typeOpts, int32(precision))
   932  	for _, d := range digits {
   933  		typeOpts = append(typeOpts, int32(len(d.Bytes())))
   934  		var isNegative int32 = isPositiveTypeOpt
   935  		if d.Sign() < 0 {
   936  			isNegative = isNegativeTypeOpt
   937  		}
   938  		typeOpts = append(typeOpts, isNegative)
   939  		bytes = append(bytes, d.Bytes()...)
   940  	}
   941  	typedLeafListDecimal := TypedLeafListDecimal{
   942  		Bytes:    bytes,
   943  		Type:     ValueType_LEAFLIST_DECIMAL,
   944  		TypeOpts: typeOpts,
   945  	}
   946  	return &typedLeafListDecimal
   947  }
   948  
   949  // ValueType gives the value type
   950  func (tv *TypedLeafListDecimal) ValueType() ValueType {
   951  	return tv.Type
   952  }
   953  
   954  func (tv *TypedLeafListDecimal) String() string {
   955  	digits, precision := tv.List()
   956  	return fmt.Sprintf("%v %d", digits, precision)
   957  }
   958  
   959  // List extracts the leaf list values
   960  func (tv *TypedLeafListDecimal) List() ([]int64, uint8) {
   961  	count := (len(tv.TypeOpts) - 1) / 2
   962  
   963  	digitsList := make([]int64, 0)
   964  	precision := uint8(tv.TypeOpts[0])
   965  	var byteCounter int32 = 0
   966  	for i := 0; i < count; i++ {
   967  		v := tv.Bytes[byteCounter : byteCounter+tv.TypeOpts[1+i*2]]
   968  		byteCounter = byteCounter + tv.TypeOpts[1+i*2]
   969  		var bigInt big.Int
   970  		bigInt.SetBytes(v)
   971  		negative := tv.TypeOpts[1+i*2+1]
   972  		if negative != isPositiveTypeOpt {
   973  			bigInt.Neg(&bigInt)
   974  		}
   975  		digitsList = append(digitsList, bigInt.Int64())
   976  	}
   977  
   978  	return digitsList, precision
   979  }
   980  
   981  // ListFloat extracts the leaf list values as floats
   982  func (tv *TypedLeafListDecimal) ListFloat() []float64 {
   983  	digits, precision := tv.List()
   984  	floatList := make([]float64, len(digits))
   985  	for i, d := range digits {
   986  		floatList[i] = float64(d) / math.Pow(10, float64(precision))
   987  	}
   988  
   989  	return floatList
   990  }
   991  
   992  ////////////////////////////////////////////////////////////////////////////////
   993  // TypedLeafListFloat
   994  ////////////////////////////////////////////////////////////////////////////////
   995  
   996  // TypedLeafListFloat for a decimal leaf list
   997  type TypedLeafListFloat TypedValue
   998  
   999  // NewLeafListFloatTv decodes float values in to a Leaf list
  1000  func NewLeafListFloatTv(values []float32) *TypedValue {
  1001  	return (*TypedValue)(newLeafListFloat(values))
  1002  }
  1003  
  1004  // newLeafListFloat decodes float values in to a Leaf list type
  1005  func newLeafListFloat(values []float32) *TypedLeafListFloat {
  1006  	bytes := make([]byte, 0)
  1007  	for _, f := range values {
  1008  		buf := make([]byte, 8)
  1009  		binary.LittleEndian.PutUint64(buf, math.Float64bits(float64(f)))
  1010  		bytes = append(bytes, buf...)
  1011  	}
  1012  	typedLeafListFloat := TypedLeafListFloat{
  1013  		Bytes: bytes,
  1014  		Type:  ValueType_LEAFLIST_FLOAT,
  1015  	}
  1016  	return &typedLeafListFloat
  1017  }
  1018  
  1019  // ValueType gives the value type
  1020  func (tv *TypedLeafListFloat) ValueType() ValueType {
  1021  	return tv.Type
  1022  }
  1023  
  1024  func (tv *TypedLeafListFloat) String() string {
  1025  	listStr := make([]string, 0)
  1026  	for _, f := range tv.List() {
  1027  		listStr = append(listStr, fmt.Sprintf("%f", f))
  1028  	}
  1029  
  1030  	return strings.Join(listStr, ",")
  1031  }
  1032  
  1033  // List extracts the leaf list values
  1034  func (tv *TypedLeafListFloat) List() []float32 {
  1035  	count := len(tv.Bytes) / 8
  1036  	float32s := make([]float32, 0)
  1037  
  1038  	for i := 0; i < count; i++ {
  1039  		v := tv.Bytes[i*8 : i*8+8]
  1040  		float32s = append(float32s, float32(math.Float64frombits(binary.LittleEndian.Uint64(v))))
  1041  	}
  1042  
  1043  	return float32s
  1044  }
  1045  
  1046  ////////////////////////////////////////////////////////////////////////////////
  1047  // TypedLeafListDouble
  1048  ////////////////////////////////////////////////////////////////////////////////
  1049  
  1050  // TypedLeafListDouble for a Double leaf list
  1051  type TypedLeafListDouble TypedValue
  1052  
  1053  // NewLeafListDoubleTv decodes double values in to a Leaf list
  1054  func NewLeafListDoubleTv(values []float64) *TypedValue {
  1055  	return (*TypedValue)(newLeafListDouble(values))
  1056  }
  1057  
  1058  // newLeafListDouble decodes double values in to a Leaf list type
  1059  func newLeafListDouble(values []float64) *TypedLeafListDouble {
  1060  	bytes := make([]byte, 0)
  1061  	for _, f := range values {
  1062  		buf := make([]byte, 8)
  1063  		binary.LittleEndian.PutUint64(buf, math.Float64bits(float64(f)))
  1064  		bytes = append(bytes, buf...)
  1065  	}
  1066  	typedLeafListDouble := TypedLeafListDouble{
  1067  		Bytes: bytes,
  1068  		Type:  ValueType_LEAFLIST_DOUBLE,
  1069  	}
  1070  	return &typedLeafListDouble
  1071  }
  1072  
  1073  // ValueType gives the value type
  1074  func (tv *TypedLeafListDouble) ValueType() ValueType {
  1075  	return tv.Type
  1076  }
  1077  
  1078  func (tv *TypedLeafListDouble) String() string {
  1079  	listStr := make([]string, 0)
  1080  	for _, f := range tv.ListDouble() {
  1081  		listStr = append(listStr, fmt.Sprintf("%f", f))
  1082  	}
  1083  
  1084  	return strings.Join(listStr, ",")
  1085  }
  1086  
  1087  // ListDouble extracts the leaf list values
  1088  func (tv *TypedLeafListDouble) ListDouble() []float64 {
  1089  	count := len(tv.Bytes) / 8
  1090  	doubles := make([]float64, 0)
  1091  
  1092  	for i := 0; i < count; i++ {
  1093  		v := tv.Bytes[i*8 : i*8+8]
  1094  		doubles = append(doubles, float64(math.Float64frombits(binary.LittleEndian.Uint64(v))))
  1095  	}
  1096  
  1097  	return doubles
  1098  }
  1099  
  1100  ////////////////////////////////////////////////////////////////////////////////
  1101  // TypedLeafListBytes
  1102  ////////////////////////////////////////////////////////////////////////////////
  1103  
  1104  // TypedLeafListBytes for an bool leaf list
  1105  type TypedLeafListBytes TypedValue
  1106  
  1107  // NewLeafListBytesTv decodes byte values in to a Leaf list
  1108  func NewLeafListBytesTv(values [][]byte) *TypedValue {
  1109  	return (*TypedValue)(newLeafListBytes(values))
  1110  }
  1111  
  1112  // newLeafListBytes decodes byte values in to a Leaf list type
  1113  func newLeafListBytes(values [][]byte) *TypedLeafListBytes {
  1114  	bytes := make([]byte, 0)
  1115  	typeopts := make([]int32, 0)
  1116  	for _, v := range values {
  1117  		bytes = append(bytes, v...)
  1118  		typeopts = append(typeopts, int32(len(v)))
  1119  	}
  1120  	typedLeafListBytes := TypedLeafListBytes{
  1121  		Bytes:    bytes,
  1122  		Type:     ValueType_LEAFLIST_BYTES, // Contains the lengths of each byte array in list
  1123  		TypeOpts: typeopts,
  1124  	}
  1125  	return &typedLeafListBytes
  1126  }
  1127  
  1128  // ValueType gives the value type
  1129  func (tv *TypedLeafListBytes) ValueType() ValueType {
  1130  	return tv.Type
  1131  }
  1132  
  1133  func (tv *TypedLeafListBytes) String() string {
  1134  	return fmt.Sprintf("%v", tv.List())
  1135  }
  1136  
  1137  // List extracts the leaf list values
  1138  func (tv *TypedLeafListBytes) List() [][]byte {
  1139  	bytes := make([][]byte, 0)
  1140  	buf := make([]byte, 0)
  1141  	idx := 0
  1142  	startAt := 0
  1143  	for i, b := range tv.Bytes {
  1144  		valueLen := tv.TypeOpts[idx]
  1145  		if i-startAt == int(valueLen) {
  1146  			bytes = append(bytes, buf)
  1147  			buf = make([]byte, 0)
  1148  			idx = idx + 1
  1149  			startAt = startAt + int(valueLen)
  1150  		}
  1151  		buf = append(buf, b)
  1152  	}
  1153  	bytes = append(bytes, buf)
  1154  	return bytes
  1155  }
  1156  
  1157  func strDecimal64(digits int64, precision uint8) string {
  1158  	var i, frac int64
  1159  	if precision > 0 {
  1160  		div := int64(10)
  1161  		it := precision - 1
  1162  		for it > 0 {
  1163  			div *= 10
  1164  			it--
  1165  		}
  1166  		i = digits / div
  1167  		frac = digits % div
  1168  	} else {
  1169  		i = digits
  1170  	}
  1171  	if frac < 0 {
  1172  		frac = -frac
  1173  	}
  1174  	if precision == 0 {
  1175  		return fmt.Sprintf("%d", i)
  1176  	}
  1177  	fmtString := fmt.Sprintf("%s0.%d%s", "%d.%", precision, "d")
  1178  	return fmt.Sprintf(fmtString, i, frac)
  1179  }