github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/uint256/conversion.gno (about)

     1  // conversions contains methods for converting Uint instances to other types and vice versa.
     2  // This includes conversions to and from basic types such as uint64 and int32, as well as string representations
     3  // and byte slices. Additionally, it covers marshaling and unmarshaling for JSON and other text formats.
     4  package uint256
     5  
     6  import (
     7  	"encoding/binary"
     8  	"errors"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  // Uint64 returns the lower 64-bits of z
    14  func (z *Uint) Uint64() uint64 {
    15  	return z.arr[0]
    16  }
    17  
    18  // Uint64WithOverflow returns the lower 64-bits of z and bool whether overflow occurred
    19  func (z *Uint) Uint64WithOverflow() (uint64, bool) {
    20  	return z.arr[0], (z.arr[1] | z.arr[2] | z.arr[3]) != 0
    21  }
    22  
    23  // SetUint64 sets z to the value x
    24  func (z *Uint) SetUint64(x uint64) *Uint {
    25  	z.arr[3], z.arr[2], z.arr[1], z.arr[0] = 0, 0, 0, x
    26  	return z
    27  }
    28  
    29  // IsUint64 reports whether z can be represented as a uint64.
    30  func (z *Uint) IsUint64() bool {
    31  	return (z.arr[1] | z.arr[2] | z.arr[3]) == 0
    32  }
    33  
    34  // Dec returns the decimal representation of z.
    35  func (z *Uint) Dec() string {
    36  	if z.IsZero() {
    37  		return "0"
    38  	}
    39  	if z.IsUint64() {
    40  		return strconv.FormatUint(z.Uint64(), 10)
    41  	}
    42  
    43  	// The max uint64 value being 18446744073709551615, the largest
    44  	// power-of-ten below that is 10000000000000000000.
    45  	// When we do a DivMod using that number, the remainder that we
    46  	// get back is the lower part of the output.
    47  	//
    48  	// The ascii-output of remainder will never exceed 19 bytes (since it will be
    49  	// below 10000000000000000000).
    50  	//
    51  	// Algorithm example using 100 as divisor
    52  	//
    53  	// 12345 % 100 = 45   (rem)
    54  	// 12345 / 100 = 123  (quo)
    55  	// -> output '45', continue iterate on 123
    56  	var (
    57  		// out is 98 bytes long: 78 (max size of a string without leading zeroes,
    58  		// plus slack so we can copy 19 bytes every iteration).
    59  		// We init it with zeroes, because when strconv appends the ascii representations,
    60  		// it will omit leading zeroes.
    61  		out     = []byte("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
    62  		divisor = NewUint(10000000000000000000) // 20 digits
    63  		y       = new(Uint).Set(z)              // copy to avoid modifying z
    64  		pos     = len(out)                      // position to write to
    65  		buf     = make([]byte, 0, 19)           // buffer to write uint64:s to
    66  	)
    67  	for {
    68  		// Obtain Q and R for divisor
    69  		var quot Uint
    70  		rem := udivrem(quot.arr[:], y.arr[:], divisor)
    71  		y.Set(&quot) // Set Q for next loop
    72  		// Convert the R to ascii representation
    73  		buf = strconv.AppendUint(buf[:0], rem.Uint64(), 10)
    74  		// Copy in the ascii digits
    75  		copy(out[pos-len(buf):], buf)
    76  		if y.IsZero() {
    77  			break
    78  		}
    79  		// Move 19 digits left
    80  		pos -= 19
    81  	}
    82  	// skip leading zeroes by only using the 'used size' of buf
    83  	return string(out[pos-len(buf):])
    84  }
    85  
    86  func (z *Uint) Scan(src interface{}) error {
    87  	if src == nil {
    88  		z.Clear()
    89  		return nil
    90  	}
    91  
    92  	switch src := src.(type) {
    93  	case string:
    94  		return z.scanScientificFromString(src)
    95  	case []byte:
    96  		return z.scanScientificFromString(string(src))
    97  	}
    98  	return errors.New("default // unsupported type: can't convert to uint256.Uint")
    99  }
   100  
   101  func (z *Uint) scanScientificFromString(src string) error {
   102  	if len(src) == 0 {
   103  		z.Clear()
   104  		return nil
   105  	}
   106  
   107  	idx := strings.IndexByte(src, 'e')
   108  	if idx == -1 {
   109  		return z.SetFromDecimal(src)
   110  	}
   111  	if err := z.SetFromDecimal(src[:idx]); err != nil {
   112  		return err
   113  	}
   114  	if src[(idx+1):] == "0" {
   115  		return nil
   116  	}
   117  	exp := new(Uint)
   118  	if err := exp.SetFromDecimal(src[(idx + 1):]); err != nil {
   119  		return err
   120  	}
   121  	if exp.GtUint64(77) { // 10**78 is larger than 2**256
   122  		return ErrBig256Range
   123  	}
   124  	exp.Exp(NewUint(10), exp)
   125  	if _, overflow := z.MulOverflow(z, exp); overflow {
   126  		return ErrBig256Range
   127  	}
   128  	return nil
   129  }
   130  
   131  // ToString returns the decimal string representation of z. It returns an empty string if z is nil.
   132  // OBS: doesn't exist from holiman's uint256
   133  func (z *Uint) ToString() string {
   134  	if z == nil {
   135  		return ""
   136  	}
   137  
   138  	return z.Dec()
   139  }
   140  
   141  // MarshalJSON implements json.Marshaler.
   142  // MarshalJSON marshals using the 'decimal string' representation. This is _not_ compatible
   143  // with big.Uint: big.Uint marshals into JSON 'native' numeric format.
   144  //
   145  // The JSON  native format is, on some platforms, (e.g. javascript), limited to 53-bit large
   146  // integer space. Thus, U256 uses string-format, which is not compatible with
   147  // big.int (big.Uint refuses to unmarshal a string representation).
   148  func (z *Uint) MarshalJSON() ([]byte, error) {
   149  	return []byte(`"` + z.Dec() + `"`), nil
   150  }
   151  
   152  // UnmarshalJSON implements json.Unmarshaler. UnmarshalJSON accepts either
   153  // - Quoted string: either hexadecimal OR decimal
   154  // - Not quoted string: only decimal
   155  func (z *Uint) UnmarshalJSON(input []byte) error {
   156  	if len(input) < 2 || input[0] != '"' || input[len(input)-1] != '"' {
   157  		// if not quoted, it must be decimal
   158  		return z.fromDecimal(string(input))
   159  	}
   160  	return z.UnmarshalText(input[1 : len(input)-1])
   161  }
   162  
   163  // MarshalText implements encoding.TextMarshaler
   164  // MarshalText marshals using the decimal representation (compatible with big.Uint)
   165  func (z *Uint) MarshalText() ([]byte, error) {
   166  	return []byte(z.Dec()), nil
   167  }
   168  
   169  // UnmarshalText implements encoding.TextUnmarshaler. This method
   170  // can unmarshal either hexadecimal or decimal.
   171  // - For hexadecimal, the input _must_ be prefixed with 0x or 0X
   172  func (z *Uint) UnmarshalText(input []byte) error {
   173  	if len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X') {
   174  		return z.fromHex(string(input))
   175  	}
   176  	return z.fromDecimal(string(input))
   177  }
   178  
   179  // SetBytes interprets buf as the bytes of a big-endian unsigned
   180  // integer, sets z to that value, and returns z.
   181  // If buf is larger than 32 bytes, the last 32 bytes is used.
   182  func (z *Uint) SetBytes(buf []byte) *Uint {
   183  	switch l := len(buf); l {
   184  	case 0:
   185  		z.Clear()
   186  	case 1:
   187  		z.SetBytes1(buf)
   188  	case 2:
   189  		z.SetBytes2(buf)
   190  	case 3:
   191  		z.SetBytes3(buf)
   192  	case 4:
   193  		z.SetBytes4(buf)
   194  	case 5:
   195  		z.SetBytes5(buf)
   196  	case 6:
   197  		z.SetBytes6(buf)
   198  	case 7:
   199  		z.SetBytes7(buf)
   200  	case 8:
   201  		z.SetBytes8(buf)
   202  	case 9:
   203  		z.SetBytes9(buf)
   204  	case 10:
   205  		z.SetBytes10(buf)
   206  	case 11:
   207  		z.SetBytes11(buf)
   208  	case 12:
   209  		z.SetBytes12(buf)
   210  	case 13:
   211  		z.SetBytes13(buf)
   212  	case 14:
   213  		z.SetBytes14(buf)
   214  	case 15:
   215  		z.SetBytes15(buf)
   216  	case 16:
   217  		z.SetBytes16(buf)
   218  	case 17:
   219  		z.SetBytes17(buf)
   220  	case 18:
   221  		z.SetBytes18(buf)
   222  	case 19:
   223  		z.SetBytes19(buf)
   224  	case 20:
   225  		z.SetBytes20(buf)
   226  	case 21:
   227  		z.SetBytes21(buf)
   228  	case 22:
   229  		z.SetBytes22(buf)
   230  	case 23:
   231  		z.SetBytes23(buf)
   232  	case 24:
   233  		z.SetBytes24(buf)
   234  	case 25:
   235  		z.SetBytes25(buf)
   236  	case 26:
   237  		z.SetBytes26(buf)
   238  	case 27:
   239  		z.SetBytes27(buf)
   240  	case 28:
   241  		z.SetBytes28(buf)
   242  	case 29:
   243  		z.SetBytes29(buf)
   244  	case 30:
   245  		z.SetBytes30(buf)
   246  	case 31:
   247  		z.SetBytes31(buf)
   248  	default:
   249  		z.SetBytes32(buf[l-32:])
   250  	}
   251  	return z
   252  }
   253  
   254  // SetBytes1 is identical to SetBytes(in[:1]), but panics is input is too short
   255  func (z *Uint) SetBytes1(in []byte) *Uint {
   256  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   257  	z.arr[0] = uint64(in[0])
   258  	return z
   259  }
   260  
   261  // SetBytes2 is identical to SetBytes(in[:2]), but panics is input is too short
   262  func (z *Uint) SetBytes2(in []byte) *Uint {
   263  	_ = in[1] // bounds check hint to compiler; see golang.org/issue/14808
   264  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   265  	z.arr[0] = uint64(binary.BigEndian.Uint16(in[0:2]))
   266  	return z
   267  }
   268  
   269  // SetBytes3 is identical to SetBytes(in[:3]), but panics is input is too short
   270  func (z *Uint) SetBytes3(in []byte) *Uint {
   271  	_ = in[2] // bounds check hint to compiler; see golang.org/issue/14808
   272  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   273  	z.arr[0] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
   274  	return z
   275  }
   276  
   277  // SetBytes4 is identical to SetBytes(in[:4]), but panics is input is too short
   278  func (z *Uint) SetBytes4(in []byte) *Uint {
   279  	_ = in[3] // bounds check hint to compiler; see golang.org/issue/14808
   280  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   281  	z.arr[0] = uint64(binary.BigEndian.Uint32(in[0:4]))
   282  	return z
   283  }
   284  
   285  // SetBytes5 is identical to SetBytes(in[:5]), but panics is input is too short
   286  func (z *Uint) SetBytes5(in []byte) *Uint {
   287  	_ = in[4] // bounds check hint to compiler; see golang.org/issue/14808
   288  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   289  	z.arr[0] = bigEndianUint40(in[0:5])
   290  	return z
   291  }
   292  
   293  // SetBytes6 is identical to SetBytes(in[:6]), but panics is input is too short
   294  func (z *Uint) SetBytes6(in []byte) *Uint {
   295  	_ = in[5] // bounds check hint to compiler; see golang.org/issue/14808
   296  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   297  	z.arr[0] = bigEndianUint48(in[0:6])
   298  	return z
   299  }
   300  
   301  // SetBytes7 is identical to SetBytes(in[:7]), but panics is input is too short
   302  func (z *Uint) SetBytes7(in []byte) *Uint {
   303  	_ = in[6] // bounds check hint to compiler; see golang.org/issue/14808
   304  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   305  	z.arr[0] = bigEndianUint56(in[0:7])
   306  	return z
   307  }
   308  
   309  // SetBytes8 is identical to SetBytes(in[:8]), but panics is input is too short
   310  func (z *Uint) SetBytes8(in []byte) *Uint {
   311  	_ = in[7] // bounds check hint to compiler; see golang.org/issue/14808
   312  	z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
   313  	z.arr[0] = binary.BigEndian.Uint64(in[0:8])
   314  	return z
   315  }
   316  
   317  // SetBytes9 is identical to SetBytes(in[:9]), but panics is input is too short
   318  func (z *Uint) SetBytes9(in []byte) *Uint {
   319  	_ = in[8] // bounds check hint to compiler; see golang.org/issue/14808
   320  	z.arr[3], z.arr[2] = 0, 0
   321  	z.arr[1] = uint64(in[0])
   322  	z.arr[0] = binary.BigEndian.Uint64(in[1:9])
   323  	return z
   324  }
   325  
   326  // SetBytes10 is identical to SetBytes(in[:10]), but panics is input is too short
   327  func (z *Uint) SetBytes10(in []byte) *Uint {
   328  	_ = in[9] // bounds check hint to compiler; see golang.org/issue/14808
   329  	z.arr[3], z.arr[2] = 0, 0
   330  	z.arr[1] = uint64(binary.BigEndian.Uint16(in[0:2]))
   331  	z.arr[0] = binary.BigEndian.Uint64(in[2:10])
   332  	return z
   333  }
   334  
   335  // SetBytes11 is identical to SetBytes(in[:11]), but panics is input is too short
   336  func (z *Uint) SetBytes11(in []byte) *Uint {
   337  	_ = in[10] // bounds check hint to compiler; see golang.org/issue/14808
   338  	z.arr[3], z.arr[2] = 0, 0
   339  	z.arr[1] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
   340  	z.arr[0] = binary.BigEndian.Uint64(in[3:11])
   341  	return z
   342  }
   343  
   344  // SetBytes12 is identical to SetBytes(in[:12]), but panics is input is too short
   345  func (z *Uint) SetBytes12(in []byte) *Uint {
   346  	_ = in[11] // bounds check hint to compiler; see golang.org/issue/14808
   347  	z.arr[3], z.arr[2] = 0, 0
   348  	z.arr[1] = uint64(binary.BigEndian.Uint32(in[0:4]))
   349  	z.arr[0] = binary.BigEndian.Uint64(in[4:12])
   350  	return z
   351  }
   352  
   353  // SetBytes13 is identical to SetBytes(in[:13]), but panics is input is too short
   354  func (z *Uint) SetBytes13(in []byte) *Uint {
   355  	_ = in[12] // bounds check hint to compiler; see golang.org/issue/14808
   356  	z.arr[3], z.arr[2] = 0, 0
   357  	z.arr[1] = bigEndianUint40(in[0:5])
   358  	z.arr[0] = binary.BigEndian.Uint64(in[5:13])
   359  	return z
   360  }
   361  
   362  // SetBytes14 is identical to SetBytes(in[:14]), but panics is input is too short
   363  func (z *Uint) SetBytes14(in []byte) *Uint {
   364  	_ = in[13] // bounds check hint to compiler; see golang.org/issue/14808
   365  	z.arr[3], z.arr[2] = 0, 0
   366  	z.arr[1] = bigEndianUint48(in[0:6])
   367  	z.arr[0] = binary.BigEndian.Uint64(in[6:14])
   368  	return z
   369  }
   370  
   371  // SetBytes15 is identical to SetBytes(in[:15]), but panics is input is too short
   372  func (z *Uint) SetBytes15(in []byte) *Uint {
   373  	_ = in[14] // bounds check hint to compiler; see golang.org/issue/14808
   374  	z.arr[3], z.arr[2] = 0, 0
   375  	z.arr[1] = bigEndianUint56(in[0:7])
   376  	z.arr[0] = binary.BigEndian.Uint64(in[7:15])
   377  	return z
   378  }
   379  
   380  // SetBytes16 is identical to SetBytes(in[:16]), but panics is input is too short
   381  func (z *Uint) SetBytes16(in []byte) *Uint {
   382  	_ = in[15] // bounds check hint to compiler; see golang.org/issue/14808
   383  	z.arr[3], z.arr[2] = 0, 0
   384  	z.arr[1] = binary.BigEndian.Uint64(in[0:8])
   385  	z.arr[0] = binary.BigEndian.Uint64(in[8:16])
   386  	return z
   387  }
   388  
   389  // SetBytes17 is identical to SetBytes(in[:17]), but panics is input is too short
   390  func (z *Uint) SetBytes17(in []byte) *Uint {
   391  	_ = in[16] // bounds check hint to compiler; see golang.org/issue/14808
   392  	z.arr[3] = 0
   393  	z.arr[2] = uint64(in[0])
   394  	z.arr[1] = binary.BigEndian.Uint64(in[1:9])
   395  	z.arr[0] = binary.BigEndian.Uint64(in[9:17])
   396  	return z
   397  }
   398  
   399  // SetBytes18 is identical to SetBytes(in[:18]), but panics is input is too short
   400  func (z *Uint) SetBytes18(in []byte) *Uint {
   401  	_ = in[17] // bounds check hint to compiler; see golang.org/issue/14808
   402  	z.arr[3] = 0
   403  	z.arr[2] = uint64(binary.BigEndian.Uint16(in[0:2]))
   404  	z.arr[1] = binary.BigEndian.Uint64(in[2:10])
   405  	z.arr[0] = binary.BigEndian.Uint64(in[10:18])
   406  	return z
   407  }
   408  
   409  // SetBytes19 is identical to SetBytes(in[:19]), but panics is input is too short
   410  func (z *Uint) SetBytes19(in []byte) *Uint {
   411  	_ = in[18] // bounds check hint to compiler; see golang.org/issue/14808
   412  	z.arr[3] = 0
   413  	z.arr[2] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
   414  	z.arr[1] = binary.BigEndian.Uint64(in[3:11])
   415  	z.arr[0] = binary.BigEndian.Uint64(in[11:19])
   416  	return z
   417  }
   418  
   419  // SetBytes20 is identical to SetBytes(in[:20]), but panics is input is too short
   420  func (z *Uint) SetBytes20(in []byte) *Uint {
   421  	_ = in[19] // bounds check hint to compiler; see golang.org/issue/14808
   422  	z.arr[3] = 0
   423  	z.arr[2] = uint64(binary.BigEndian.Uint32(in[0:4]))
   424  	z.arr[1] = binary.BigEndian.Uint64(in[4:12])
   425  	z.arr[0] = binary.BigEndian.Uint64(in[12:20])
   426  	return z
   427  }
   428  
   429  // SetBytes21 is identical to SetBytes(in[:21]), but panics is input is too short
   430  func (z *Uint) SetBytes21(in []byte) *Uint {
   431  	_ = in[20] // bounds check hint to compiler; see golang.org/issue/14808
   432  	z.arr[3] = 0
   433  	z.arr[2] = bigEndianUint40(in[0:5])
   434  	z.arr[1] = binary.BigEndian.Uint64(in[5:13])
   435  	z.arr[0] = binary.BigEndian.Uint64(in[13:21])
   436  	return z
   437  }
   438  
   439  // SetBytes22 is identical to SetBytes(in[:22]), but panics is input is too short
   440  func (z *Uint) SetBytes22(in []byte) *Uint {
   441  	_ = in[21] // bounds check hint to compiler; see golang.org/issue/14808
   442  	z.arr[3] = 0
   443  	z.arr[2] = bigEndianUint48(in[0:6])
   444  	z.arr[1] = binary.BigEndian.Uint64(in[6:14])
   445  	z.arr[0] = binary.BigEndian.Uint64(in[14:22])
   446  	return z
   447  }
   448  
   449  // SetBytes23 is identical to SetBytes(in[:23]), but panics is input is too short
   450  func (z *Uint) SetBytes23(in []byte) *Uint {
   451  	_ = in[22] // bounds check hint to compiler; see golang.org/issue/14808
   452  	z.arr[3] = 0
   453  	z.arr[2] = bigEndianUint56(in[0:7])
   454  	z.arr[1] = binary.BigEndian.Uint64(in[7:15])
   455  	z.arr[0] = binary.BigEndian.Uint64(in[15:23])
   456  	return z
   457  }
   458  
   459  // SetBytes24 is identical to SetBytes(in[:24]), but panics is input is too short
   460  func (z *Uint) SetBytes24(in []byte) *Uint {
   461  	_ = in[23] // bounds check hint to compiler; see golang.org/issue/14808
   462  	z.arr[3] = 0
   463  	z.arr[2] = binary.BigEndian.Uint64(in[0:8])
   464  	z.arr[1] = binary.BigEndian.Uint64(in[8:16])
   465  	z.arr[0] = binary.BigEndian.Uint64(in[16:24])
   466  	return z
   467  }
   468  
   469  // SetBytes25 is identical to SetBytes(in[:25]), but panics is input is too short
   470  func (z *Uint) SetBytes25(in []byte) *Uint {
   471  	_ = in[24] // bounds check hint to compiler; see golang.org/issue/14808
   472  	z.arr[3] = uint64(in[0])
   473  	z.arr[2] = binary.BigEndian.Uint64(in[1:9])
   474  	z.arr[1] = binary.BigEndian.Uint64(in[9:17])
   475  	z.arr[0] = binary.BigEndian.Uint64(in[17:25])
   476  	return z
   477  }
   478  
   479  // SetBytes26 is identical to SetBytes(in[:26]), but panics is input is too short
   480  func (z *Uint) SetBytes26(in []byte) *Uint {
   481  	_ = in[25] // bounds check hint to compiler; see golang.org/issue/14808
   482  	z.arr[3] = uint64(binary.BigEndian.Uint16(in[0:2]))
   483  	z.arr[2] = binary.BigEndian.Uint64(in[2:10])
   484  	z.arr[1] = binary.BigEndian.Uint64(in[10:18])
   485  	z.arr[0] = binary.BigEndian.Uint64(in[18:26])
   486  	return z
   487  }
   488  
   489  // SetBytes27 is identical to SetBytes(in[:27]), but panics is input is too short
   490  func (z *Uint) SetBytes27(in []byte) *Uint {
   491  	_ = in[26] // bounds check hint to compiler; see golang.org/issue/14808
   492  	z.arr[3] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
   493  	z.arr[2] = binary.BigEndian.Uint64(in[3:11])
   494  	z.arr[1] = binary.BigEndian.Uint64(in[11:19])
   495  	z.arr[0] = binary.BigEndian.Uint64(in[19:27])
   496  	return z
   497  }
   498  
   499  // SetBytes28 is identical to SetBytes(in[:28]), but panics is input is too short
   500  func (z *Uint) SetBytes28(in []byte) *Uint {
   501  	_ = in[27] // bounds check hint to compiler; see golang.org/issue/14808
   502  	z.arr[3] = uint64(binary.BigEndian.Uint32(in[0:4]))
   503  	z.arr[2] = binary.BigEndian.Uint64(in[4:12])
   504  	z.arr[1] = binary.BigEndian.Uint64(in[12:20])
   505  	z.arr[0] = binary.BigEndian.Uint64(in[20:28])
   506  	return z
   507  }
   508  
   509  // SetBytes29 is identical to SetBytes(in[:29]), but panics is input is too short
   510  func (z *Uint) SetBytes29(in []byte) *Uint {
   511  	_ = in[23] // bounds check hint to compiler; see golang.org/issue/14808
   512  	z.arr[3] = bigEndianUint40(in[0:5])
   513  	z.arr[2] = binary.BigEndian.Uint64(in[5:13])
   514  	z.arr[1] = binary.BigEndian.Uint64(in[13:21])
   515  	z.arr[0] = binary.BigEndian.Uint64(in[21:29])
   516  	return z
   517  }
   518  
   519  // SetBytes30 is identical to SetBytes(in[:30]), but panics is input is too short
   520  func (z *Uint) SetBytes30(in []byte) *Uint {
   521  	_ = in[29] // bounds check hint to compiler; see golang.org/issue/14808
   522  	z.arr[3] = bigEndianUint48(in[0:6])
   523  	z.arr[2] = binary.BigEndian.Uint64(in[6:14])
   524  	z.arr[1] = binary.BigEndian.Uint64(in[14:22])
   525  	z.arr[0] = binary.BigEndian.Uint64(in[22:30])
   526  	return z
   527  }
   528  
   529  // SetBytes31 is identical to SetBytes(in[:31]), but panics is input is too short
   530  func (z *Uint) SetBytes31(in []byte) *Uint {
   531  	_ = in[30] // bounds check hint to compiler; see golang.org/issue/14808
   532  	z.arr[3] = bigEndianUint56(in[0:7])
   533  	z.arr[2] = binary.BigEndian.Uint64(in[7:15])
   534  	z.arr[1] = binary.BigEndian.Uint64(in[15:23])
   535  	z.arr[0] = binary.BigEndian.Uint64(in[23:31])
   536  	return z
   537  }
   538  
   539  // SetBytes32 sets z to the value of the big-endian 256-bit unsigned integer in.
   540  func (z *Uint) SetBytes32(in []byte) *Uint {
   541  	_ = in[31] // bounds check hint to compiler; see golang.org/issue/14808
   542  	z.arr[3] = binary.BigEndian.Uint64(in[0:8])
   543  	z.arr[2] = binary.BigEndian.Uint64(in[8:16])
   544  	z.arr[1] = binary.BigEndian.Uint64(in[16:24])
   545  	z.arr[0] = binary.BigEndian.Uint64(in[24:32])
   546  	return z
   547  }
   548  
   549  // Utility methods that are "missing" among the bigEndian.UintXX methods.
   550  
   551  // bigEndianUint40 returns the uint64 value represented by the 5 bytes in big-endian order.
   552  func bigEndianUint40(b []byte) uint64 {
   553  	_ = b[4] // bounds check hint to compiler; see golang.org/issue/14808
   554  	return uint64(b[4]) | uint64(b[3])<<8 | uint64(b[2])<<16 | uint64(b[1])<<24 |
   555  		uint64(b[0])<<32
   556  }
   557  
   558  // bigEndianUint56 returns the uint64 value represented by the 7 bytes in big-endian order.
   559  func bigEndianUint56(b []byte) uint64 {
   560  	_ = b[6] // bounds check hint to compiler; see golang.org/issue/14808
   561  	return uint64(b[6]) | uint64(b[5])<<8 | uint64(b[4])<<16 | uint64(b[3])<<24 |
   562  		uint64(b[2])<<32 | uint64(b[1])<<40 | uint64(b[0])<<48
   563  }
   564  
   565  // bigEndianUint48 returns the uint64 value represented by the 6 bytes in big-endian order.
   566  func bigEndianUint48(b []byte) uint64 {
   567  	_ = b[5] // bounds check hint to compiler; see golang.org/issue/14808
   568  	return uint64(b[5]) | uint64(b[4])<<8 | uint64(b[3])<<16 | uint64(b[2])<<24 |
   569  		uint64(b[1])<<32 | uint64(b[0])<<40
   570  }