222 lines
4.1 KiB
Go
222 lines
4.1 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package jsonrw
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"reflect"
|
|
|
|
"github.com/hyperledger/fabric/internal/fileutil"
|
|
"github.com/hyperledger/fabric/internal/ledgerutil/models"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// json Reading
|
|
|
|
// Loads a json file containing a DiffRecordList object
|
|
func LoadRecords(filePath string) (*models.DiffRecordList, error) {
|
|
f, err := os.Open(filePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var records *models.DiffRecordList
|
|
|
|
d := json.NewDecoder(bufio.NewReader(f))
|
|
err = d.Decode(&records)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = f.Close()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return records, nil
|
|
}
|
|
|
|
// json Writing
|
|
|
|
// JSONFileWriter writes data to a json file
|
|
type JSONFileWriter struct {
|
|
file *os.File
|
|
buffer *bufio.Writer
|
|
encoder *json.Encoder
|
|
objectOpened bool
|
|
firstFieldWritten bool
|
|
listOpened bool
|
|
firstEntryWritten bool
|
|
count int
|
|
}
|
|
|
|
func NewJSONFileWriter(filePath string) (*JSONFileWriter, error) {
|
|
f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0o644)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
b := bufio.NewWriter(f)
|
|
|
|
return &JSONFileWriter{
|
|
file: f,
|
|
buffer: b,
|
|
encoder: json.NewEncoder(b),
|
|
}, nil
|
|
}
|
|
|
|
// Open a json object
|
|
func (w *JSONFileWriter) OpenObject() error {
|
|
if w.objectOpened {
|
|
return errors.Errorf("object already open, must close object before starting a new one")
|
|
}
|
|
|
|
w.objectOpened = true
|
|
_, err := w.buffer.Write([]byte("{\n"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Close a json object
|
|
func (w *JSONFileWriter) CloseObject() error {
|
|
if !w.objectOpened {
|
|
return errors.Errorf("no object open, cannot close object")
|
|
}
|
|
|
|
_, err := w.buffer.Write([]byte("}\n"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
w.objectOpened = false
|
|
w.firstFieldWritten = false
|
|
|
|
return nil
|
|
}
|
|
|
|
// Add field to an open json object
|
|
func (w *JSONFileWriter) AddField(k string, v interface{}) error {
|
|
// Need to open object before adding fields
|
|
if !w.objectOpened {
|
|
return errors.Errorf("no object open, cannot add field")
|
|
}
|
|
// Add commas for fields after the first field in the object
|
|
if w.firstFieldWritten {
|
|
_, err := w.buffer.Write([]byte(",\n"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
w.firstFieldWritten = true
|
|
}
|
|
// Key : Value
|
|
keyString := fmt.Sprintf("\"%s\":", k)
|
|
_, err := w.buffer.Write([]byte(keyString))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Determine if v is list
|
|
if reflect.TypeOf(v).Kind() == reflect.Slice {
|
|
err = w.OpenList()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
err = w.encoder.Encode(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Open a json list
|
|
func (w *JSONFileWriter) OpenList() error {
|
|
if w.listOpened {
|
|
return errors.Errorf("list already open, must close list before starting a new one")
|
|
}
|
|
|
|
w.listOpened = true
|
|
w.count = 0
|
|
_, err := w.buffer.Write([]byte("[\n"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Close a json list
|
|
func (w *JSONFileWriter) CloseList() error {
|
|
if !w.listOpened {
|
|
return errors.Errorf("no list open, cannot close list")
|
|
}
|
|
|
|
w.listOpened = false
|
|
_, err := w.buffer.Write([]byte("]\n"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Add entries to an open json list
|
|
func (w *JSONFileWriter) AddEntry(r interface{}) error {
|
|
// Need to open list before adding entries
|
|
if !w.listOpened {
|
|
return errors.Errorf("no list open, cannot add entries")
|
|
}
|
|
// Add commas for entries after the first entry in the list
|
|
if w.firstEntryWritten {
|
|
_, err := w.buffer.Write([]byte(",\n"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
w.firstEntryWritten = true
|
|
}
|
|
|
|
err := w.encoder.Encode(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
w.count++
|
|
|
|
return nil
|
|
}
|
|
|
|
func (w *JSONFileWriter) Close() error {
|
|
if w.listOpened {
|
|
return errors.Errorf("list still open, must close list before closing jsonFileWriter")
|
|
}
|
|
|
|
err := w.buffer.Flush()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = w.file.Sync()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = fileutil.SyncParentDir(w.file.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return w.file.Close()
|
|
}
|