/
array.go
76 lines (62 loc) · 1.46 KB
/
array.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
package jsonmerge
import "io"
type arrayMerger struct {
isFirstPage bool
}
// NewArrayMerger creates a Merger for JSON arrays.
func NewArrayMerger() Merger {
return &arrayMerger{
isFirstPage: true,
}
}
func (merger *arrayMerger) NewPage(r io.Reader, isLastPage bool) io.ReadCloser {
return &arrayMergerPage{
merger: merger,
Reader: r,
isLastPage: isLastPage,
}
}
func (m *arrayMerger) Close() error {
// arrayMerger merges when reading, so any output was already written
// and there's nothing to do on Close.
return nil
}
type arrayMergerPage struct {
merger *arrayMerger
io.Reader
isLastPage bool
isSubsequentRead bool
cachedByte byte
}
func (page *arrayMergerPage) Read(p []byte) (int, error) {
var n int
var err error
if page.cachedByte != 0 && len(p) > 0 {
p[0] = page.cachedByte
n, err = page.Reader.Read(p[1:])
n += 1
page.cachedByte = 0
} else {
n, err = page.Reader.Read(p)
}
if !page.isSubsequentRead && !page.merger.isFirstPage && n > 0 && p[0] == '[' {
if n > 1 && p[1] == ']' {
// Empty array case.
p[0] = ' '
} else {
// Avoid starting a new array and continue with a comma instead.
p[0] = ','
}
}
if !page.isLastPage && n > 0 && p[n-1] == ']' {
// Avoid closing off an array in case we determine we are at EOF.
page.cachedByte = p[n-1]
n -= 1
}
page.isSubsequentRead = true
return n, err
}
func (page *arrayMergerPage) Close() error {
page.merger.isFirstPage = false
return nil
}