github.com/RevenueMonster/sqlike@v1.0.6/jsonb/reader.go (about) 1 package jsonb 2 3 import ( 4 "errors" 5 ) 6 7 var whiteSpaceMap = map[byte]bool{ 8 ' ': true, 9 '\n': true, 10 '\t': true, 11 '\r': true, 12 } 13 14 var emptyJSON = []byte(`null`) 15 16 // Reader : 17 type Reader struct { 18 typ jsonType 19 b []byte 20 pos int 21 len int 22 start int 23 end int 24 } 25 26 // NewReader : 27 func NewReader(b []byte) *Reader { 28 length := len(b) 29 copier := make([]byte, length) 30 copy(copier, b) 31 return &Reader{b: copier, len: length} 32 } 33 34 func (r *Reader) reset() *Reader { 35 r.pos = 0 36 return r 37 } 38 39 // Bytes : 40 func (r *Reader) Bytes() []byte { 41 return r.b 42 } 43 44 // nextToken : nextToken will skip all whitespace and stop on a char 45 func (r *Reader) nextToken() byte { 46 var c byte 47 for i := r.pos; i < r.len; i++ { 48 c = r.b[i] 49 if _, ok := whiteSpaceMap[c]; ok { 50 r.b = append(r.b[:i], r.b[i+1:]...) 51 r.len = len(r.b) 52 i-- 53 continue 54 } 55 r.pos = i + 1 56 return c 57 } 58 return 0 59 } 60 61 func (r *Reader) prevToken() byte { 62 if r.pos > 0 { 63 return r.b[r.pos-1] 64 } 65 return 0 66 } 67 68 func (r *Reader) peekType() jsonType { 69 c := r.nextToken() 70 defer r.unreadByte() 71 typ := valueMap[c] 72 return typ 73 } 74 75 // IsNull : 76 func (r *Reader) IsNull() bool { 77 offset := r.pos + 4 78 if offset > r.len { 79 return false 80 } 81 if string(r.b[r.pos:offset]) == null { 82 return true 83 } 84 return false 85 } 86 87 func (r *Reader) skipArray() { 88 level := 1 89 c := r.nextToken() 90 if c != '[' { 91 return 92 } 93 94 for i := r.pos; i < r.len; i++ { 95 switch r.b[i] { 96 case '"': // If inside string, skip it 97 // iter.head = i + 1 98 // iter.skipString() 99 // i = iter.head - 1 // it will be i++ soon 100 case '[': // If open symbol, increase level 101 level++ 102 case ']': // If close symbol, increase level 103 level-- 104 105 // If we have returned to the original level, we're done 106 if level <= 0 { 107 r.pos = i + 1 108 return 109 } 110 } 111 } 112 } 113 114 // ReadBytes : 115 func (r *Reader) ReadBytes() ([]byte, error) { 116 i := r.pos 117 if err := r.skip(); err != nil { 118 return nil, err 119 } 120 return r.b[i:r.pos], nil 121 } 122 123 // ReadValue : 124 func (r *Reader) ReadValue() (interface{}, error) { 125 typ := r.peekType() 126 switch typ { 127 case jsonString: 128 return r.ReadString() 129 case jsonNumber: 130 num, err := r.ReadNumber() 131 if err != nil { 132 return nil, err 133 } 134 return num.Float64() 135 case jsonBoolean: 136 return r.ReadBoolean() 137 case jsonNull: 138 if err := r.ReadNull(); err != nil { 139 return nil, err 140 } 141 return nil, nil 142 case jsonArray: 143 var v []interface{} 144 if err := r.ReadArray(func(it *Reader) error { 145 x, err := it.ReadValue() 146 if err != nil { 147 return err 148 } 149 v = append(v, x) 150 return nil 151 }); err != nil { 152 return v, err 153 } 154 return v, nil 155 case jsonObject: 156 var v map[string]interface{} 157 if err := r.ReadObject(func(it *Reader, k string) error { 158 if v == nil { 159 v = make(map[string]interface{}) 160 } 161 x, err := it.ReadValue() 162 if err != nil { 163 return err 164 } 165 v[k] = x 166 return nil 167 }); err != nil { 168 return nil, err 169 } 170 return v, nil 171 default: 172 return nil, errors.New("invalid json format") 173 } 174 } 175 176 func (r *Reader) unreadByte() *Reader { 177 if r.pos > 0 { 178 r.pos-- 179 } 180 return r 181 } 182 183 // ReadBoolean : 184 func (r *Reader) ReadBoolean() (bool, error) { 185 c := r.nextToken() 186 r.unreadByte() 187 if c == 'n' { 188 if err := r.skipBytes([]byte{'n', 'u', 'l', 'l'}); err != nil { 189 return false, err 190 } 191 return false, nil 192 } else if c == 't' { 193 if err := r.skipBytes([]byte{'t', 'r', 'u', 'e'}); err != nil { 194 return false, err 195 } 196 return true, nil 197 } else if c == 'f' { 198 if err := r.skipBytes([]byte{'f', 'a', 'l', 's', 'e'}); err != nil { 199 return false, err 200 } 201 return false, nil 202 } 203 return false, errors.New("invalid boolean value") 204 } 205 206 // ReadNull : 207 func (r *Reader) ReadNull() error { 208 c := r.nextToken() 209 if c == 'n' { 210 return r.skipBytes([]byte{'u', 'l', 'l'}) 211 } 212 return nil 213 }