github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/json/decode-minified.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 // DecoderMinifed store data to decode data by each method! 15 type DecoderMinifed 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 *DecoderMinifed) Offset(o int) { 23 d.Buf = d.Buf[o:] 24 } 25 26 // FindEndToken find next end json token 27 func (d *DecoderMinifed) 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 // ResetToken set d.Token to nil 50 func (d *DecoderMinifed) ResetToken() { 51 d.Token = 0 52 } 53 54 // CheckToken set d.Token to nil 55 func (d *DecoderMinifed) CheckToken(t byte) bool { 56 if d.Token == t { 57 d.ResetToken() 58 return true 59 } 60 return false 61 } 62 63 // DecodeKey return json key. pass d.Buf start from after {||, and receive from after : 64 func (d *DecoderMinifed) DecodeKey() string { 65 d.Offset(2) 66 var loc = bytes.IndexByte(d.Buf, '"') 67 var slice []byte = d.Buf[:loc] 68 d.Offset(loc + 2) // +2 due to have '":' after key name end! 69 return convert.UnsafeByteSliceToString(slice) 70 } 71 72 // NotFoundKey call in default switch of each decode iteration 73 func (d *DecoderMinifed) NotFoundKey() (err protocol.Error) { 74 d.FindEndToken() 75 return 76 } 77 78 // NotFoundKeyStrict call in default switch of each decode iteration in strict mode. 79 func (d *DecoderMinifed) NotFoundKeyStrict() protocol.Error { 80 return ErrEncodedIncludeNotDeffiendKey 81 } 82 83 // DecodeBool convert 64bit integer number string to number. pass d.Buf start from after : and receive from after , 84 func (d *DecoderMinifed) DecodeBool() (b bool, err protocol.Error) { 85 if d.Buf[0] == 't' { 86 b = true 87 d.Offset(5) // true, 88 } else { 89 // b = false 90 d.Offset(6) // false, 91 } 92 return 93 } 94 95 // DecodeUInt8 convert 8bit integer number string to number. pass d.Buf start from number and receive from after , 96 func (d *DecoderMinifed) DecodeUInt8() (ui uint8, err protocol.Error) { 97 d.FindEndToken() 98 ui, err = convert.StringToUint8Base10(convert.UnsafeByteSliceToString(d.LastItem)) 99 if err != nil { 100 err = ErrEncodedIntegerCorrupted 101 return 102 } 103 return 104 } 105 106 // DecodeUInt16 convert 16bit integer number string to number. pass d.Buf start from number and receive from after , 107 func (d *DecoderMinifed) DecodeUInt16() (ui uint16, err protocol.Error) { 108 d.FindEndToken() 109 ui, err = convert.StringToUint16Base10(convert.UnsafeByteSliceToString(d.LastItem)) 110 if err != nil { 111 err = ErrEncodedIntegerCorrupted 112 return 113 } 114 return 115 } 116 117 // DecodeUInt32 convert 32bit integer number string to number. pass d.Buf start from number and receive from after , 118 func (d *DecoderMinifed) DecodeUInt32() (ui uint32, err protocol.Error) { 119 d.FindEndToken() 120 ui, err = convert.StringToUint32Base10(convert.UnsafeByteSliceToString(d.LastItem)) 121 if err != nil { 122 err = ErrEncodedIntegerCorrupted 123 return 124 } 125 return 126 } 127 128 // DecodeUInt64 convert 64bit integer number string to number. pass d.Buf start from number and receive from after , 129 func (d *DecoderMinifed) DecodeUInt64() (ui uint64, err protocol.Error) { 130 d.FindEndToken() 131 ui, err = convert.StringToUint64Base10(convert.UnsafeByteSliceToString(d.LastItem)) 132 if err != nil { 133 err = ErrEncodedIntegerCorrupted 134 return 135 } 136 return 137 } 138 139 // DecodeInt32 convert 32bit number string to number. pass d.Buf start from number and receive from after end of number 140 func (d *DecoderUnsafe) DecodeInt32() (i int32, err protocol.Error) { 141 d.FindEndToken() 142 var goErr error 143 var num int64 144 num, goErr = strconv.ParseInt(convert.UnsafeByteSliceToString(d.LastItem), 10, 32) 145 if goErr != nil { 146 return 0, ErrEncodedIntegerCorrupted 147 } 148 i = int32(num) 149 return 150 } 151 152 // DecodeInt64 convert 64bit number string to number. pass d.Buf start from number and receive from after , 153 func (d *DecoderMinifed) DecodeInt64() (i int64, err protocol.Error) { 154 d.FindEndToken() 155 var goErr error 156 i, goErr = strconv.ParseInt(convert.UnsafeByteSliceToString(d.LastItem), 10, 64) 157 if goErr != nil { 158 return 0, ErrEncodedStringCorrupted 159 } 160 return 161 } 162 163 // DecodeFloat64AsNumber convert float64 number string to float64 number. pass d.Buf start from number and receive from , 164 func (d *DecoderMinifed) DecodeFloat64AsNumber() (f float64, err protocol.Error) { 165 d.FindEndToken() 166 var goErr error 167 f, goErr = strconv.ParseFloat(convert.UnsafeByteSliceToString(d.LastItem), 64) 168 if goErr != nil { 169 return 0, ErrEncodedStringCorrupted 170 } 171 return 172 } 173 174 // DecodeString return string. pass d.Buf start from after " and receive from from after " 175 func (d *DecoderMinifed) DecodeString() (s string) { 176 var loc int // Coma, Colon, bracket, ... location 177 loc = bytes.IndexByte(d.Buf, '"') 178 if loc < 0 { 179 // Reach last item of d.Buf! 180 loc = len(d.Buf) - 1 181 } 182 183 var slice []byte = d.Buf[:loc] 184 d.Offset(loc + 1) 185 return string(slice) 186 } 187 188 /* 189 Array part 190 */ 191 192 // DecodeByteArrayAsBase64 convert base64 string to [n]byte 193 func (d *DecoderMinifed) DecodeByteArrayAsBase64(array []byte) (err protocol.Error) { 194 d.Offset(1) // due to have " at start 195 196 var loc = bytes.IndexByte(d.Buf, '"') 197 if loc < 0 { 198 err = ErrEncodedArrayCorrupted 199 return 200 } 201 202 var goErr error 203 _, goErr = base64.RawStdEncoding.Decode(array, d.Buf[:loc]) 204 if goErr != nil { 205 return ErrEncodedArrayCorrupted 206 } 207 208 d.Offset(loc + 1) 209 return 210 } 211 212 // DecodeByteArrayAsNumber convert number array to [n]byte 213 func (d *DecoderMinifed) DecodeByteArrayAsNumber(array []byte) (err protocol.Error) { 214 var value uint8 215 for i := 0; i < len(array); i++ { 216 d.Offset(1) // due to have [ or , 217 value, err = d.DecodeUInt8() 218 if err != nil { 219 err = ErrEncodedArrayCorrupted 220 return 221 } 222 array[i] = value 223 } 224 if d.Buf[0] != ']' { 225 err = ErrEncodedArrayCorrupted 226 } 227 d.Offset(1) 228 return 229 } 230 231 /* 232 Slice as Number 233 */ 234 235 // DecodeByteSliceAsNumber convert number string slice to []byte. pass buf start from after [ and receive from after ] 236 func (d *DecoderMinifed) DecodeByteSliceAsNumber() (slice []byte, err protocol.Error) { 237 d.Offset(1) // due to have [ at start 238 slice = make([]byte, 0, 8) // TODO::: Is cap efficient enough? 239 240 var num uint8 241 for !d.CheckToken(']') { 242 num, err = d.DecodeUInt8() 243 if err != nil { 244 err = ErrEncodedSliceCorrupted 245 return 246 } 247 slice = append(slice, num) 248 d.Offset(1) 249 } 250 return 251 } 252 253 // DecodeUInt16SliceAsNumber convert uint16 number string slice to []byte. pass buf start from after [ and receive from after ] 254 func (d *DecoderMinifed) DecodeUInt16SliceAsNumber() (slice []uint16, err protocol.Error) { 255 d.Offset(1) // due to have [ at start 256 slice = make([]uint16, 0, 8) // TODO::: Is cap efficient enough? 257 258 var num uint16 259 for !d.CheckToken(']') { 260 num, err = d.DecodeUInt16() 261 if err != nil { 262 err = ErrEncodedSliceCorrupted 263 return 264 } 265 slice = append(slice, num) 266 d.Offset(1) 267 } 268 return 269 } 270 271 // DecodeUInt32SliceAsNumber convert uint32 number string slice to []byte. pass buf start from after [ and receive from after ] 272 func (d *DecoderMinifed) DecodeUInt32SliceAsNumber() (slice []uint32, err protocol.Error) { 273 d.Offset(1) // due to have [ at start 274 slice = make([]uint32, 0, 8) // TODO::: Is cap efficient enough? 275 276 var num uint32 277 for !d.CheckToken(']') { 278 num, err = d.DecodeUInt32() 279 if err != nil { 280 err = ErrEncodedSliceCorrupted 281 return 282 } 283 slice = append(slice, num) 284 d.Offset(1) 285 } 286 return 287 } 288 289 // DecodeUInt64SliceAsNumber convert uint64 number string slice to []byte. pass buf start from after [ and receive from after ] 290 func (d *DecoderMinifed) DecodeUInt64SliceAsNumber() (slice []uint64, err protocol.Error) { 291 d.Offset(1) // due to have [ at start 292 slice = make([]uint64, 0, 8) // TODO::: Is cap efficient enough? 293 294 var num uint64 295 for !d.CheckToken(']') { 296 num, err = d.DecodeUInt64() 297 if err != nil { 298 err = ErrEncodedSliceCorrupted 299 return 300 } 301 slice = append(slice, num) 302 d.Offset(1) 303 } 304 return 305 } 306 307 /* 308 Slice as Base64 309 */ 310 311 // DecodeByteSliceAsBase64 convert base64 string to []byte 312 func (d *DecoderMinifed) DecodeByteSliceAsBase64() (slice []byte, err protocol.Error) { 313 d.Offset(1) // due to have " at start 314 315 // Coma, Colon, bracket, ... location 316 var loc int = bytes.IndexByte(d.Buf, '"') 317 slice = make([]byte, base64.RawStdEncoding.DecodedLen(len(d.Buf[:loc]))) 318 var n int 319 var goErr error 320 n, goErr = base64.RawStdEncoding.Decode(slice, d.Buf[:loc]) 321 if goErr != nil { 322 err = ErrEncodedSliceCorrupted 323 return 324 } 325 slice = slice[:n] 326 327 d.Offset(loc + 1) 328 return 329 } 330 331 // Decode32ByteArraySliceAsBase64 decode [32]byte base64 string slice. pass buf start from after [ and receive from after ] 332 func (d *DecoderMinifed) Decode32ByteArraySliceAsBase64() (slice [][32]byte, err protocol.Error) { 333 d.Offset(1) // due to have [ at start 334 335 const base64Len = 43 // base64.RawStdEncoding.EncodedLen(len(32)) >> (32*8 + 5) / 6 336 slice = make([][32]byte, 0, 8) 337 338 var goErr error 339 var array [32]byte 340 for d.Buf[1] != ']' { 341 d.Offset(2) // due to have `["` || `",` 342 _, goErr = base64.RawStdEncoding.Decode(array[:], d.Buf[:base64Len]) 343 if goErr != nil { 344 err = ErrEncodedSliceCorrupted 345 return 346 } 347 slice = append(slice, array) 348 d.Buf = d.Buf[base64Len:] 349 } 350 351 d.Offset(2) // due to have `"]` 352 return 353 }