Improve readability of json parser code
This commit is contained in:
parent
b405dafb89
commit
1e78491cb2
|
@ -6,7 +6,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Filter(w *bytes.Buffer, b []byte, keys []string) error {
|
func Filter(w *bytes.Buffer, b []byte, keys []string) error {
|
||||||
s := 0
|
|
||||||
state := expectKey
|
state := expectKey
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -19,10 +18,29 @@ func Filter(w *bytes.Buffer, b []byte, keys []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// is an list
|
||||||
isList := false
|
isList := false
|
||||||
|
|
||||||
|
// list item
|
||||||
item := 0
|
item := 0
|
||||||
|
|
||||||
|
// field in an object
|
||||||
field := 0
|
field := 0
|
||||||
|
|
||||||
|
s, e, d := 0, 0, 0
|
||||||
|
|
||||||
|
kf := false
|
||||||
|
|
||||||
for i := 0; i < len(b); i++ {
|
for i := 0; i < len(b); i++ {
|
||||||
|
if state == expectObjClose || state == expectListClose {
|
||||||
|
switch b[i] {
|
||||||
|
case '{', '[':
|
||||||
|
d++
|
||||||
|
case '}', ']':
|
||||||
|
d--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case state == expectKey:
|
case state == expectKey:
|
||||||
switch b[i] {
|
switch b[i] {
|
||||||
|
@ -35,7 +53,7 @@ func Filter(w *bytes.Buffer, b []byte, keys []string) error {
|
||||||
if item == 0 {
|
if item == 0 {
|
||||||
err = w.WriteByte('{')
|
err = w.WriteByte('{')
|
||||||
} else {
|
} else {
|
||||||
_, err = w.WriteString("},{")
|
_, err = w.Write([]byte("},{"))
|
||||||
}
|
}
|
||||||
item++
|
item++
|
||||||
field = 0
|
field = 0
|
||||||
|
@ -44,36 +62,14 @@ func Filter(w *bytes.Buffer, b []byte, keys []string) error {
|
||||||
s = i
|
s = i
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
case state == expectKeyClose && b[i] == '"':
|
case state == expectKeyClose && b[i] == '"':
|
||||||
state = expectColon
|
state = expectColon
|
||||||
i++
|
k := b[(s + 1):i]
|
||||||
}
|
_, kf = kmap[sha1.Sum(k)]
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if state != expectColon {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
k := b[(s + 1):(i - 1)]
|
|
||||||
h := sha1.Sum(k)
|
|
||||||
_, kf := kmap[h]
|
|
||||||
|
|
||||||
e := 0
|
|
||||||
d := 0
|
|
||||||
for ; i < len(b); i++ {
|
|
||||||
if state == expectObjClose || state == expectListClose {
|
|
||||||
switch b[i] {
|
|
||||||
case '{', '[':
|
|
||||||
d++
|
|
||||||
case '}', ']':
|
|
||||||
d--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case state == expectColon && b[i] == ':':
|
case state == expectColon && b[i] == ':':
|
||||||
state = expectValue
|
state = expectValue
|
||||||
|
|
||||||
|
@ -115,14 +111,20 @@ func Filter(w *bytes.Buffer, b []byte, keys []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if e != 0 {
|
if e != 0 {
|
||||||
if kf {
|
state = expectKey
|
||||||
|
cb := b[s:(e + 1)]
|
||||||
|
e = 0
|
||||||
|
|
||||||
|
if !kf {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if field != 0 {
|
if field != 0 {
|
||||||
if err := w.WriteByte(','); err != nil {
|
if err := w.WriteByte(','); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cb := b[s:(e + 1)]
|
|
||||||
sk := 0
|
sk := 0
|
||||||
for i := 0; i < len(cb); i++ {
|
for i := 0; i < len(cb); i++ {
|
||||||
if cb[i] == '\n' || cb[i] == '\t' {
|
if cb[i] == '\n' || cb[i] == '\t' {
|
||||||
|
@ -138,21 +140,20 @@ func Filter(w *bytes.Buffer, b []byte, keys []string) error {
|
||||||
} else {
|
} else {
|
||||||
_, err = w.Write(cb)
|
_, err = w.Write(cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
field++
|
field++
|
||||||
}
|
}
|
||||||
state = expectKey
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if item != 0 {
|
if item != 0 {
|
||||||
if err := w.WriteByte('}'); err != nil {
|
if err := w.WriteByte('}'); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isList {
|
if isList {
|
||||||
if err := w.WriteByte(']'); err != nil {
|
if err := w.WriteByte(']'); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
49
json/get.go
49
json/get.go
|
@ -34,31 +34,15 @@ func Get(b []byte, keys [][]byte) []Field {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l := 10
|
prealloc := 20
|
||||||
res := make([]Field, l)
|
res := make([]Field, prealloc)
|
||||||
|
|
||||||
|
s, e, d := 0, 0, 0
|
||||||
|
|
||||||
|
var kf bool
|
||||||
|
var k []byte
|
||||||
|
|
||||||
for i := 0; i < len(b); i++ {
|
for i := 0; i < len(b); i++ {
|
||||||
switch {
|
|
||||||
case state == expectKey && b[i] == '"':
|
|
||||||
state = expectKeyClose
|
|
||||||
s = i + 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
case state == expectKeyClose && b[i] == '"':
|
|
||||||
state = expectColon
|
|
||||||
}
|
|
||||||
|
|
||||||
if state != expectColon {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
k := b[s:i]
|
|
||||||
h := sha1.Sum(k)
|
|
||||||
_, kf := kmap[h]
|
|
||||||
|
|
||||||
e := 0
|
|
||||||
d := 0
|
|
||||||
for ; i < len(b); i++ {
|
|
||||||
if state == expectObjClose || state == expectListClose {
|
if state == expectObjClose || state == expectListClose {
|
||||||
switch b[i] {
|
switch b[i] {
|
||||||
case '{', '[':
|
case '{', '[':
|
||||||
|
@ -69,6 +53,15 @@ func Get(b []byte, keys [][]byte) []Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
case state == expectKey && b[i] == '"':
|
||||||
|
state = expectKeyClose
|
||||||
|
s = i
|
||||||
|
|
||||||
|
case state == expectKeyClose && b[i] == '"':
|
||||||
|
state = expectColon
|
||||||
|
k = b[(s + 1):i]
|
||||||
|
_, kf = kmap[sha1.Sum(k)]
|
||||||
|
|
||||||
case state == expectColon && b[i] == ':':
|
case state == expectColon && b[i] == ':':
|
||||||
state = expectValue
|
state = expectValue
|
||||||
|
|
||||||
|
@ -117,21 +110,17 @@ func Get(b []byte, keys [][]byte) []Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
if e != 0 {
|
if e != 0 {
|
||||||
e++
|
|
||||||
|
|
||||||
if kf {
|
if kf {
|
||||||
if len(res) == cap(res) {
|
if len(res) == cap(res) {
|
||||||
r := make([]Field, 0, (len(res) + l))
|
r := make([]Field, 0, (len(res) * 2))
|
||||||
copy(r, res)
|
copy(r, res)
|
||||||
res = r
|
res = r
|
||||||
}
|
}
|
||||||
|
res = append(res, Field{k, b[s:(e + 1)]})
|
||||||
res = append(res, Field{k, b[s:e]})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state = expectKey
|
state = expectKey
|
||||||
break
|
e = 0
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,6 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
|
||||||
return errors.New("'from' and 'to' must be of the same length")
|
return errors.New("'from' and 'to' must be of the same length")
|
||||||
}
|
}
|
||||||
|
|
||||||
state := expectKey
|
|
||||||
ws, we := 0, len(b)
|
|
||||||
|
|
||||||
s := 0
|
|
||||||
fi := -1
|
|
||||||
|
|
||||||
fmap := make(map[[20]byte]int, (len(from) * 2))
|
fmap := make(map[[20]byte]int, (len(from) * 2))
|
||||||
tmap := make(map[[20]byte]int, (len(from)))
|
tmap := make(map[[20]byte]int, (len(from)))
|
||||||
|
|
||||||
|
@ -33,36 +27,18 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
|
||||||
tmap[h2] = i
|
tmap[h2] = i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state := expectKey
|
||||||
|
ws, we := 0, len(b)
|
||||||
|
|
||||||
|
s, e, d := 0, 0, 0
|
||||||
|
fi := -1
|
||||||
|
|
||||||
for i := 0; i < len(b); i++ {
|
for i := 0; i < len(b); i++ {
|
||||||
switch {
|
// skip any left padding whitespace
|
||||||
case ws == 0 && b[i] == '{' || b[i] == '[':
|
if ws == 0 && (b[i] == '{' || b[i] == '[') {
|
||||||
ws = i
|
ws = i
|
||||||
|
|
||||||
case state == expectKey && b[i] == '"':
|
|
||||||
state = expectKeyClose
|
|
||||||
s = i + 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
case state == expectKeyClose && b[i] == '"':
|
|
||||||
state = expectColon
|
|
||||||
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if state != expectColon {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 := sha1.Sum(b[s:i])
|
|
||||||
if n, ok := fmap[h1]; ok {
|
|
||||||
we = s
|
|
||||||
fi = n
|
|
||||||
}
|
|
||||||
|
|
||||||
e := 0
|
|
||||||
d := 0
|
|
||||||
for ; i < len(b); i++ {
|
|
||||||
if state == expectObjClose || state == expectListClose {
|
if state == expectObjClose || state == expectListClose {
|
||||||
switch b[i] {
|
switch b[i] {
|
||||||
case '{', '[':
|
case '{', '[':
|
||||||
|
@ -73,6 +49,18 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
case state == expectKey && b[i] == '"':
|
||||||
|
state = expectKeyClose
|
||||||
|
s = i
|
||||||
|
|
||||||
|
case state == expectKeyClose && b[i] == '"':
|
||||||
|
state = expectColon
|
||||||
|
h1 := sha1.Sum(b[(s + 1):i])
|
||||||
|
if n, ok := fmap[h1]; ok {
|
||||||
|
we = s
|
||||||
|
fi = n
|
||||||
|
}
|
||||||
|
|
||||||
case state == expectColon && b[i] == ':':
|
case state == expectColon && b[i] == ':':
|
||||||
state = expectValue
|
state = expectValue
|
||||||
|
|
||||||
|
@ -120,13 +108,15 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
|
||||||
|
|
||||||
if e != 0 {
|
if e != 0 {
|
||||||
e++
|
e++
|
||||||
|
|
||||||
h2 := sha1.Sum(b[s:e])
|
h2 := sha1.Sum(b[s:e])
|
||||||
|
replace := false
|
||||||
|
|
||||||
if n, ok1 := fmap[h2]; ok1 && n == fi {
|
if n, ok1 := fmap[h2]; ok1 && n == fi {
|
||||||
ti, ok2 := tmap[h2]
|
ti, ok2 := tmap[h2]
|
||||||
|
|
||||||
if ok2 {
|
if ok2 {
|
||||||
if _, err := w.Write(b[ws:we]); err != nil {
|
if _, err := w.Write(b[ws:(we + 1)]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := w.Write(to[ti].Key); err != nil {
|
if _, err := w.Write(to[ti].Key); err != nil {
|
||||||
|
@ -138,19 +128,21 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
|
||||||
if _, err := w.Write(to[ti].Value); err != nil {
|
if _, err := w.Write(to[ti].Value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
replace = true
|
||||||
ws = e
|
ws = e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ws != e && (b[s] == '[' || b[s] == '{') {
|
if !replace && (b[s] == '[' || b[s] == '{') {
|
||||||
|
// the i++ in the for loop will add 1 so we account for that (s - 1)
|
||||||
i = s - 1
|
i = s - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
state = expectKey
|
state = expectKey
|
||||||
we = len(b)
|
we = len(b)
|
||||||
fi = -1
|
fi = -1
|
||||||
break
|
e = 0
|
||||||
}
|
d = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,41 +9,15 @@ func Strip(b []byte, path []string) []byte {
|
||||||
state := expectKey
|
state := expectKey
|
||||||
|
|
||||||
kb := make([][]byte, 0, len(path))
|
kb := make([][]byte, 0, len(path))
|
||||||
ki := 0
|
|
||||||
for _, k := range path {
|
for _, k := range path {
|
||||||
kb = append(kb, []byte(k))
|
kb = append(kb, []byte(k))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s, e, d := 0, 0, 0
|
||||||
|
ki := 0
|
||||||
|
pm := false
|
||||||
|
|
||||||
for i := 0; i < len(b); i++ {
|
for i := 0; i < len(b); i++ {
|
||||||
switch {
|
|
||||||
case state == expectKey && b[i] == '"':
|
|
||||||
state = expectKeyClose
|
|
||||||
s = i + 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
case state == expectKeyClose && b[i] == '"':
|
|
||||||
state = expectColon
|
|
||||||
}
|
|
||||||
|
|
||||||
if state != expectColon {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if ki >= len(kb) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(b[s:i], kb[ki]) {
|
|
||||||
state = expectKey
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ki++
|
|
||||||
|
|
||||||
e := 0
|
|
||||||
d := 0
|
|
||||||
s := 0
|
|
||||||
for ; i < len(b); i++ {
|
|
||||||
if state == expectObjClose || state == expectListClose {
|
if state == expectObjClose || state == expectListClose {
|
||||||
switch b[i] {
|
switch b[i] {
|
||||||
case '{', '[':
|
case '{', '[':
|
||||||
|
@ -54,6 +28,20 @@ func Strip(b []byte, path []string) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
case state == expectKey && b[i] == '"':
|
||||||
|
state = expectKeyClose
|
||||||
|
s = i
|
||||||
|
|
||||||
|
case state == expectKeyClose && b[i] == '"':
|
||||||
|
state = expectColon
|
||||||
|
if ki == len(kb) {
|
||||||
|
ki = 0
|
||||||
|
}
|
||||||
|
pm = bytes.Equal(b[(s+1):i], kb[ki])
|
||||||
|
if pm {
|
||||||
|
ki++
|
||||||
|
}
|
||||||
|
|
||||||
case state == expectColon && b[i] == ':':
|
case state == expectColon && b[i] == ':':
|
||||||
state = expectValue
|
state = expectValue
|
||||||
|
|
||||||
|
@ -99,18 +87,18 @@ func Strip(b []byte, path []string) []byte {
|
||||||
e = i
|
e = i
|
||||||
}
|
}
|
||||||
|
|
||||||
if e != 0 && (b[s] == '[' || b[s] == '{') {
|
if e != 0 {
|
||||||
e++
|
if pm && (b[s] == '[' || b[s] == '{') {
|
||||||
b = b[s:e]
|
b = b[s:(e + 1)]
|
||||||
i = 0
|
i = 0
|
||||||
|
|
||||||
if ki == len(kb) {
|
if ki == len(kb) {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state = expectKey
|
state = expectKey
|
||||||
break
|
e = 0
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue