-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathutil.go
99 lines (85 loc) · 2.24 KB
/
util.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
/*
Copyright 2018 liipx(lipengxiang)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package binlog
import (
"io"
)
// ReadNBytes read n bytes from io.Reader
func ReadNBytes(rd io.Reader, size int64) ([]byte, error) {
data := make([]byte, size)
n, err := rd.Read(data)
total := n
for int64(total) < size && err == nil {
n, err = rd.Read(data[total:])
total += n
}
if n == 0 && err != nil {
return nil, err
}
return data, err
}
// FixedLengthInt will turn byte to uint64
// this function is from 'github.com/siddontang/go-mysql/replication/util.go'
func FixedLengthInt(buf []byte) uint64 {
var num uint64
for i, b := range buf {
num |= uint64(b) << (uint(i) * 8)
}
return num
}
// LengthEncodedInt will decode byte to uint64
// this function is from 'github.com/siddontang/go-mysql/replication/util.go'
func LengthEncodedInt(b []byte) (num uint64, isNull bool, n int) {
switch b[0] {
case 0xfb:
// 251: NULL
n = 1
isNull = true
return
case 0xfc:
// 252: value of following 2
num = uint64(b[1]) | uint64(b[2])<<8
n = 3
return
case 0xfd:
// 253: value of following 3
num = uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16
n = 4
return
case 0xfe:
// 254: value of following 8
num = uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16 |
uint64(b[4])<<24 | uint64(b[5])<<32 | uint64(b[6])<<40 |
uint64(b[7])<<48 | uint64(b[8])<<56
n = 9
return
}
// 0-250: value of first byte
num = uint64(b[0])
n = 1
return
}
// LengthEnodedString will decode bytes
func LengthEnodedString(b []byte) ([]byte, bool, int, error) {
// Get length
num, isNull, n := LengthEncodedInt(b)
if num < 1 {
return nil, isNull, n, nil
}
n += int(num)
// Check data length
if len(b) >= n {
return b[n-int(num) : n], false, n, nil
}
return nil, false, n, io.EOF
}