-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
70 lines (65 loc) · 1.25 KB
/
main.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
package dutf
import (
"strings"
"unicode/utf8"
)
func AppendRune(p []byte, last rune, r rune) (dutf []byte, _last rune) {
if r <= 0x7F {
p = utf8.AppendRune(p, r)
} else {
xorResult := last ^ r
if r <= 0x3FFF {
p = append(p,
byte(0x80|(xorResult&0x7F)),
byte((xorResult>>7)&0x7F))
} else {
p = append(p,
byte(0x80|(xorResult&0x7F)),
byte(0x80|((xorResult>>7)&0x7F)),
byte((xorResult>>14)&0x7F))
}
last = r
}
return p, last
}
func EncodeString(s string) (dutf []byte) {
last := rune(0)
buffer := make([]byte, 0, len(s))
for _, c := range s {
buffer, last = AppendRune(buffer, last, c)
}
return buffer
}
func DecodeRune(p []byte, last rune) (r rune, siz int) {
if p[0] <= 0x7F {
return rune(p[0]), 1
}
xorDiff := rune(0)
i := 0
for {
if i >= len(p) {
return utf8.RuneError, -1
}
xorDiff |= (rune(p[i]) & 0x7F) << (7 * i)
if p[i] <= 0x7F {
return last ^ xorDiff, i + 1
}
i++
}
}
func DecodeString(p []byte) (result string, undecodedBytes []byte) {
var buffer strings.Builder
last := rune(0)
for len(p) > 0 {
r, siz := DecodeRune(p, last)
if r == utf8.RuneError {
return buffer.String(), p
}
if r > 0x7F {
last = r
}
buffer.WriteRune(r)
p = p[siz:]
}
return buffer.String(), nil
}