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  }