<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/json_array
diff options
context:
space:
mode:
Diffstat (limited to 'json_array')
-rw-r--r--json_array/read.go118
-rw-r--r--json_array/write.go151
2 files changed, 0 insertions, 269 deletions
diff --git a/json_array/read.go b/json_array/read.go
deleted file mode 100644
index 786bc2c..0000000
--- a/json_array/read.go
+++ /dev/null
@@ -1,118 +0,0 @@
-package json_array
-
-import (
- "main/walk"
- "encoding/json"
- "errors"
- "bufio"
-)
-
-type state int
-const (
- stateStart state = iota
- stateValueStart
- stateEnd
- stateDead
-)
-
-func atomiseValue(value interface{}) []walk.AtomOLD {
- switch v := value.(type) {
- case nil:
- return []walk.AtomOLD{walk.NewAtomNull()}
- case bool:
- return []walk.AtomOLD{walk.NewAtomBool(v)}
- case float64:
- return []walk.AtomOLD{walk.NewAtomNumber(v)}
- case string:
- atoms := []walk.AtomOLD{walk.NewAtomStringTerminal()}
- for _, r := range v {
- atoms = append(atoms, walk.NewAtomStringRune(r))
- }
- atoms = append(atoms, walk.NewAtomStringTerminal())
- return atoms
- case []interface{}:
- atoms := []walk.AtomOLD{walk.NewAtomTerminal(walk.ArrayBegin)}
- for _, element := range v {
- atoms = append(atoms, atomiseValue(element)...)
- }
- atoms = append(atoms, walk.NewAtomTerminal(walk.ArrayEnd))
- return atoms
- case map[string]interface{}:
- atoms := []walk.AtomOLD{walk.NewAtomTerminal(walk.MapBegin)}
- for key, element := range v {
- atoms = append(atoms, atomiseValue(key)...)
- atoms = append(atoms, atomiseValue(element)...)
- }
- atoms = append(atoms, walk.NewAtomTerminal(walk.MapEnd))
- return atoms
- default:
- panic("Invalid JSON value type")
- }
-}
-
-func NewJSONArrayReader(reader *bufio.Reader) *JSONArrayReader {
- return &JSONArrayReader {
- decoder: json.NewDecoder(reader),
- state: stateStart,
- index: 0,
- }
-}
-
-type JSONArrayReader struct {
- decoder *json.Decoder
- state state
- index int
-}
-
-func (in *JSONArrayReader) Read() (walk.WalkItem, error) {
- restart:
- switch in.state {
- case stateStart:
- arrayStart, err := in.decoder.Token()
- if err != nil {
- panic("Error reading start of JSON array")
- }
- delim, isDelim := arrayStart.(json.Delim)
- if !isDelim || delim != '[' {
- panic("JSON input is not an array!")
- }
- in.state = stateValueStart
- goto restart
- case stateValueStart:
- if !in.decoder.More() {
- in.state = stateEnd
- goto restart
- }
- var m interface{}
- err := in.decoder.Decode(&m)
- if err != nil {
- panic("Error decoding array value")
- }
- in.index += 1
- return walk.WalkItem {
- Path: []interface{}{float64(in.index - 1)},
- Value: []interface{}{m},
- }, nil
- case stateEnd:
- arrayEnd, err := in.decoder.Token()
- if err != nil {
- panic("Error reading end of JSON array")
- }
- delim, isDelim := arrayEnd.(json.Delim)
- if !isDelim || delim != ']' {
- panic("JSON array wasn't ended")
- }
- in.state = stateDead
- return walk.WalkItem{}, errors.New("eof")
- case stateDead:
- return walk.WalkItem{}, errors.New("eof")
- default:
- panic("Unreachable!!!")
- }
-}
-
-func (in *JSONArrayReader) AssertDone() {
- if in.state != stateDead || in.decoder.More() {
- panic("More JSON after array value")
- }
-}
diff --git a/json_array/write.go b/json_array/write.go
deleted file mode 100644
index aaa2851..0000000
--- a/json_array/write.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package json_array
-
-import (
- "bufio"
- "strings"
- "main/walk"
- "encoding/json"
-)
-
-func assembleValue(atoms []walk.AtomOLD) (interface{}, []walk.AtomOLD) {
- if len(atoms) == 0 {
- panic("Missing JSON value in output")
- }
- switch atoms[0].Typ {
- case walk.AtomNull:
- return nil, atoms[1:]
- case walk.AtomBool:
- return atoms[0].Bool(), atoms[1:]
- case walk.AtomNumber:
- return atoms[0].Number(), atoms[1:]
- case walk.AtomStringTerminal:
- var builder strings.Builder
- atoms = atoms[1:]
- for {
- if len(atoms) == 0 {
- panic("Missing closing string terminal")
- }
- if atoms[0].Typ == walk.AtomStringTerminal {
- break
- }
- if atoms[0].Typ != walk.AtomStringRune {
- panic("Non string rune atom inside string")
- }
- builder.WriteRune(atoms[0].StringRune())
- atoms = atoms[1:]
- }
- atoms = atoms[1:]
- return builder.String(), atoms
- case walk.AtomStringRune:
- panic("String rune used outside of string terminals")
- case walk.AtomTerminal:
- terminal := atoms[0].Terminal()
- switch terminal {
- case walk.ArrayEnd, walk.MapEnd:
- panic("Tried to extract value from end terminal")
- case walk.ArrayBegin:
- var arr []interface{}
- var element interface{}
- atoms = atoms[1:]
- for {
- if len(atoms) == 0 {
- panic("Missing array end terminal")
- }
- if atoms[0].Typ == walk.AtomTerminal && atoms[0].Terminal() == walk.ArrayEnd {
- atoms = atoms[1:]
- break
- }
- element, atoms = assembleValue(atoms)
- arr = append(arr, element)
- }
- return arr, atoms
- case walk.MapBegin:
- obj := make(map[string]interface{})
- var key interface{}
- var element interface{}
- atoms = atoms[1:]
- for {
- if len(atoms) == 0 {
- panic("Missing map end terminal")
- }
- if atoms[0].Typ == walk.AtomTerminal && atoms[0].Terminal() == walk.MapEnd {
- atoms = atoms[1:]
- break
- }
- key, atoms = assembleValue(atoms)
- element, atoms = assembleValue(atoms)
- keyString, keyIsString := key.(string)
- if !keyIsString {
- panic("Key is not string")
- }
- obj[keyString] = element
- }
- return obj, atoms
- default:
- panic("Invalid terminal")
- }
- default:
- panic("Invalid atom")
- }
-}
-
-func outputValue(values []interface{}, writer *bufio.Writer) {
- for _, value := range values {
- bytes, err := json.MarshalIndent(value, "\t", "\t")
- if err != nil {
- panic("Error marshalling json into bytes")
- }
- _, err = writer.Write(bytes)
- if err != nil {
- panic("Error writing value")
- }
- }
-}
-
-type writerState int
-const (
- writerStateStart writerState = iota
- writerStateValue
-)
-
-func NewJSONArrayWriter(writer *bufio.Writer) *JSONArrayWriter {
- return &JSONArrayWriter {
- writer: writer,
- state: writerStateStart,
- }
-}
-
-type JSONArrayWriter struct {
- writer *bufio.Writer
- state writerState
-}
-
-func (out *JSONArrayWriter) Write(item walk.WalkItem) error {
- switch out.state {
- case writerStateStart:
- _, err := out.writer.WriteString("[\n\t")
- if err != nil {
- panic("Error outputting [ at beginning of array")
- }
- outputValue(item.Value, out.writer)
- out.state = writerStateValue
- return nil
- case writerStateValue:
- _, err := out.writer.WriteString(",\n\t")
- if err != nil {
- panic("Error outputting comma at the end of a value")
- }
- outputValue(item.Value, out.writer)
- return nil
- default:
- panic("Invalid writer state")
- }
-}
-
-func (out *JSONArrayWriter) AssertDone() {
- if out.state == writerStateStart {
- out.writer.WriteString("[")
- }
- out.writer.WriteString("\n]")
- out.writer.Flush()
-}