gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

iter_skip_sloppy.go (3255B)


      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 }