-
Notifications
You must be signed in to change notification settings - Fork 6
/
slice.go
118 lines (99 loc) · 2.6 KB
/
slice.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package bytes
import "errors"
/**
* @Author: imuge
* @Date: 2020/4/29 9:21 上午
*/
var EMPTY_SLICE = NewSlice([]byte{})
var _ BytesSerializable = (*Slice)(nil)
type Slice struct {
Bytes []byte
Offset int
Size int
}
func NewSlice(bytes []byte) Slice {
return Slice{
bytes,
0,
len(bytes),
}
}
func NewSliceWithOffset(bytes []byte, offset int) (*Slice, error) {
if offset >= len(bytes) {
return nil, errors.New("offset out of bounds")
}
return NewSliceWithOffsetAndSize(bytes, offset, len(bytes)-offset)
}
func NewSliceWithOffsetAndSize(bytes []byte, offset, size int) (*Slice, error) {
if offset+size > len(bytes) {
return nil, errors.New("index out of bounds")
}
return &Slice{
bytes,
offset,
size,
}, nil
}
func (s Slice) IsEmpty() bool {
return s.Size == 0
}
func (s Slice) GetByte(offset int) (byte, error) {
off := s.Offset + offset
if !s.checkBoundary(off, 1) {
return 0, errors.New("accessing index is out of BytesSlice's bounds!")
}
return s.Bytes[off], nil
}
func (s Slice) GetInt16(offset int) (int16, error) {
off := s.Offset + offset
if !s.checkBoundary(off, 2) {
return 0, errors.New("accessing index is out of BytesSlice's bounds!")
}
return ToInt16(s.Bytes[off : off+2]), nil
}
func (s Slice) GetInt32(offset int) (int32, error) {
off := s.Offset + offset
if !s.checkBoundary(off, 4) {
return 0, errors.New("accessing index is out of BytesSlice's bounds!")
}
return ToInt32(s.Bytes[off : off+4]), nil
}
func (s Slice) GetInt64(offset int) (int64, error) {
off := s.Offset + offset
if !s.checkBoundary(off, 8) {
return 0, errors.New("accessing index is out of BytesSlice's bounds!")
}
return ToInt64(s.Bytes[off : off+8]), nil
}
func (s Slice) GetString() string {
return ToString(s.Bytes[s.Offset : s.Offset+s.Size])
}
func (s Slice) GetBytesCopy(offset, size int) ([]byte, error) {
newOffset := s.Offset + offset
if !s.checkBoundary(newOffset, size) {
return nil, errors.New("accessing index is out of BytesSlice's bounds!")
}
if size == 0 {
return []byte{}, nil
}
dst := make([]byte, size)
copy(dst, s.Bytes[newOffset:newOffset+size])
return dst, nil
}
func (s Slice) GetSlice(offset, size int) (*Slice, error) {
newOffset := s.Offset + offset
if !s.checkBoundary(newOffset, size) {
return nil, errors.New("accessing index is out of BytesSlice's bounds!")
}
return NewSliceWithOffsetAndSize(s.Bytes, newOffset, size)
}
func (s Slice) ToBytes() []byte {
bs, _ := s.GetBytesCopy(0, s.Size)
return bs
}
func (s Slice) checkBoundary(offset, len int) bool {
if offset < s.Offset || offset+len > s.Offset+s.Size {
return false
}
return true
}