Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

passing the first tests, seems to be working splendidly

  • Loading branch information...
commit a0586689027f355ff22ef98cf6911f2bedf03a25 1 parent 8084600
@quartzjer authored
Showing with 42 additions and 21 deletions.
  1. +1 −0  .gitignore
  2. +1 −1  README
  3. +29 −17 js0n.c
  4. +1 −1  js0n.h
  5. +10 −2 js0n_test.c
View
1  .gitignore
@@ -0,0 +1 @@
+js0n_test
View
2  README
@@ -1,6 +1,6 @@
js0n - the "cheapest" c json parser possible?
-A one-pass super low overhead parsing walk of the raw bytes and no mem copying of any sort, fills in a simple array of offsets and lengths of the first depth array values or object key/values.
+A one-pass super low overhead parsing walk of the raw bytes and no mem copying of any sort, fills in a simple array of offsets and lengths of the first depth array values or object key/values. It should parse any valid json, but trades full validation for efficiency (some invalid json will still parse). Excellent for low level high speed scanning/routing of small chunks of json.
Parsing this:
View
46 js0n.c
@@ -1,19 +1,22 @@
+// by jeremie miller - 2010
+// public domain, contributions/improvements welcome via github
-int js0n(unsigned char *js, unsigned int len, unsigned short **out)
+// opportunity to further optimize would be having different jump tables for higher depths
+#define PUSH(i) if(depth == 1) *out++ = ((cur+i) - js)
+#define CAP(i) if(depth == 1) *out++ = (cur+i) - (js + *(out-1)) + 1
+
+int js0n(unsigned char *js, unsigned int len, unsigned short *out)
{
- unsigned char buff[1024], *cur, *end;
- int mode=0; // 0=structures 1=strings
+ unsigned char *cur, *end;
int depth=0;
- int kind=0; // 0=obj 1=array
- char quote;
static void *gostruct[] =
{
[0 ... 255] = &&l_bad,
['\t'] = &&l_ws, [' '] = &&l_ws, ['\r'] = &&l_ws, ['\n'] = &&l_ws,
['"'] = &&l_quot,
[':'] = &&l_is,[','] = &&l_more,
- ['['] = &&l_ko, [']'] = &&l_kc,
- ['{'] = &&l_ko, ['}'] = &&l_kc,
+ ['['] = &&l_up, [']'] = &&l_down, // tracking [] and {} individually would allow fuller validation but is really messy
+ ['{'] = &&l_up, ['}'] = &&l_down,
['-'] = &&l_bare, [48 ... 57] = &&l_bare, // 0-9
['t'] = &&l_bare, ['f'] = &&l_bare, ['n'] = &&l_bare // true, false, null
};
@@ -46,31 +49,38 @@ int js0n(unsigned char *js, unsigned int len, unsigned short **out)
l_loop:;
}
+ return depth; // 0 if successful full parse, >0 for incomplete data
+
l_bad:
- printf("bad char %d\n",*cur);
return 1;
l_char:
- printf("%c",mode?'.':'*');
goto l_loop;
- l_ko:
- printf("%d%c",++depth,*cur);
+ l_up:
+ PUSH(0);
+ ++depth;
goto l_loop;
- l_kc:
- printf("%d%c",--depth,*cur);
+
+ l_down:
+ --depth;
+ CAP(0);
goto l_loop;
l_ws:
l_is:
l_more:
- printf("%c",*cur);
goto l_loop;
l_quot:
- printf("%c",*cur);
- go = mode?gostruct:gostring;
- mode^=1;
+ if(go==gostruct)
+ {
+ PUSH(1);
+ go=gostring;
+ }else{
+ CAP(-1);
+ go=gostruct;
+ }
goto l_loop;
l_esc:
@@ -82,10 +92,12 @@ int js0n(unsigned char *js, unsigned int len, unsigned short **out)
goto l_loop;
l_bare:
+ PUSH(0);
go = gobare;
goto l_loop;
l_unbare:
+ CAP(-1);
go = gostruct;
goto *go[*cur];
View
2  js0n.h
@@ -1,6 +1,6 @@
// pass it a raw json string and length, it will return an array of unsigned shorts, see js0n.c for more
-int js0n(unsigned char *js, unsigned int len, unsigned short **out);
+int js0n(unsigned char *js, unsigned int len, unsigned short *out);
// TODO: decode a string value, copy into new while unescaping things and unicode stuffs
// int js0n(unsigned char *in, unsigned int len, unsigned char *out);
View
12 js0n_test.c
@@ -7,8 +7,8 @@
int main(int argc, char **argv)
{
unsigned char buff[1024], *json;
- int len, lastlen=0;
- unsigned short **res;
+ int len, lastlen=0, ret, i;
+ unsigned short *res;
FILE *f;
if((f = fopen(argv[1],"r")) == NULL)
@@ -24,6 +24,14 @@ int main(int argc, char **argv)
}
fclose(f);
printf("got[%.*s]\n",lastlen,json);
+ res = malloc(lastlen); // way more than enough
+ bzero(res,lastlen);
+ ret = js0n(json,lastlen,res);
+ printf("returned %d\n",ret);
+ for(i=0;res[i];i+=2)
+ {
+ printf("%d: at %d len %d is %.*s\n",i,res[i],res[i+1],res[i+1],json+res[i]);
+ }
return 0;
}
Please sign in to comment.
Something went wrong with that request. Please try again.