...

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

Documentation: github.com/json-iterator/go

     1  //+build jsoniter_sloppy
     2  
     3  package jsoniter
     4  
     5  // sloppy but faster implementation, do not validate the input json
     6  
     7  func (iter *Iterator) skipNumber() {
     8  	for {
     9  		for i := iter.head; i < iter.tail; i++ {
    10  			c := iter.buf[i]
    11  			switch c {
    12  			case ' ', '\n', '\r', '\t', ',', '}', ']':
    13  				iter.head = i
    14  				return
    15  			}
    16  		}
    17  		if !iter.loadMore() {
    18  			return
    19  		}
    20  	}
    21  }
    22  
    23  func (iter *Iterator) skipArray() {
    24  	level := 1
    25  	if !iter.incrementDepth() {
    26  		return
    27  	}
    28  	for {
    29  		for i := iter.head; i < iter.tail; i++ {
    30  			switch iter.buf[i] {
    31  			case '"': // If inside string, skip it
    32  				iter.head = i + 1
    33  				iter.skipString()
    34  				i = iter.head - 1 // it will be i++ soon
    35  			case '[': // If open symbol, increase level
    36  				level++
    37  				if !iter.incrementDepth() {
    38  					return
    39  				}
    40  			case ']': // If close symbol, increase level
    41  				level--
    42  				if !iter.decrementDepth() {
    43  					return
    44  				}
    45  
    46  				// If we have returned to the original level, we're done
    47  				if level == 0 {
    48  					iter.head = i + 1
    49  					return
    50  				}
    51  			}
    52  		}
    53  		if !iter.loadMore() {
    54  			iter.ReportError("skipObject", "incomplete array")
    55  			return
    56  		}
    57  	}
    58  }
    59  
    60  func (iter *Iterator) skipObject() {
    61  	level := 1
    62  	if !iter.incrementDepth() {
    63  		return
    64  	}
    65  
    66  	for {
    67  		for i := iter.head; i < iter.tail; i++ {
    68  			switch iter.buf[i] {
    69  			case '"': // If inside string, skip it
    70  				iter.head = i + 1
    71  				iter.skipString()
    72  				i = iter.head - 1 // it will be i++ soon
    73  			case '{': // If open symbol, increase level
    74  				level++
    75  				if !iter.incrementDepth() {
    76  					return
    77  				}
    78  			case '}': // If close symbol, increase level
    79  				level--
    80  				if !iter.decrementDepth() {
    81  					return
    82  				}
    83  
    84  				// If we have returned to the original level, we're done
    85  				if level == 0 {
    86  					iter.head = i + 1
    87  					return
    88  				}
    89  			}
    90  		}
    91  		if !iter.loadMore() {
    92  			iter.ReportError("skipObject", "incomplete object")
    93  			return
    94  		}
    95  	}
    96  }
    97  
    98  func (iter *Iterator) skipString() {
    99  	for {
   100  		end, escaped := iter.findStringEnd()
   101  		if end == -1 {
   102  			if !iter.loadMore() {
   103  				iter.ReportError("skipString", "incomplete string")
   104  				return
   105  			}
   106  			if escaped {
   107  				iter.head = 1 // skip the first char as last char read is \
   108  			}
   109  		} else {
   110  			iter.head = end
   111  			return
   112  		}
   113  	}
   114  }
   115  
   116  // adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
   117  // Tries to find the end of string
   118  // Support if string contains escaped quote symbols.
   119  func (iter *Iterator) findStringEnd() (int, bool) {
   120  	escaped := false
   121  	for i := iter.head; i < iter.tail; i++ {
   122  		c := iter.buf[i]
   123  		if c == '"' {
   124  			if !escaped {
   125  				return i + 1, false
   126  			}
   127  			j := i - 1
   128  			for {
   129  				if j < iter.head || iter.buf[j] != '\\' {
   130  					// even number of backslashes
   131  					// either end of buffer, or " found
   132  					return i + 1, true
   133  				}
   134  				j--
   135  				if j < iter.head || iter.buf[j] != '\\' {
   136  					// odd number of backslashes
   137  					// it is \" or \\\"
   138  					break
   139  				}
   140  				j--
   141  			}
   142  		} else if c == '\\' {
   143  			escaped = true
   144  		}
   145  	}
   146  	j := iter.tail - 1
   147  	for {
   148  		if j < iter.head || iter.buf[j] != '\\' {
   149  			// even number of backslashes
   150  			// either end of buffer, or " found
   151  			return -1, false // do not end with \
   152  		}
   153  		j--
   154  		if j < iter.head || iter.buf[j] != '\\' {
   155  			// odd number of backslashes
   156  			// it is \" or \\\"
   157  			break
   158  		}
   159  		j--
   160  
   161  	}
   162  	return -1, true // end with \
   163  }
   164  

View as plain text