forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
int64.go
77 lines (65 loc) · 1.54 KB
/
int64.go
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
package ormfield
import (
"encoding/binary"
io "io"
"google.golang.org/protobuf/reflect/protoreflect"
)
// Int64Codec encodes 64-bit integers as big-endian unsigned 64-bit integers
// by adding the maximum value of int32 (9223372036854775807) + 1 before encoding so
// that these values can be used for ordered iteration.
type Int64Codec struct{}
var int64Codec = Int64Codec{}
const int64Max = 9223372036854775807
func (i Int64Codec) Decode(r Reader) (protoreflect.Value, error) {
var x uint64
err := binary.Read(r, binary.BigEndian, &x)
if x >= int64Max {
x = x - int64Max - 1
return protoreflect.ValueOfInt64(int64(x)), err
} else {
y := int64(x) - int64Max - 1
return protoreflect.ValueOfInt64(y), err
}
}
func (i Int64Codec) Encode(value protoreflect.Value, w io.Writer) error {
var x int64
if value.IsValid() {
x = value.Int()
}
if x >= -1 {
y := uint64(x) + int64Max + 1
return binary.Write(w, binary.BigEndian, y)
} else {
x += int64Max
x += 1
return binary.Write(w, binary.BigEndian, uint64(x))
}
}
func (i Int64Codec) Compare(v1, v2 protoreflect.Value) int {
return compareInt(v1, v2)
}
func (i Int64Codec) IsOrdered() bool {
return true
}
func (i Int64Codec) FixedBufferSize() int {
return 8
}
func (i Int64Codec) ComputeBufferSize(protoreflect.Value) (int, error) {
return i.FixedBufferSize(), nil
}
func compareInt(v1, v2 protoreflect.Value) int {
var x, y int64
if v1.IsValid() {
x = v1.Int()
}
if v2.IsValid() {
y = v2.Int()
}
if x == y {
return 0
} else if x < y {
return -1
} else {
return 1
}
}