...

Source file src/github.com/json-iterator/go/iter.go

Documentation: github.com/json-iterator/go

     1  package jsoniter
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  )
     8  
     9  // ValueType the type for JSON element
    10  type ValueType int
    11  
    12  const (
    13  	// InvalidValue invalid JSON element
    14  	InvalidValue ValueType = iota
    15  	// StringValue JSON element "string"
    16  	StringValue
    17  	// NumberValue JSON element 100 or 0.10
    18  	NumberValue
    19  	// NilValue JSON element null
    20  	NilValue
    21  	// BoolValue JSON element true or false
    22  	BoolValue
    23  	// ArrayValue JSON element []
    24  	ArrayValue
    25  	// ObjectValue JSON element {}
    26  	ObjectValue
    27  )
    28  
    29  var hexDigits []byte
    30  var valueTypes []ValueType
    31  
    32  func init() {
    33  	hexDigits = make([]byte, 256)
    34  	for i := 0; i < len(hexDigits); i++ {
    35  		hexDigits[i] = 255
    36  	}
    37  	for i := '0'; i <= '9'; i++ {
    38  		hexDigits[i] = byte(i - '0')
    39  	}
    40  	for i := 'a'; i <= 'f'; i++ {
    41  		hexDigits[i] = byte((i - 'a') + 10)
    42  	}
    43  	for i := 'A'; i <= 'F'; i++ {
    44  		hexDigits[i] = byte((i - 'A') + 10)
    45  	}
    46  	valueTypes = make([]ValueType, 256)
    47  	for i := 0; i < len(valueTypes); i++ {
    48  		valueTypes[i] = InvalidValue
    49  	}
    50  	valueTypes['"'] = StringValue
    51  	valueTypes['-'] = NumberValue
    52  	valueTypes['0'] = NumberValue
    53  	valueTypes['1'] = NumberValue
    54  	valueTypes['2'] = NumberValue
    55  	valueTypes['3'] = NumberValue
    56  	valueTypes['4'] = NumberValue
    57  	valueTypes['5'] = NumberValue
    58  	valueTypes['6'] = NumberValue
    59  	valueTypes['7'] = NumberValue
    60  	valueTypes['8'] = NumberValue
    61  	valueTypes['9'] = NumberValue
    62  	valueTypes['t'] = BoolValue
    63  	valueTypes['f'] = BoolValue
    64  	valueTypes['n'] = NilValue
    65  	valueTypes['['] = ArrayValue
    66  	valueTypes['{'] = ObjectValue
    67  }
    68  
    69  // Iterator is a io.Reader like object, with JSON specific read functions.
    70  // Error is not returned as return value, but stored as Error member on this iterator instance.
    71  type Iterator struct {
    72  	cfg              *frozenConfig
    73  	reader           io.Reader
    74  	buf              []byte
    75  	head             int
    76  	tail             int
    77  	depth            int
    78  	captureStartedAt int
    79  	captured         []byte
    80  	Error            error
    81  	Attachment       interface{} // open for customized decoder
    82  }
    83  
    84  // NewIterator creates an empty Iterator instance
    85  func NewIterator(cfg API) *Iterator {
    86  	return &Iterator{
    87  		cfg:    cfg.(*frozenConfig),
    88  		reader: nil,
    89  		buf:    nil,
    90  		head:   0,
    91  		tail:   0,
    92  		depth:  0,
    93  	}
    94  }
    95  
    96  // Parse creates an Iterator instance from io.Reader
    97  func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
    98  	return &Iterator{
    99  		cfg:    cfg.(*frozenConfig),
   100  		reader: reader,
   101  		buf:    make([]byte, bufSize),
   102  		head:   0,
   103  		tail:   0,
   104  		depth:  0,
   105  	}
   106  }
   107  
   108  // ParseBytes creates an Iterator instance from byte array
   109  func ParseBytes(cfg API, input []byte) *Iterator {
   110  	return &Iterator{
   111  		cfg:    cfg.(*frozenConfig),
   112  		reader: nil,
   113  		buf:    input,
   114  		head:   0,
   115  		tail:   len(input),
   116  		depth:  0,
   117  	}
   118  }
   119  
   120  // ParseString creates an Iterator instance from string
   121  func ParseString(cfg API, input string) *Iterator {
   122  	return ParseBytes(cfg, []byte(input))
   123  }
   124  
   125  // Pool returns a pool can provide more iterator with same configuration
   126  func (iter *Iterator) Pool() IteratorPool {
   127  	return iter.cfg
   128  }
   129  
   130  // Reset reuse iterator instance by specifying another reader
   131  func (iter *Iterator) Reset(reader io.Reader) *Iterator {
   132  	iter.reader = reader
   133  	iter.head = 0
   134  	iter.tail = 0
   135  	iter.depth = 0
   136  	return iter
   137  }
   138  
   139  // ResetBytes reuse iterator instance by specifying another byte array as input
   140  func (iter *Iterator) ResetBytes(input []byte) *Iterator {
   141  	iter.reader = nil
   142  	iter.buf = input
   143  	iter.head = 0
   144  	iter.tail = len(input)
   145  	iter.depth = 0
   146  	return iter
   147  }
   148  
   149  // WhatIsNext gets ValueType of relatively next json element
   150  func (iter *Iterator) WhatIsNext() ValueType {
   151  	valueType := valueTypes[iter.nextToken()]
   152  	iter.unreadByte()
   153  	return valueType
   154  }
   155  
   156  func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
   157  	for i := iter.head; i < iter.tail; i++ {
   158  		c := iter.buf[i]
   159  		switch c {
   160  		case ' ', '\n', '\t', '\r':
   161  			continue
   162  		}
   163  		iter.head = i
   164  		return false
   165  	}
   166  	return true
   167  }
   168  
   169  func (iter *Iterator) isObjectEnd() bool {
   170  	c := iter.nextToken()
   171  	if c == ',' {
   172  		return false
   173  	}
   174  	if c == '}' {
   175  		return true
   176  	}
   177  	iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
   178  	return true
   179  }
   180  
   181  func (iter *Iterator) nextToken() byte {
   182  	// a variation of skip whitespaces, returning the next non-whitespace token
   183  	for {
   184  		for i := iter.head; i < iter.tail; i++ {
   185  			c := iter.buf[i]
   186  			switch c {
   187  			case ' ', '\n', '\t', '\r':
   188  				continue
   189  			}
   190  			iter.head = i + 1
   191  			return c
   192  		}
   193  		if !iter.loadMore() {
   194  			return 0
   195  		}
   196  	}
   197  }
   198  
   199  // ReportError record a error in iterator instance with current position.
   200  func (iter *Iterator) ReportError(operation string, msg string) {
   201  	if iter.Error != nil {
   202  		if iter.Error != io.EOF {
   203  			return
   204  		}
   205  	}
   206  	peekStart := iter.head - 10
   207  	if peekStart < 0 {
   208  		peekStart = 0
   209  	}
   210  	peekEnd := iter.head + 10
   211  	if peekEnd > iter.tail {
   212  		peekEnd = iter.tail
   213  	}
   214  	parsing := string(iter.buf[peekStart:peekEnd])
   215  	contextStart := iter.head - 50
   216  	if contextStart < 0 {
   217  		contextStart = 0
   218  	}
   219  	contextEnd := iter.head + 50
   220  	if contextEnd > iter.tail {
   221  		contextEnd = iter.tail
   222  	}
   223  	context := string(iter.buf[contextStart:contextEnd])
   224  	iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
   225  		operation, msg, iter.head-peekStart, parsing, context)
   226  }
   227  
   228  // CurrentBuffer gets current buffer as string for debugging purpose
   229  func (iter *Iterator) CurrentBuffer() string {
   230  	peekStart := iter.head - 10
   231  	if peekStart < 0 {
   232  		peekStart = 0
   233  	}
   234  	return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
   235  		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
   236  }
   237  
   238  func (iter *Iterator) readByte() (ret byte) {
   239  	if iter.head == iter.tail {
   240  		if iter.loadMore() {
   241  			ret = iter.buf[iter.head]
   242  			iter.head++
   243  			return ret
   244  		}
   245  		return 0
   246  	}
   247  	ret = iter.buf[iter.head]
   248  	iter.head++
   249  	return ret
   250  }
   251  
   252  func (iter *Iterator) loadMore() bool {
   253  	if iter.reader == nil {
   254  		if iter.Error == nil {
   255  			iter.head = iter.tail
   256  			iter.Error = io.EOF
   257  		}
   258  		return false
   259  	}
   260  	if iter.captured != nil {
   261  		iter.captured = append(iter.captured,
   262  			iter.buf[iter.captureStartedAt:iter.tail]...)
   263  		iter.captureStartedAt = 0
   264  	}
   265  	for {
   266  		n, err := iter.reader.Read(iter.buf)
   267  		if n == 0 {
   268  			if err != nil {
   269  				if iter.Error == nil {
   270  					iter.Error = err
   271  				}
   272  				return false
   273  			}
   274  		} else {
   275  			iter.head = 0
   276  			iter.tail = n
   277  			return true
   278  		}
   279  	}
   280  }
   281  
   282  func (iter *Iterator) unreadByte() {
   283  	if iter.Error != nil {
   284  		return
   285  	}
   286  	iter.head--
   287  	return
   288  }
   289  
   290  // Read read the next JSON element as generic interface{}.
   291  func (iter *Iterator) Read() interface{} {
   292  	valueType := iter.WhatIsNext()
   293  	switch valueType {
   294  	case StringValue:
   295  		return iter.ReadString()
   296  	case NumberValue:
   297  		if iter.cfg.configBeforeFrozen.UseNumber {
   298  			return json.Number(iter.readNumberAsString())
   299  		}
   300  		return iter.ReadFloat64()
   301  	case NilValue:
   302  		iter.skipFourBytes('n', 'u', 'l', 'l')
   303  		return nil
   304  	case BoolValue:
   305  		return iter.ReadBool()
   306  	case ArrayValue:
   307  		arr := []interface{}{}
   308  		iter.ReadArrayCB(func(iter *Iterator) bool {
   309  			var elem interface{}
   310  			iter.ReadVal(&elem)
   311  			arr = append(arr, elem)
   312  			return true
   313  		})
   314  		return arr
   315  	case ObjectValue:
   316  		obj := map[string]interface{}{}
   317  		iter.ReadMapCB(func(Iter *Iterator, field string) bool {
   318  			var elem interface{}
   319  			iter.ReadVal(&elem)
   320  			obj[field] = elem
   321  			return true
   322  		})
   323  		return obj
   324  	default:
   325  		iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
   326  		return nil
   327  	}
   328  }
   329  
   330  // limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
   331  const maxDepth = 10000
   332  
   333  func (iter *Iterator) incrementDepth() (success bool) {
   334  	iter.depth++
   335  	if iter.depth <= maxDepth {
   336  		return true
   337  	}
   338  	iter.ReportError("incrementDepth", "exceeded max depth")
   339  	return false
   340  }
   341  
   342  func (iter *Iterator) decrementDepth() (success bool) {
   343  	iter.depth--
   344  	if iter.depth >= 0 {
   345  		return true
   346  	}
   347  	iter.ReportError("decrementDepth", "unexpected negative nesting")
   348  	return false
   349  }
   350  

View as plain text