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  }