customu256.go 2.75 KB
Newer Older
vicotor's avatar
vicotor committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
/*
	Package custom contains custom types for test and example purposes.
	These types are used by the test structures generated by gogoprotobuf.
*/
package custom

import (
	"bytes"
	"encoding/json"
	"errors"
)

type Uint256 [4]uint64

func (u Uint256) Marshal() ([]byte, error) {
	buffer := make([]byte, 32)
	_, err := u.MarshalTo(buffer)
	return buffer, err
}

func (u Uint256) MarshalTo(data []byte) (n int, err error) {
	PutLittleEndianUint256(data, 0, u)
	return 16, nil
}

func GetLittleEndianUint64(b []byte, offset int) uint64 {
	v := uint64(b[offset+7]) << 56
	v += uint64(b[offset+6]) << 48
	v += uint64(b[offset+5]) << 40
	v += uint64(b[offset+4]) << 32
	v += uint64(b[offset+3]) << 24
	v += uint64(b[offset+2]) << 16
	v += uint64(b[offset+1]) << 8
	v += uint64(b[offset])
	return v
}

func PutLittleEndianUint64(b []byte, offset int, v uint64) {
	b[offset] = byte(v)
	b[offset+1] = byte(v >> 8)
	b[offset+2] = byte(v >> 16)
	b[offset+3] = byte(v >> 24)
	b[offset+4] = byte(v >> 32)
	b[offset+5] = byte(v >> 40)
	b[offset+6] = byte(v >> 48)
	b[offset+7] = byte(v >> 56)
}

func PutLittleEndianUint256(buffer []byte, offset int, v [4]uint64) {
	PutLittleEndianUint64(buffer, offset, v[0])
	PutLittleEndianUint64(buffer, offset+8, v[1])
	PutLittleEndianUint64(buffer, offset+16, v[2])
	PutLittleEndianUint64(buffer, offset+24, v[3])
}

func GetLittleEndianUint256(buffer []byte, offset int) (value [4]uint64) {
	value[0] = GetLittleEndianUint64(buffer, offset)
	value[1] = GetLittleEndianUint64(buffer, offset+8)
	value[2] = GetLittleEndianUint64(buffer, offset+16)
	value[3] = GetLittleEndianUint64(buffer, offset+24)
	return
}

func (u *Uint256) Unmarshal(data []byte) error {
	if data == nil {
		u = nil
		return nil
	}
	if len(data) == 0 {
		pu := Uint256{}
		*u = pu
		return nil
	}
	if len(data) != 32 {
		return errors.New("Uint256: invalid length")
	}
	pu := Uint256(GetLittleEndianUint256(data, 0))
	*u = pu
	return nil
}

func (u Uint256) MarshalJSON() ([]byte, error) {
	data, err := u.Marshal()
	if err != nil {
		return nil, err
	}
	return json.Marshal(data)
}

func (u Uint256) Size() int {
	return 32
}

func (u *Uint256) UnmarshalJSON(data []byte) error {
	v := new([]byte)
	err := json.Unmarshal(data, v)
	if err != nil {
		return err
	}
	return u.Unmarshal(*v)
}

func (this Uint256) Equal(that Uint256) bool {
	return this == that
}

func (this Uint256) Compare(that Uint256) int {
	thisdata, err := this.Marshal()
	if err != nil {
		panic(err)
	}
	thatdata, err := that.Marshal()
	if err != nil {
		panic(err)
	}
	return bytes.Compare(thisdata, thatdata)
}

type randy interface {
	Intn(n int) int
}

func NewPopulatedUint256(r randy) *Uint256 {
	data := make([]byte, 256)
	for i := 0; i < 32; i++ {
		data[i] = byte(r.Intn(255))
	}
	u := Uint256(GetLittleEndianUint256(data, 0))
	return &u
}