-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathinteger.go
89 lines (70 loc) · 1.48 KB
/
integer.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
78
79
80
81
82
83
84
85
86
87
88
89
package snmp
import (
"io"
)
// Int represents an SNMP INTEGER.
type Int int
// encodeInteger encodes a length-encoded integer.
func encodeInteger(i int) []byte {
result := []byte{}
if i == 0 {
result = append(result, 0)
}
if i < 0 {
minusOne := (-i) - 1
for minusOne > 0 {
result = append(result, byte((minusOne%256)^0xff))
minusOne >>= 8
}
if len(result) == 0 {
result = append(result, 0xff)
} else {
if result[len(result)-1]&0x80 == 0 {
result = append(result, 0xff)
}
}
} else {
for i > 0 {
result = append(result, byte(i%256))
i >>= 8
}
if result[len(result)-1]&0x80 != 0 {
result = append(result, 0x0)
}
}
return reverseSlice(result)
}
// Encode encodes an Int with the proper header.
func (i Int) Encode() ([]byte, error) {
result := encodeInteger(int(i))
return append(encodeHeaderSequence(0x02, len(result)), result...), nil
}
// decodeInteger decodes an integer up to length bytes from r.
// It returns the SNMP data type, the number of bytes read, and an error.
func decodeInteger(length int, r io.Reader) (Int, int, error) {
intBytes := make([]byte, int(length))
bytesRead := 0
n, err := r.Read(intBytes)
bytesRead += n
if err != nil {
return 0, bytesRead, err
}
i := 0
negative := false
if intBytes[0]&0x80 != 0 {
negative = true
}
for j, b := range intBytes {
if j > 0 {
i <<= 8
}
if negative {
b ^= 0xff
}
i |= int(b)
}
if negative {
i = -1 * (i + 1)
}
return Int(i), bytesRead, nil
}