github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_decoder_native.go (about) 1 package jzon 2 3 import ( 4 "io" 5 "unsafe" 6 ) 7 8 // bool decoder 9 type boolDecoder struct{} 10 11 func (*boolDecoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) error { 12 c, err := it.nextToken() 13 if err != nil { 14 return err 15 } 16 switch c { 17 case 'n': 18 it.head++ 19 return it.expectBytes("ull") 20 case 't': 21 it.head++ 22 if err := it.expectBytes("rue"); err != nil { 23 return err 24 } 25 *(*bool)(ptr) = true 26 return nil 27 case 'f': 28 it.head++ 29 if err := it.expectBytes("alse"); err != nil { 30 return err 31 } 32 *(*bool)(ptr) = false 33 return nil 34 case '"': 35 quoted := (opts != nil) && opts.Quoted 36 if !quoted { 37 return UnexpectedByteError{got: c} 38 } 39 it.head++ 40 c, err := it.nextToken() 41 if err != nil { 42 return err 43 } 44 it.head++ 45 switch c { 46 case 't': 47 if err := it.expectBytes(`rue"`); err != nil { 48 return err 49 } 50 *(*bool)(ptr) = true 51 return nil 52 case 'f': 53 if err := it.expectBytes(`alse"`); err != nil { 54 return err 55 } 56 *(*bool)(ptr) = false 57 return nil 58 case 'n': 59 return it.expectBytes(`ull"`) 60 default: 61 return UnexpectedByteError{got: c} 62 } 63 default: 64 return UnexpectedByteError{got: c} 65 } 66 } 67 68 // string decoder 69 type stringDecoder struct{} 70 71 func (*stringDecoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) error { 72 c, err := it.nextToken() 73 if err != nil { 74 return err 75 } 76 switch c { 77 case '"': 78 it.head++ 79 s, err := it.readString() 80 if err != nil { 81 return err 82 } 83 quoted := (opts != nil) && opts.Quoted 84 if !quoted { 85 *(*string)(ptr) = s 86 return nil 87 } 88 l := len(s) 89 if l < 2 { 90 return BadQuotedStringError(s) 91 } 92 switch s[0] { 93 case 'n': 94 if s != "null" { 95 return BadQuotedStringError(s) 96 } 97 return nil 98 case '"': 99 if s[l-1] != '"' { 100 return BadQuotedStringError(s) 101 } 102 // borrow another iterator 103 subIt := it.cfg.NewIterator() 104 defer subIt.Release() 105 subIt.ResetBytes(localStringToBytes(s)) 106 subStr, err := subIt.ReadString() 107 if err != nil { 108 return BadQuotedStringError(s) 109 } 110 // check eof 111 _, err = subIt.nextToken() 112 if err != io.EOF { 113 return BadQuotedStringError(s) 114 } 115 *(*string)(ptr) = subStr 116 return nil 117 default: 118 return BadQuotedStringError(s) 119 } 120 case 'n': 121 it.head++ 122 return it.expectBytes("ull") 123 default: 124 return UnexpectedByteError{got: c, exp: '"', exp2: 'n'} 125 } 126 }