gtsocial-umbx

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

iter_object.go (6362B)


      1 package jsoniter
      2 
      3 import (
      4 	"fmt"
      5 	"strings"
      6 )
      7 
      8 // ReadObject read one field from object.
      9 // If object ended, returns empty string.
     10 // Otherwise, returns the field name.
     11 func (iter *Iterator) ReadObject() (ret string) {
     12 	c := iter.nextToken()
     13 	switch c {
     14 	case 'n':
     15 		iter.skipThreeBytes('u', 'l', 'l')
     16 		return "" // null
     17 	case '{':
     18 		c = iter.nextToken()
     19 		if c == '"' {
     20 			iter.unreadByte()
     21 			field := iter.ReadString()
     22 			c = iter.nextToken()
     23 			if c != ':' {
     24 				iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
     25 			}
     26 			return field
     27 		}
     28 		if c == '}' {
     29 			return "" // end of object
     30 		}
     31 		iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c}))
     32 		return
     33 	case ',':
     34 		field := iter.ReadString()
     35 		c = iter.nextToken()
     36 		if c != ':' {
     37 			iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
     38 		}
     39 		return field
     40 	case '}':
     41 		return "" // end of object
     42 	default:
     43 		iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c})))
     44 		return
     45 	}
     46 }
     47 
     48 // CaseInsensitive
     49 func (iter *Iterator) readFieldHash() int64 {
     50 	hash := int64(0x811c9dc5)
     51 	c := iter.nextToken()
     52 	if c != '"' {
     53 		iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
     54 		return 0
     55 	}
     56 	for {
     57 		for i := iter.head; i < iter.tail; i++ {
     58 			// require ascii string and no escape
     59 			b := iter.buf[i]
     60 			if b == '\\' {
     61 				iter.head = i
     62 				for _, b := range iter.readStringSlowPath() {
     63 					if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
     64 						b += 'a' - 'A'
     65 					}
     66 					hash ^= int64(b)
     67 					hash *= 0x1000193
     68 				}
     69 				c = iter.nextToken()
     70 				if c != ':' {
     71 					iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
     72 					return 0
     73 				}
     74 				return hash
     75 			}
     76 			if b == '"' {
     77 				iter.head = i + 1
     78 				c = iter.nextToken()
     79 				if c != ':' {
     80 					iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
     81 					return 0
     82 				}
     83 				return hash
     84 			}
     85 			if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
     86 				b += 'a' - 'A'
     87 			}
     88 			hash ^= int64(b)
     89 			hash *= 0x1000193
     90 		}
     91 		if !iter.loadMore() {
     92 			iter.ReportError("readFieldHash", `incomplete field name`)
     93 			return 0
     94 		}
     95 	}
     96 }
     97 
     98 func calcHash(str string, caseSensitive bool) int64 {
     99 	if !caseSensitive {
    100 		str = strings.ToLower(str)
    101 	}
    102 	hash := int64(0x811c9dc5)
    103 	for _, b := range []byte(str) {
    104 		hash ^= int64(b)
    105 		hash *= 0x1000193
    106 	}
    107 	return int64(hash)
    108 }
    109 
    110 // ReadObjectCB read object with callback, the key is ascii only and field name not copied
    111 func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
    112 	c := iter.nextToken()
    113 	var field string
    114 	if c == '{' {
    115 		if !iter.incrementDepth() {
    116 			return false
    117 		}
    118 		c = iter.nextToken()
    119 		if c == '"' {
    120 			iter.unreadByte()
    121 			field = iter.ReadString()
    122 			c = iter.nextToken()
    123 			if c != ':' {
    124 				iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
    125 			}
    126 			if !callback(iter, field) {
    127 				iter.decrementDepth()
    128 				return false
    129 			}
    130 			c = iter.nextToken()
    131 			for c == ',' {
    132 				field = iter.ReadString()
    133 				c = iter.nextToken()
    134 				if c != ':' {
    135 					iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
    136 				}
    137 				if !callback(iter, field) {
    138 					iter.decrementDepth()
    139 					return false
    140 				}
    141 				c = iter.nextToken()
    142 			}
    143 			if c != '}' {
    144 				iter.ReportError("ReadObjectCB", `object not ended with }`)
    145 				iter.decrementDepth()
    146 				return false
    147 			}
    148 			return iter.decrementDepth()
    149 		}
    150 		if c == '}' {
    151 			return iter.decrementDepth()
    152 		}
    153 		iter.ReportError("ReadObjectCB", `expect " after {, but found `+string([]byte{c}))
    154 		iter.decrementDepth()
    155 		return false
    156 	}
    157 	if c == 'n' {
    158 		iter.skipThreeBytes('u', 'l', 'l')
    159 		return true // null
    160 	}
    161 	iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c}))
    162 	return false
    163 }
    164 
    165 // ReadMapCB read map with callback, the key can be any string
    166 func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
    167 	c := iter.nextToken()
    168 	if c == '{' {
    169 		if !iter.incrementDepth() {
    170 			return false
    171 		}
    172 		c = iter.nextToken()
    173 		if c == '"' {
    174 			iter.unreadByte()
    175 			field := iter.ReadString()
    176 			if iter.nextToken() != ':' {
    177 				iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
    178 				iter.decrementDepth()
    179 				return false
    180 			}
    181 			if !callback(iter, field) {
    182 				iter.decrementDepth()
    183 				return false
    184 			}
    185 			c = iter.nextToken()
    186 			for c == ',' {
    187 				field = iter.ReadString()
    188 				if iter.nextToken() != ':' {
    189 					iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
    190 					iter.decrementDepth()
    191 					return false
    192 				}
    193 				if !callback(iter, field) {
    194 					iter.decrementDepth()
    195 					return false
    196 				}
    197 				c = iter.nextToken()
    198 			}
    199 			if c != '}' {
    200 				iter.ReportError("ReadMapCB", `object not ended with }`)
    201 				iter.decrementDepth()
    202 				return false
    203 			}
    204 			return iter.decrementDepth()
    205 		}
    206 		if c == '}' {
    207 			return iter.decrementDepth()
    208 		}
    209 		iter.ReportError("ReadMapCB", `expect " after {, but found `+string([]byte{c}))
    210 		iter.decrementDepth()
    211 		return false
    212 	}
    213 	if c == 'n' {
    214 		iter.skipThreeBytes('u', 'l', 'l')
    215 		return true // null
    216 	}
    217 	iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
    218 	return false
    219 }
    220 
    221 func (iter *Iterator) readObjectStart() bool {
    222 	c := iter.nextToken()
    223 	if c == '{' {
    224 		c = iter.nextToken()
    225 		if c == '}' {
    226 			return false
    227 		}
    228 		iter.unreadByte()
    229 		return true
    230 	} else if c == 'n' {
    231 		iter.skipThreeBytes('u', 'l', 'l')
    232 		return false
    233 	}
    234 	iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c}))
    235 	return false
    236 }
    237 
    238 func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) {
    239 	str := iter.ReadStringAsSlice()
    240 	if iter.skipWhitespacesWithoutLoadMore() {
    241 		if ret == nil {
    242 			ret = make([]byte, len(str))
    243 			copy(ret, str)
    244 		}
    245 		if !iter.loadMore() {
    246 			return
    247 		}
    248 	}
    249 	if iter.buf[iter.head] != ':' {
    250 		iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]}))
    251 		return
    252 	}
    253 	iter.head++
    254 	if iter.skipWhitespacesWithoutLoadMore() {
    255 		if ret == nil {
    256 			ret = make([]byte, len(str))
    257 			copy(ret, str)
    258 		}
    259 		if !iter.loadMore() {
    260 			return
    261 		}
    262 	}
    263 	if ret == nil {
    264 		return str
    265 	}
    266 	return ret
    267 }