Simple JSON  0.1
A free simple json library for C
simple_json_parse.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include "simple_json.h"
5 #include "simple_json_object.h"
6 #include "simple_json_array.h"
7 #include "simple_json_string.h"
8 #include "simple_json_error.h"
9 
13 typedef struct
14 {
15  char *buffer;
16  char *position;
17  char *end;
18 }jsParse;
19 
23 
25 {
26  if (!parse)return 1;
27  if (parse->position >= parse->end)
28  {
29  printf("we have parsed too far");
30  return 1;
31  }
32  return 0;
33 }
34 
35 char *get_next_unescaped_char(char *buffer, char target)
36 {
37  if (!buffer)return NULL;
38  if (buffer[0] == target)return buffer;
39  while ((buffer[0] != '\0')&&(buffer[1] != '\0'))
40  {
41  if ((buffer[0] != '\\')&&(buffer[1] == target))
42  {
43  return ++buffer;
44  }
45  buffer++;
46  }
47  return NULL;
48 }
49 
51 {
52  char *p,*p1,*p2,*p3;
53  size_t str_length;
55  int quoted = 0;
56  if (!parse)return NULL;
57  // validate we are an object
58  if (overseek_check_fail(parse))return NULL;
59 
60  string = sj_string_new();
61  if (!string)
62  {
63  return NULL;
64  }
65  if (*parse->position == '"')
66  {
67  //chomp quote character
68  quoted = 1;
69  parse->position++;
70  }
71  if (quoted)
72  {
73  p = get_next_unescaped_char(parse->position, '"');
74  }
75  else
76  {
77  p = get_next_unescaped_char(parse->position, ',');
78  p1 = get_next_unescaped_char(parse->position, ']');
79  p2 = get_next_unescaped_char(parse->position, '}');
80  p3 = get_next_unescaped_char(parse->position, ':');
81  if (p != NULL)
82  {
83  if (p2 != NULL)p = MIN(p,p2);
84  }
85  else p = p2;
86  if (p1 != NULL)
87  {
88  if (p3 != NULL)p1 = MIN(p1,p3);
89  }
90  else p1 = p3;
91  if (p != NULL)
92  {
93  if (p1 != NULL)p = MIN(p,p1);
94  }
95  else p = p1;
96  }
97  if (p == NULL)
98  {
99  sj_set_error("sj_parse_string: no end delimeter");
100  sj_string_free(string);
101  return NULL;
102  }
103  str_length = p - parse->position;
104  if (str_length <= 0)
105  {
106  sj_set_error("sj_parse_string: string is a zero or negative length");
107  sj_string_free(string);
108  return NULL;
109  }
110  sj_string_set_limit(string,parse->position,str_length);
111  parse->position = p + quoted;
112  return string;
113 }
114 
116 {
117  SJString *string;
118  if (overseek_check_fail(parse))return NULL;
119  if (strncmp(parse->position,"null",4)==0)
120  {
121  switch (parse->position[4])
122  {
123  case ',':// NULL value in an array
124  case ']':// NULL value as the last value for an array
125  case '}':// NULL value as the last value for an object
126  parse->position+=4;
127  return sj_null_new();
128  }
129  }
130  switch (*parse->position)
131  {
132  case '{':
133  return sj_parse_object(parse);
134  case '[':
135  return sj_parse_array(parse);
136  }
137  string = sj_parse_string(parse);
138  if (string == NULL)return NULL;
139  return sj_string_to_value(string);
140 }
141 
143 {
144  SJson *json = NULL;
145  SJson *value = NULL;
146  if (!parse)return NULL;
147  // validate we are an object
148  if (*parse->position != '[')
149  {
150  sj_set_error("sj_parse_object: expected first character to be a {\n");
151  return NULL;
152  }
153 
154  // allocate working space
155  json = sj_array_new();
156  if (!json)return NULL;
157 
158  //chomp first character
159  parse->position++;
160  do
161  {
162  value = sj_parse_value(parse);
163  if (value == NULL)
164  {
165  sj_set_error("--=== array value failed to parse! ===--\n");
166  sj_array_free(json);
167  return NULL;
168  }
169 
170  sj_array_append(json,value);
171 
172  if (*parse->position == ',')
173  {
174  parse->position++;
175  }
176  }
177  while(*parse->position != ']');
178  parse->position++;
179  return json;
180 }
181 
183 {
184  SJson *json = NULL;
185  SJson *value = NULL;
186  SJString *key;
187  if (!parse)return NULL;
188  // validate we are an object
189  if (*parse->position != '{')
190  {
191  sj_set_error("sj_parse_object: expected first character to be a {\n");
192  return NULL;
193  }
194 
195  // allocate working space
196  json = sj_object_new();
197  if (!json)return NULL;
198 
199  //chomp first character
200  parse->position++;
201  do
202  {
203  key = sj_parse_string(parse);
204  if (*parse->position != ':')
205  {
206  sj_set_error("sj_parse_object: no colon (:) delimeter for object\n");
207  sj_object_free(json);
208  sj_string_free(key);
209  return NULL;
210  }
211  parse->position++;
212  value = sj_parse_value(parse);
213 
214  if (value == NULL)
215  {
216  sj_set_error("--=== array value failed to parse! ===--");
217  sj_string_free(key);
218  sj_object_free(json);
219  return NULL;
220  }
221  sj_object_insert(json,key->text,value);
222  sj_string_free(key);
223 
224  if (*parse->position == ',')
225  {
226  parse->position++;
227  }
228  }
229  while(*parse->position != '}');
230  parse->position++;
231  return json;
232 }
233 
234 SJson *sj_parse_buffer(char *string,unsigned long length)
235 {
236  SJson *json = NULL;
237  jsParse parse;
238  if (!string)
239  {
240  sj_set_error("sj_parse_buffer: no string provided");
241  return NULL;
242  }
243  parse.buffer = string;
244  parse.position = strchr(string, '{');
245  parse.end = &string[length -1];
246  json = sj_parse_object(&parse);
247  return json;
248 }
char * get_next_unescaped_char(char *buffer, char target)
this is the abstract container structure for all json data This structure may be an object...
SJson * sj_parse_object(jsParse *parse)
void sj_object_insert(SJson *object, char *key, SJson *value)
insert data into a json object
void sj_string_set_limit(SJString *string, char *s, unsigned long l)
set the value of string to s but only length of s
void sj_array_append(SJson *array, SJson *value)
append to a JSON array a new value
int overseek_check_fail(jsParse *parse)
SJson * sj_object_new()
allocate a new empty json object
SJson * sj_parse_value(jsParse *parse)
SJString * sj_string_new()
make a new empty string
SJson * sj_parse_array(jsParse *parse)
SJson * sj_parse_buffer(char *string, unsigned long length)
given a string, create a JSON object from it
SJson * sj_null_new()
make a new json value that is NULL
Definition: simple_json.c:173
SJString * sj_parse_string(jsParse *parse)
SJson * sj_string_to_value(SJString *string)
make a jason value object out of a string
#define MIN(a, b)
void sj_set_error(char *er)
used internally to se the error message
void sj_array_free(SJson *array)
char * position
a basic structure that keeps track of a string and its length Automatically grows to accomodate longe...
void sj_object_free(SJson *object)
free a previously allocated json object
SJson * sj_array_new()
allocate a new empty json array
SJString * string
char * buffer
void sj_string_free(SJString *string)
free an SJString
structure keeps track of the buffer being parsed and the position last used