| 1189 | |
| 1190 | |
| 1191 | int json_path_setup(json_path_t *p, |
| 1192 | CHARSET_INFO *i_cs, const uchar *str, const uchar *end) |
| 1193 | { |
| 1194 | int c_len, t_next, state= PS_GO, is_negative_index= 0, is_last= 0, |
| 1195 | prev_value=0, is_to= 0, *cur_val; |
| 1196 | json_path_step_t *curr_step= NULL, *last_step= NULL; |
| 1197 | |
| 1198 | enum json_path_step_types double_wildcard= JSON_PATH_KEY_NULL; |
| 1199 | json_string_setup(&p->s, i_cs, str, end); |
| 1200 | |
| 1201 | curr_step= (json_path_step_t*)(p->steps.buffer); |
| 1202 | |
| 1203 | last_step= curr_step; |
| 1204 | curr_step->type= JSON_PATH_ARRAY_WILD; |
| 1205 | p->last_step_idx= 0; |
| 1206 | last_step->key= (const uchar*)""; |
| 1207 | p->mode_strict= FALSE; |
| 1208 | p->types_used= JSON_PATH_KEY_NULL; |
| 1209 | |
| 1210 | do |
| 1211 | { |
| 1212 | json_path_step_t *last_step= |
| 1213 | (json_path_step_t*)(p->steps.buffer) + p->last_step_idx; |
| 1214 | if ((c_len= json_next_char(&p->s)) <= 0) |
| 1215 | t_next= json_eos(&p->s) ? P_EOS : P_BAD; |
| 1216 | else |
| 1217 | t_next= (p->s.c_next >= 128) ? P_ETC : json_path_chr_map[p->s.c_next]; |
| 1218 | |
| 1219 | if ((state= json_path_transitions[state][t_next]) < 0) |
| 1220 | return p->s.error= state; |
| 1221 | |
| 1222 | p->s.c_str+= c_len; |
| 1223 | |
| 1224 | switch (state) |
| 1225 | { |
| 1226 | case PS_LAX: |
| 1227 | if ((p->s.error= skip_string_verbatim(&p->s, "ax"))) |
| 1228 | return 1; |
| 1229 | p->mode_strict= FALSE; |
| 1230 | continue; |
| 1231 | case PS_SCT: |
| 1232 | if ((p->s.error= skip_string_verbatim(&p->s, "rict"))) |
| 1233 | return 1; |
| 1234 | p->mode_strict= TRUE; |
| 1235 | state= PS_LAX; |
| 1236 | continue; |
| 1237 | case PS_KWD: |
| 1238 | case PS_AWD: |
| 1239 | last_step->type|= JSON_PATH_WILD; |
| 1240 | p->types_used|= JSON_PATH_WILD; |
| 1241 | continue; |
| 1242 | case PS_INT: |
| 1243 | cur_val= is_to ? &(last_step->n_item_end) : |
| 1244 | &(last_step->n_item); |
| 1245 | if (is_last) |
| 1246 | { |
| 1247 | prev_value*= 10; |
| 1248 | prev_value-= p->s.c_next - '0'; |