-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslice.go
68 lines (51 loc) · 986 Bytes
/
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
package jq
import (
"fmt"
"nikand.dev/go/cbor"
)
type (
Slice struct {
Low, High int
arr []Off
}
)
func NewSlice(lo, hi int) *Slice { return &Slice{Low: lo, High: hi} }
func (f *Slice) ApplyTo(b *Buffer, off Off, next bool) (res Off, more bool, err error) {
if next {
return None, false, nil
}
tag := b.Reader().Tag(off)
if tag != cbor.Array {
return off, false, NewTypeError(tag, cbor.Array)
}
f.arr = b.Reader().ArrayMap(off, f.arr[:0])
l := len(f.arr)
lo, hi := f.Low, f.High
if lo < 0 {
lo = l + lo
}
if hi < 0 {
hi = l + hi
}
lo = bound(lo, 0, l)
hi = bound(hi, 0, l)
if lo == 0 && hi == l {
return off, false, nil
}
if hi < lo {
f.arr = append(f.arr, f.arr[:hi]...)
hi += l
}
res = b.Writer().ArrayMap(tag, f.arr[lo:hi])
return res, false, nil
}
func (f Slice) String() string { return fmt.Sprintf(".[%d:%d]", f.Low, f.High) }
func bound(x, lo, hi int) int {
if x < lo {
x = lo
}
if x > hi {
x = hi
}
return x
}