github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/json/decode.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package json 4 5 import ( 6 "bytes" 7 "encoding/base64" 8 "strconv" 9 10 "../convert" 11 "../protocol" 12 ) 13 14 // Decoder store data to decode data by each method! 15 type Decoder struct { 16 Buf []byte 17 Token byte 18 LastItem []byte 19 } 20 21 // Offset make d.Buf to start of given offset 22 func (d *Decoder) Offset(o int) { 23 d.Buf = d.Buf[o:] 24 } 25 26 // FindEndToken find next end json token 27 func (d *Decoder) FindEndToken() { 28 for i, c := range d.Buf { 29 switch c { 30 case ',': 31 d.Token = ',' 32 d.LastItem = d.Buf[:i] 33 d.Buf = d.Buf[i:] 34 return 35 case ']': 36 d.Token = ']' 37 d.LastItem = d.Buf[:i] 38 d.Buf = d.Buf[i:] 39 return 40 case '}': 41 d.Token = '}' 42 d.LastItem = d.Buf[:i] 43 d.Buf = d.Buf[i:] 44 return 45 } 46 } 47 } 48 49 // TrimToDigit remove any data and set Buf to first charecter as number 50 func (d *Decoder) TrimToDigit() { 51 for i, c := range d.Buf { 52 if '0' <= c && c <= '9' { 53 d.Buf = d.Buf[i:] 54 return 55 } 56 } 57 } 58 59 // TrimSpaces remove any spaces from Buf 60 func (d *Decoder) TrimSpaces() { 61 for i, c := range d.Buf { 62 if c != ' ' { 63 d.Buf = d.Buf[i:] 64 return 65 } 66 } 67 } 68 69 // TrimToStringStart remove any data from Buf to first charecter after quotation mark as '"' 70 func (d *Decoder) TrimToStringStart() { 71 for i, c := range d.Buf { 72 if c == '"' { 73 d.Buf = d.Buf[i+1:] // remove any byte before " due to don't need them 74 return 75 } 76 } 77 } 78 79 // CheckNullValue check if null exist as value. pass d.Buf start from after : and receive from from after , if null exist 80 func (d *Decoder) CheckNullValue() (null bool) { 81 for i, c := range d.Buf { 82 switch c { 83 case 'n': 84 if bytes.Equal(d.Buf[i:i+4], []byte("null")) { 85 null = true 86 } 87 case '"': 88 return false 89 case ',': 90 return 91 } 92 } 93 return 94 } 95 96 // ResetToken set d.Token to nil 97 func (d *Decoder) ResetToken() { 98 d.Token = 0 99 } 100 101 // CheckToken set d.Token to nil 102 func (d *Decoder) CheckToken(t byte) bool { 103 if d.Token == t { 104 d.ResetToken() 105 return true 106 } 107 return false 108 } 109 110 // DecodeKey return key very safe for each decode iteration. pass d.Buf start from any where and receive from after : 111 func (d *Decoder) DecodeKey() string { 112 d.TrimToStringStart() 113 var loc = bytes.IndexByte(d.Buf, '"') 114 if loc < 0 { 115 return "" 116 } 117 118 var key []byte = d.Buf[:loc] 119 120 d.Buf = d.Buf[loc+1:] // remove any byte before last " due to don't need them 121 loc = bytes.IndexByte(d.Buf, ':') 122 d.Buf = d.Buf[loc+1:] 123 return convert.UnsafeByteSliceToString(key) 124 } 125 126 // NotFoundKey call in default switch of each decode iteration 127 func (d *Decoder) NotFoundKey() (err protocol.Error) { 128 d.FindEndToken() 129 return 130 } 131 132 // NotFoundKeyStrict call in default switch of each decode iteration in strict mode. 133 func (d *Decoder) NotFoundKeyStrict() protocol.Error { 134 return ErrEncodedIncludeNotDeffiendKey 135 } 136 137 // DecodeBool convert string base boolean to bool. pass d.Buf start from after : and receive from after , 138 func (d *Decoder) DecodeBool() (b bool, err protocol.Error) { 139 d.TrimSpaces() 140 if d.Buf[0] == 't' { 141 b = true 142 d.Offset(5) // true, 143 } else { 144 // b = false 145 d.Offset(6) // false, 146 } 147 return 148 } 149 150 // DecodeUInt8 convert 8bit integer number string to number. pass d.Buf start from number and receive from after , 151 func (d *Decoder) DecodeUInt8() (ui uint8, err protocol.Error) { 152 d.TrimToDigit() 153 d.FindEndToken() 154 ui, err = convert.StringToUint8Base10(convert.UnsafeByteSliceToString(d.LastItem)) 155 if err != nil { 156 err = ErrEncodedIntegerCorrupted 157 return 158 } 159 return 160 } 161 162 // DecodeUInt16 convert 16bit integer number string to number. pass d.Buf start from number and receive from after , 163 func (d *Decoder) DecodeUInt16() (ui uint16, err protocol.Error) { 164 d.TrimToDigit() 165 d.FindEndToken() 166 ui, err = convert.StringToUint16Base10(convert.UnsafeByteSliceToString(d.LastItem)) 167 if err != nil { 168 err = ErrEncodedIntegerCorrupted 169 return 170 } 171 return 172 } 173 174 // DecodeUInt32 convert 32bit integer number string to number. pass d.Buf start from number and receive from after , 175 func (d *Decoder) DecodeUInt32() (ui uint32, err protocol.Error) { 176 d.TrimToDigit() 177 d.FindEndToken() 178 ui, err = convert.StringToUint32Base10(convert.UnsafeByteSliceToString(d.LastItem)) 179 if err != nil { 180 err = ErrEncodedIntegerCorrupted 181 return 182 } 183 return 184 } 185 186 // DecodeUInt64 convert 64bit integer number string to number. pass d.Buf start from after : and receive from after , 187 func (d *Decoder) DecodeUInt64() (ui uint64, err protocol.Error) { 188 d.TrimToDigit() 189 d.FindEndToken() 190 ui, err = convert.StringToUint64Base10(convert.UnsafeByteSliceToString(d.LastItem)) 191 if err != nil { 192 err = ErrEncodedIntegerCorrupted 193 return 194 } 195 return 196 } 197 198 // DecodeInt64 convert 64bit number string to number. pass d.Buf start from number and receive from after , 199 func (d *Decoder) DecodeInt64() (i int64, err protocol.Error) { 200 d.TrimToDigit() 201 d.FindEndToken() 202 var goErr error 203 i, goErr = strconv.ParseInt(convert.UnsafeByteSliceToString(d.LastItem), 10, 64) 204 if goErr != nil { 205 return 0, ErrEncodedIntegerCorrupted 206 } 207 return 208 } 209 210 // DecodeFloat64AsNumber convert float64 number string to float64 number. pass d.Buf start from after : and receive from , 211 func (d *Decoder) DecodeFloat64AsNumber() (f float64, err protocol.Error) { 212 d.TrimToDigit() 213 d.FindEndToken() 214 var goErr error 215 f, goErr = strconv.ParseFloat(convert.UnsafeByteSliceToString(d.LastItem), 64) 216 if goErr != nil { 217 return 0, ErrEncodedIntegerCorrupted 218 } 219 return 220 } 221 222 // DecodeString return string. pass d.Buf start from after : and receive from from after " 223 func (d *Decoder) DecodeString() (s string, err protocol.Error) { 224 if d.CheckNullValue() { 225 return 226 } 227 228 d.TrimToStringStart() 229 var loc = bytes.IndexByte(d.Buf, '"') 230 if loc < 0 { 231 err = ErrEncodedStringCorrupted 232 return 233 } 234 235 var slice []byte = d.Buf[:loc] 236 237 d.Offset(loc + 1) 238 s = string(slice) 239 return 240 } 241 242 /* 243 Array part 244 */ 245 246 // DecodeByteArrayAsBase64 convert base64 string to [n]byte 247 func (d *Decoder) DecodeByteArrayAsBase64(array []byte) (err protocol.Error) { 248 if d.CheckNullValue() { 249 return 250 } 251 252 d.TrimToStringStart() 253 var loc = bytes.IndexByte(d.Buf, '"') 254 if loc < 0 { 255 err = ErrEncodedArrayCorrupted 256 return 257 } 258 259 var goErr error 260 _, goErr = base64.RawStdEncoding.Decode(array, d.Buf[:loc]) 261 if goErr != nil { 262 return ErrEncodedArrayCorrupted 263 } 264 265 d.FindEndToken() 266 return 267 } 268 269 // DecodeByteArrayAsNumber convert number array to [n]byte 270 func (d *Decoder) DecodeByteArrayAsNumber(array []byte) (err protocol.Error) { 271 if d.CheckNullValue() { 272 return 273 } 274 275 var value uint8 276 for i := 0; i < len(array); i++ { 277 value, err = d.DecodeUInt8() 278 if err != nil { 279 err = ErrEncodedArrayCorrupted 280 return 281 } 282 array[i] = value 283 d.FindEndToken() 284 } 285 if d.Token != ']' { 286 err = ErrEncodedArrayCorrupted 287 } 288 return 289 } 290 291 /* 292 Slice as Number 293 */ 294 295 // DecodeByteSliceAsNumber convert number string slice to []byte. pass buf start from after [ and receive from after ] 296 func (d *Decoder) DecodeByteSliceAsNumber() (slice []byte, err protocol.Error) { 297 slice = make([]byte, 0, 8) // TODO::: Is cap efficient enough? 298 299 var num uint8 300 for !d.CheckToken(']') { 301 num, err = d.DecodeUInt8() 302 if err != nil { 303 err = ErrEncodedSliceCorrupted 304 return 305 } 306 slice = append(slice, num) 307 308 d.FindEndToken() 309 } 310 return 311 } 312 313 // DecodeUInt16SliceAsNumber convert uint16 number string slice to []byte. pass buf start from after [ and receive from after ] 314 func (d *Decoder) DecodeUInt16SliceAsNumber() (slice []uint16, err protocol.Error) { 315 slice = make([]uint16, 0, 8) // TODO::: Is cap efficient enough? 316 317 var num uint16 318 for !d.CheckToken(']') { 319 num, err = d.DecodeUInt16() 320 if err != nil { 321 err = ErrEncodedSliceCorrupted 322 return 323 } 324 slice = append(slice, num) 325 326 d.FindEndToken() 327 } 328 return 329 } 330 331 // DecodeUInt32SliceAsNumber convert uint32 number string slice to []byte. pass buf start from after [ and receive from after ] 332 func (d *Decoder) DecodeUInt32SliceAsNumber() (slice []uint32, err protocol.Error) { 333 slice = make([]uint32, 0, 8) // TODO::: Is cap efficient enough? 334 335 var num uint32 336 for !d.CheckToken(']') { 337 num, err = d.DecodeUInt32() 338 if err != nil { 339 err = ErrEncodedSliceCorrupted 340 return 341 } 342 slice = append(slice, num) 343 344 d.FindEndToken() 345 } 346 return 347 } 348 349 // DecodeUInt64SliceAsNumber convert uint64 number string slice to []byte. pass buf start from after [ and receive from after ] 350 func (d *Decoder) DecodeUInt64SliceAsNumber() (slice []uint64, err protocol.Error) { 351 slice = make([]uint64, 0, 8) // TODO::: Is cap efficient enough? 352 353 var num uint64 354 for !d.CheckToken(']') { 355 num, err = d.DecodeUInt64() 356 if err != nil { 357 err = ErrEncodedSliceCorrupted 358 return 359 } 360 slice = append(slice, num) 361 362 d.FindEndToken() 363 } 364 return 365 } 366 367 /* 368 Slice as Base64 369 */ 370 371 // DecodeByteSliceAsBase64 convert base64 string to []byte 372 func (d *Decoder) DecodeByteSliceAsBase64() (slice []byte, err protocol.Error) { 373 d.TrimToStringStart() 374 var loc = bytes.IndexByte(d.Buf, '"') 375 if loc < 0 { 376 err = ErrEncodedSliceCorrupted 377 return 378 } 379 380 slice = make([]byte, base64.RawStdEncoding.DecodedLen(len(d.Buf[:loc]))) 381 var n int 382 var goErr error 383 n, goErr = base64.RawStdEncoding.Decode(slice, d.Buf[:loc]) 384 if goErr != nil { 385 return slice, ErrEncodedSliceCorrupted 386 } 387 slice = slice[:n] 388 389 d.FindEndToken() 390 return 391 } 392 393 // Decode32ByteArraySliceAsBase64 decode [32]byte base64 string slice. pass buf start from after [ and receive from after ] 394 func (d *Decoder) Decode32ByteArraySliceAsBase64() (slice [][32]byte, err protocol.Error) { 395 const base64Len = 43 // base64.RawStdEncoding.EncodedLen(len(32)) >> (32*8 + 5) / 6 396 slice = make([][32]byte, 0, 8) 397 398 var openBracketLoc = bytes.IndexByte(d.Buf, '[') 399 if openBracketLoc < 0 { 400 err = ErrEncodedSliceCorrupted 401 return 402 } 403 d.Buf = d.Buf[openBracketLoc+1:] 404 var goErr error 405 var array [32]byte 406 for !d.CheckToken(']') { 407 d.TrimToStringStart() 408 _, goErr = base64.RawStdEncoding.Decode(array[:], d.Buf[:base64Len]) 409 if goErr != nil { 410 err = ErrEncodedSliceCorrupted 411 return 412 } 413 slice = append(slice, array) 414 d.Buf = d.Buf[base64Len:] 415 d.FindEndToken() 416 } 417 return 418 }