-
Notifications
You must be signed in to change notification settings - Fork 0
/
map.go
96 lines (71 loc) · 1.7 KB
/
map.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
package jq
import (
"fmt"
"nikand.dev/go/cbor"
)
type (
Map struct {
Filter Filter
arr []Off
}
MapValues struct {
Filter Filter
arr []Off
}
)
func NewMap(f Filter) *Map { return &Map{Filter: f} }
func NewMapValues(f Filter) *MapValues { return &MapValues{Filter: f} }
func (f *Map) ApplyTo(b *Buffer, off Off, next bool) (res Off, more bool, err error) {
if next {
return None, false, nil
}
res, f.arr, err = mapApplyTo(f.Filter, b, off, f.arr[:0], false)
return res, false, err
}
func (f *MapValues) ApplyTo(b *Buffer, off Off, next bool) (res Off, more bool, err error) {
if next {
return None, false, nil
}
res, f.arr, err = mapApplyTo(f.Filter, b, off, f.arr[:0], true)
return res, false, err
}
func mapApplyTo(f Filter, b *Buffer, off Off, arr []Off, values bool) (res Off, _ []Off, err error) {
br := b.Reader()
tag := br.Tag(off)
if tag != cbor.Array && tag != cbor.Map {
return off, arr, NewTypeError(tag, cbor.Array, cbor.Map)
}
val := 0
if tag == cbor.Map {
val = 1
}
arr = br.ArrayMap(off, arr)
l := len(arr)
for j := 0; j < l; j += 1 + val {
if !values {
arr, err = ApplyGetAll(f, b, arr[j+val], arr)
if err != nil {
return off, arr, err
}
continue
}
res, _, err = f.ApplyTo(b, arr[j+val], false)
if err != nil {
return off, arr, err
}
if res == None {
continue
}
if tag == cbor.Map {
arr = append(arr, arr[j])
}
arr = append(arr, res)
}
if !values {
tag = cbor.Array
}
res = b.Writer().ArrayMap(tag, arr[l:])
return res, arr, nil
}
func (f Map) String() string { return fmt.Sprintf("map(%v)", f.Filter) }
func (f MapValues) String() string { return fmt.Sprintf("map_values(%v)", f.Filter) }