-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathjsonlines.go
More file actions
70 lines (62 loc) · 1.79 KB
/
jsonlines.go
File metadata and controls
70 lines (62 loc) · 1.79 KB
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
package jsonlines
import (
"fmt"
"reflect"
"io"
"bufio"
"encoding/json"
)
func getOriginalSlice(ptrToSlice interface{}) (slice reflect.Value, err error) {
ptr2sl := reflect.TypeOf(ptrToSlice)
if ptr2sl.Kind() != reflect.Ptr {
return reflect.ValueOf(nil), fmt.Errorf("expected pointer to slice, got %s", ptr2sl.Kind())
}
originalSlice := reflect.Indirect(reflect.ValueOf(ptrToSlice))
sliceType := originalSlice.Type()
if sliceType.Kind() != reflect.Slice {
return reflect.ValueOf(nil), fmt.Errorf("expected pointer to slice, got pointer to %s", sliceType.Kind())
}
return originalSlice, nil
}
// Decode reads the next JSON Lines-encoded value that reads
// from r and stores it in the slice pointed to by ptrToSlice.
func Decode(r io.Reader, ptrToSlice interface{}) error {
originalSlice, err := getOriginalSlice(ptrToSlice)
if err != nil {
return err
}
slElem := originalSlice.Type().Elem()
//originalSlice := reflect.Indirect(reflect.ValueOf(ptrToSlice))
scanner := bufio.NewScanner(r)
for scanner.Scan() {
//create new object
newObj := reflect.New(slElem).Interface()
item := scanner.Bytes()
err := json.Unmarshal(item, newObj)
if err != nil {
return err
}
ptrToNewObj := reflect.Indirect(reflect.ValueOf(newObj))
originalSlice.Set(reflect.Append(originalSlice, ptrToNewObj))
}
if err := scanner.Err(); err != nil {
return err
}
return nil
}
// Encode writes the JSON Lines encoding of ptrToSlice to the w stream
func Encode(w io.Writer, ptrToSlice interface{}) error {
originalSlice, err := getOriginalSlice(ptrToSlice)
if err != nil {
return err
}
enc := json.NewEncoder(w)
for i := 0; i < originalSlice.Len(); i++ {
elem := originalSlice.Index(i).Interface()
err = enc.Encode(elem)
if err != nil {
return err
}
}
return nil
}