forked from andig/gosml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnumber.go
104 lines (84 loc) · 2.3 KB
/
number.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package sml
import (
"encoding/binary"
"fmt"
)
const (
TYPENUMBER_8 = 1
TYPENUMBER_16 = 2
TYPENUMBER_32 = 4
TYPENUMBER_64 = 8
)
func U8Parse(buf *Buffer) (uint8, error) {
num, err := NumberParse(buf, TYPEUNSIGNED, TYPENUMBER_8)
return uint8(num), err
}
func U16Parse(buf *Buffer) (uint16, error) {
num, err := NumberParse(buf, TYPEUNSIGNED, TYPENUMBER_16)
return uint16(num), err
}
func U32Parse(buf *Buffer) (uint32, error) {
num, err := NumberParse(buf, TYPEUNSIGNED, TYPENUMBER_32)
return uint32(num), err
}
func U64Parse(buf *Buffer) (uint64, error) {
num, err := NumberParse(buf, TYPEUNSIGNED, TYPENUMBER_64)
return uint64(num), err
}
func I8Parse(buf *Buffer) (int8, error) {
num, err := NumberParse(buf, TYPEINTEGER, TYPENUMBER_8)
return int8(num), err
}
func I16Parse(buf *Buffer) (int16, error) {
num, err := NumberParse(buf, TYPEINTEGER, TYPENUMBER_16)
return int16(num), err
}
func I32Parse(buf *Buffer) (int32, error) {
num, err := NumberParse(buf, TYPEINTEGER, TYPENUMBER_32)
return int32(num), err
}
func I64Parse(buf *Buffer) (int64, error) {
num, err := NumberParse(buf, TYPEINTEGER, TYPENUMBER_64)
return int64(num), err
}
func NumberParse(buf *Buffer, numtype uint8, maxSize int) (int64, error) {
if skip := BufOptionalIsSkipped(buf); skip {
return 0, nil
}
Debug(buf, "NumberParse")
typefield := BufGetNextType(buf)
if typefield != numtype {
return 0, fmt.Errorf("Unexpected type %02x (expected %02x)", typefield, numtype)
}
length := BufGetNextLength(buf)
if length < 0 || length > maxSize {
return 0, fmt.Errorf("Invalid length: %d", length)
}
np := make([]byte, maxSize)
missingBytes := maxSize - length
for i := 0; i < length; i++ {
np[missingBytes+i] = buf.Bytes[buf.Cursor+i]
}
negativeInt := typefield == TYPEINTEGER && (typefield&128 > 0)
if negativeInt {
for i := 0; i < missingBytes; i++ {
np[i] = 0xFF
}
}
var num int64
switch maxSize {
case TYPENUMBER_8:
num = int64(np[0])
case TYPENUMBER_16:
num = int64(int16(binary.BigEndian.Uint16(np)))
case TYPENUMBER_32:
num = int64(int32(binary.BigEndian.Uint32(np)))
case TYPENUMBER_64:
num = int64(binary.BigEndian.Uint64(np))
default:
return num, fmt.Errorf("Invalid number type size %02x", maxSize)
}
BufUpdateBytesRead(buf, length)
// fmt.Printf("num: %d\n", num)
return num, nil
}