github.com/quantosnetwork/Quantos@v0.0.0-20220306172517-e20b28c5a29a/encoder/encodeInt.go (about)

     1  package encoder
     2  
     3  
     4  import "unsafe"
     5  
     6  const intMask uint64 = 1<<(32<<(^uint(0)>>63)) - 1
     7  
     8  var intLookup [100]uint16
     9  
    10  // "00010203...96979899" cast to []uint16
    11  var intLELookup = [100]uint16{
    12  	0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930,
    13  	0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931,
    14  	0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932,
    15  	0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933,
    16  	0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934,
    17  	0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935,
    18  	0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936,
    19  	0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937,
    20  	0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938,
    21  	0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939,
    22  }
    23  
    24  func init() {
    25  	var b [2]byte
    26  	*(*uint16)(unsafe.Pointer(&b)) = uint16(0xABCD)
    27  	switch b[0] {
    28  	case 0xCD:
    29  		intLookup = intLELookup
    30  	case 0xAB:
    31  		intLookup = [100]uint16{
    32  			0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, 0x3038, 0x3039,
    33  			0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, 0x3139,
    34  			0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239,
    35  			0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 0x3338, 0x3339,
    36  			0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, 0x3438, 0x3439,
    37  			0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, 0x3539,
    38  			0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639,
    39  			0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739,
    40  			0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, 0x3838, 0x3839,
    41  			0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939,
    42  		}
    43  	default:
    44  		panic("could not determine endianness")
    45  	}
    46  }
    47  
    48  //go:nosplit
    49  func (e *Encoder) writeInt(data int64) {
    50  	u64 := uint64(data)
    51  	n := u64 & intMask
    52  	negative := data < 0
    53  	if !negative {
    54  		if n < 10 {
    55  			e.writeByte(byte(n + '0'))
    56  			return
    57  		} else if n < 100 {
    58  			memmov(
    59  				unsafe.Pointer(uintptr((*sliceHeader)(unsafe.Pointer(&e.buffer)).data)+uintptr(e.offset)),
    60  				unsafe.Pointer(&intLELookup[n]),
    61  				2,
    62  			)
    63  			e.offset += 2
    64  			return
    65  		}
    66  	} else {
    67  		n = -n & intMask
    68  	}
    69  	var b [22]byte
    70  	u := (*[11]uint16)(unsafe.Pointer(&b))
    71  	i := 11
    72  	for n >= 100 {
    73  		j := n % 100
    74  		n /= 100
    75  		i--
    76  		u[i] = intLookup[j]
    77  	}
    78  	i--
    79  	u[i] = intLookup[n]
    80  	i *= 2 // convert to byte index
    81  	if n < 10 {
    82  		i++ // remove leading zero
    83  	}
    84  	if negative {
    85  		i--
    86  		b[i] = '-'
    87  	}
    88  	e.write(b[i:])
    89  }
    90  
    91  //go:nosplit
    92  func (e *Encoder) encodeInt(data int64) {
    93  	e.grow(24)
    94  	e.writeByte('i')
    95  	e.writeInt(data)
    96  	e.writeByte('e')
    97  }