github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_read.go (about) 1 package jzon 2 3 import ( 4 "encoding/json" 5 ) 6 7 var ( 8 readFunctions [charNum]func(it *Iterator, c byte) (interface{}, error) 9 ) 10 11 func init() { 12 readFunctions['"'] = func(it *Iterator, c byte) (interface{}, error) { 13 return it.readString() 14 } 15 readFunctions['n'] = func(it *Iterator, c byte) (interface{}, error) { 16 return nil, it.expectBytes("ull") 17 } 18 readFunctions['t'] = func(it *Iterator, c byte) (interface{}, error) { 19 return true, it.expectBytes("rue") 20 } 21 readFunctions['f'] = func(it *Iterator, c byte) (interface{}, error) { 22 return false, it.expectBytes("alse") 23 } 24 readFunctions['['] = readArrayWithStack 25 readFunctions['{'] = readObjectWithStack 26 for _, c := range []byte("-0123456789") { 27 readFunctions[c] = func(it *Iterator, c byte) (interface{}, error) { 28 if it.useNumber { 29 s, err := it.readNumberAsString(c) 30 return json.Number(s), err 31 } 32 return it.readFloat64(c) 33 } 34 } 35 errFunc := func(it *Iterator, c byte) (interface{}, error) { 36 return nil, UnexpectedByteError{got: c} 37 } 38 for i := 0; i < charNum; i++ { 39 if readFunctions[i] == nil { 40 readFunctions[i] = errFunc 41 } 42 } 43 } 44 45 // Read reads a json object as a golang object 46 func (it *Iterator) Read() (interface{}, error) { 47 c, err := it.nextToken() 48 if err != nil { 49 return nil, err 50 } 51 it.head++ 52 return readFunctions[c](it, c) 53 } 54 55 func readWithStack(it *Iterator, top stackElement, s *stack, ns *nodeStack) ( 56 _ interface{}, err error) { 57 var c byte 58 for { 59 c, err = it.nextToken() 60 if err != nil { 61 return nil, err 62 } 63 it.head++ 64 if top&1 == 0 { 65 // stackElementObjectBegin 66 // stackElementObject 67 if c == '}' { 68 if top = s.pop(); top == stackElementNone { 69 return ns.topObject(), nil 70 } 71 ns.popObject() 72 continue 73 } 74 if top == stackElementObject { 75 if c != ',' { 76 return nil, UnexpectedByteError{got: c, exp: ','} 77 } 78 c, err = it.nextToken() 79 if err != nil { 80 return nil, err 81 } 82 it.head++ 83 } 84 if c != '"' { 85 return nil, UnexpectedByteError{got: c, exp: '"'} 86 } 87 field, err := it.readObjectField() 88 if err != nil { 89 return nil, err 90 } 91 c, err = it.nextToken() 92 if err != nil { 93 return nil, err 94 } 95 it.head++ 96 switch c { 97 case '[': 98 s.pushObject() 99 ns.pushArray(field) 100 top = stackElementArrayBegin 101 case '{': 102 s.pushObject() 103 ns.pushObject(field) 104 top = stackElementObjectBegin 105 default: 106 o, err := readFunctions[c](it, c) 107 if err != nil { 108 return nil, err 109 } 110 top = stackElementObject 111 ns.setTopObject(field, o) 112 } 113 } else { 114 // stackElementArrayBegin 115 // stackElementArray 116 if c == ']' { 117 if top = s.pop(); top == stackElementNone { 118 return ns.topArray(), nil 119 } 120 ns.popArray() 121 continue 122 } 123 if top == stackElementArray { 124 if c != ',' { 125 return nil, UnexpectedByteError{got: c, exp: ','} 126 } 127 c, err = it.nextToken() 128 if err != nil { 129 return nil, err 130 } 131 it.head++ 132 } 133 switch c { 134 case '[': 135 s.pushArray() 136 ns.pushArray("") 137 top = stackElementArrayBegin 138 case '{': 139 s.pushArray() 140 ns.pushObject("") 141 top = stackElementObjectBegin 142 default: 143 o, err := readFunctions[c](it, c) 144 if err != nil { 145 return nil, err 146 } 147 top = stackElementArray 148 ns.appendTopArray(o) 149 } 150 } 151 } 152 }