-
Notifications
You must be signed in to change notification settings - Fork 0
/
decimal.go
102 lines (91 loc) · 1.99 KB
/
decimal.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
package evmasm
import (
"unicode/utf8"
)
// decimal parses the UTF-8 text in a []byte, trying to interpret it as decimal digits (i.e., base 10 digits), and tries to turn those decimal digits into a number that fits into a byte.
//
// If what it finds are not all decimal digits, then it returns a NotNumeral error.
//
// If what it finds are decimal digits but represents a number larger than can fit in a byte (i.e., larger than 255), then it returns a errOverflow error.
//
// Examples:
//
// decimal( []byte("0") ) -> 0, nil
//
// decimal( []byte("1") ) -> 1, nil
//
// decimal( []byte("2") ) -> 2, nil
//
// decimal( []byte("3") ) -> 3, nil
//
//
// decimal( []byte("00") ) -> 0, nil
//
// decimal( []byte("01") ) -> 1, nil
//
// decimal( []byte("02") ) -> 2, nil
//
// decimal( []byte("03") ) -> 3, nil
//
//
// decimal( []byte("253") ) -> 253, nil
//
// decimal( []byte("254") ) -> 254, nil
//
// decimal( []byte("255") ) -> 255, nil
//
// Error Examples:
//
// decimal( []byte("ff") ) -> 0, NotNumeral
//
// decimal( []byte("0x01") ) -> 0, NotNumeral
//
// decimal( []byte("apple") ) -> 0, NotNumeral
//
// decimal( []byte("") ) -> 0, NotNumeral
//
//
// decimal( []byte("256") ) -> 0, errOverflow
//
// decimal( []byte("1000") ) -> 0, errOverflow
func decimal(text []byte) (byte, error) {
if nil == text {
return 0, internalNotNumeral{string(text)}
}
if 0 >= len(text) {
return 0, internalNotNumeral{string(text)}
}
var num uint16
{
var p []byte = text
for {
r, size := utf8.DecodeRune(p)
if utf8.RuneError == r {
return 0, internalNotNumeral{string(text)}
}
p = p[size:]
var n uint16
switch r {
case '0','1','2','3','4','5','6','7','8','9':
n = uint16(r - '0')
default:
return 0, internalNotNumeral{string(text)}
}
num *= 10
if num > 255 {
return 0, errOverflow
}
num += n
if num > 255 {
return 0, errOverflow
}
if 0 >= len(p) {
break
}
}
}
if num > 255 {
return 0, errOverflow
}
return byte(num), nil
}