2  * Copyright (c) 2012 Rogerz Zhang <rogerz.zhang@gmail.com> 
   4  * Jansson is free software; you can redistribute it and/or modify 
   5  * it under the terms of the MIT license. See LICENSE for details. 
   7  * source here https://github.com/rogerz/jansson/blob/json_path/src/path.c 
  14 #include "jansson_private.h" 
  16 json_t 
*json_path_get(const json_t 
*json
, const char *path
) 
  18     static const char root_chr 
= '$', array_open 
= '['; 
  19     static const char *path_delims 
= ".[", *array_close 
= "]"; 
  21     char *token
, *buf
, *peek
, *endptr
, delim 
= '\0'; 
  24     if (!json 
|| !path 
|| path
[0] != root_chr
) 
  27         buf 
= jsonp_strdup(path
); 
  34     while (peek 
&& *peek 
&& cursor
) 
  36         char *last_peek 
= peek
; 
  37         peek 
= strpbrk(peek
, expect
); 
  39             if (!token 
&& peek 
!= last_peek
) 
  43         } else if (expect 
!= path_delims 
|| !token
) { 
  47         if (expect 
== path_delims
) { 
  49                 cursor 
= json_object_get(cursor
, token
); 
  51             expect 
= (delim 
== array_open 
? array_close 
: path_delims
); 
  53         } else if (expect 
== array_close
) { 
  54             size_t index 
= strtol(token
, &endptr
, 0); 
  57             cursor 
= json_array_get(cursor
, index
); 
  66     return (json_t 
*)cursor
; 
  72 int json_path_set_new(json_t 
*json
, const char *path
, json_t 
*value
, size_t flags
, json_error_t 
*error
) 
  74     static const char root_chr 
= '$', array_open 
= '[', object_delim 
= '.'; 
  75     static const char * const path_delims 
= ".[", *array_close 
= "]"; 
  77     json_t 
*cursor
, *parent 
= NULL
; 
  78     char *token
, *buf 
= NULL
, *peek
, delim 
= '\0'; 
  82     jsonp_error_init(error
, "<path>"); 
  84     if (!json 
|| !path 
|| flags 
|| !value
) { 
  85         jsonp_error_set(error
, -1, -1, 0, json_error_invalid_argument
, "invalid argument"); 
  88         buf 
= jsonp_strdup(path
); 
  91     if (buf
[0] != root_chr
) { 
  92         jsonp_error_set(error
, -1, -1, 0, json_error_invalid_format
, "path should start with $"); 
 101     while (peek 
&& *peek 
&& cursor
) 
 103         char *last_peek 
= peek
; 
 104         peek 
= strpbrk(last_peek
, expect
); 
 107             if (!token 
&& peek 
!= last_peek
) { 
 108                 jsonp_error_set(error
, -1, -1, last_peek 
- buf
, json_error_invalid_format
, "unexpected trailing chars"); 
 113         } else { // end of path 
 114             if (expect 
== path_delims
) { 
 117                 jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_invalid_format
, "missing ']'?"); 
 122         if (expect 
== path_delims
) { 
 124                 if (token
[0] == '\0') { 
 125                     jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_invalid_format
, "empty token"); 
 130                 cursor 
= json_object_get(parent
, token
); 
 133                     if (!json_is_object(parent
)) { 
 134                         jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_item_not_found
, "object expected"); 
 137                     if (delim 
== object_delim
) { 
 138                         cursor 
= json_object(); 
 139                         json_object_set_new(parent
, token
, cursor
); 
 141                         jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_item_not_found
, "new array is not allowed"); 
 146             expect 
= (delim 
== array_open 
? array_close 
: path_delims
); 
 148         } else if (expect 
== array_close
) { 
 153             if (!json_is_array(parent
)) { 
 154                 jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_item_not_found
, "array expected"); 
 157             index 
= strtol(token
, &endptr
, 0); 
 159                 jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_item_not_found
, "invalid array index"); 
 162             cursor 
= json_array_get(parent
, index
); 
 164                 jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_item_not_found
, "array index out of bound"); 
 169             expect 
= path_delims
; 
 172             jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_unknown
, "unexpected error in path move"); 
 178         if (json_is_object(cursor
)) { 
 179             json_object_set(cursor
, token
, value
); 
 181             jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_item_not_found
, "object expected"); 
 184         cursor 
= json_object_get(cursor
, token
); 
 185     } else if (index_saved 
!= -1 && json_is_array(parent
)) { 
 186         json_array_set(parent
, index_saved
, value
); 
 187         cursor 
= json_array_get(parent
, index_saved
); 
 189         jsonp_error_set(error
, -1, -1, peek 
- buf
, json_error_item_not_found
, "invalid path");