github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_read_object.go (about) 1 package jzon 2 3 func readObjectWithStack(it *Iterator, _ byte) (interface{}, error) { 4 c, err := it.nextToken() 5 if err != nil { 6 return nil, err 7 } 8 topObj := map[string]interface{}{} 9 if c == '}' { 10 it.head++ 11 return topObj, nil 12 } 13 for { 14 if c != '"' { 15 return nil, UnexpectedByteError{got: c, exp: '"'} 16 } 17 it.head++ 18 field, err := it.readObjectField() 19 if err != nil { 20 return nil, err 21 } 22 c, err = it.nextToken() 23 if err != nil { 24 return nil, err 25 } 26 it.head++ 27 // We disabled the following switch to test benchmark 28 // comparing to using builtin stack 29 // the result is using ours own stack will improve the 30 // performance by about 25% 31 switch c { 32 case '{': 33 s := stackPool.Get().(*stack).initObject() 34 ns := nodeStackPool.Get().(*nodeStack). 35 initObject(topObj). 36 pushObject(field) 37 ret, err := readWithStack(it, stackElementObjectBegin, s, ns) 38 releaseNodeStack(ns) 39 stackPool.Put(s) 40 return ret, err 41 case '[': 42 s := stackPool.Get().(*stack).initObject() 43 ns := nodeStackPool.Get().(*nodeStack). 44 initObject(topObj). 45 pushArray(field) 46 ret, err := readWithStack(it, stackElementArrayBegin, s, ns) 47 releaseNodeStack(ns) 48 stackPool.Put(s) 49 return ret, err 50 } 51 o, err := readFunctions[c](it, c) 52 if err != nil { 53 return nil, err 54 } 55 topObj[field] = o 56 c, err = it.nextToken() 57 if err != nil { 58 return nil, err 59 } 60 it.head++ 61 if c == '}' { 62 return topObj, nil 63 } 64 if c != ',' { 65 return nil, UnexpectedByteError{got: c, exp: '}', exp2: ','} 66 } 67 c, err = it.nextToken() 68 if err != nil { 69 return nil, err 70 } 71 } 72 }