Skip to content

Commit

Permalink
reduced down the v1 pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
quartzjer committed Oct 5, 2014
1 parent bb95e25 commit cb40bd3
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 30 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -15,7 +15,7 @@ Parsing this:
{"foo":"bar","barbar":[1,2,3],"obj":{"a":"b"}}
````

Using `at = js0n(json, len, "barbar", &len)` would return an at of `22` and set len to `7`.
Using `at = js0n("barbr", json, len, &vlen)` would return an at pointing to `[1,2,3]` and set vlen to `7`.


## History
Expand Down
24 changes: 13 additions & 11 deletions src/js0n.c
@@ -1,4 +1,4 @@
// by jeremie miller - 2010
// by jeremie miller - 2014
// public domain, contributions/improvements welcome via github at https://github.com/quartzjer/js0n

// gcc started warning for the init syntax used here, is not helpful so don't generate the spam, supressing the warning is really inconsistently supported across versions
Expand All @@ -10,15 +10,16 @@
#pragma GCC diagnostic ignored "-Winitializer-overrides"
#pragma GCC diagnostic ignored "-Woverride-init"

// opportunity to further optimize would be having different jump tables for higher depths
#define PUSH(i) if(depth == 1) prev = *out++ = ((cur+i) - js)
#define CAP(i) if(depth == 1) prev = *out++ = ((cur+i) - (js + prev) + 1)
// opportunity to further optimize would be having different short-cut jump tables for higher depths
#define PUSH(i) if(depth == 1) prev = ((cur+i) - start)
#define CAP(i) if(depth == 1) prev = ((cur+i) - (start + prev) + 1)

// this makes a single pass across the json bytes, using each byte as an index into a jump table to build an index and transition state
int js0n(const unsigned char *js, unsigned int len, unsigned short *out, unsigned int olen)
char *js0n(char *key, char *json, unsigned int len, unsigned int *vlen)
{
unsigned short prev = 0, *oend;
const unsigned char *cur, *end;
char *val = 0;
unsigned short prev = 0;
const unsigned char *cur, *end, *start;
int depth=0;
int utf8_remain=0;
static void *gostruct[] =
Expand Down Expand Up @@ -65,17 +66,18 @@ int js0n(const unsigned char *js, unsigned int len, unsigned short *out, unsigne
};
void **go = gostruct;

for(cur=js,end=js+len,oend=out+olen; cur<end && out<oend; cur++)
if(!key || !json || !len) return 0;

for(start=cur=(unsigned char*)json,end=cur+len; cur<end; cur++)
{
goto *go[*cur];
l_loop:;
}

if(out < oend) *out = 0;
return depth; // 0 if successful full parse, >0 for incomplete data
return val;

l_bad:
return 1;
return 0;

l_up:
PUSH(0);
Expand Down
7 changes: 4 additions & 3 deletions src/js0n.h
@@ -1,3 +1,4 @@
// pass it a raw json string and length, and it will tag all the key/value offsets in the out argument (size it same as js to be safe)
// returns 0 if successful, >0 if not
int js0n(const unsigned char *js, unsigned int len, unsigned short *out, unsigned int olen);
// pass it a raw json string, length, and key and it will return a pointer to the start of the value
// if a vlen is given, it will set it to the length, otherwise it will null terminate it
// returns 0 if not found or any error
char *js0n(char *key, char *json, unsigned int len, unsigned int *vlen);
20 changes: 5 additions & 15 deletions test/example.c
Expand Up @@ -3,25 +3,15 @@
#include <string.h>
#include "../src/js0n.h"

void
ex1()
void ex1(void)
{
char *s = "{\"foo\":\"bar\",\"barbar\":[1,2,3],\"obj\":{\"a\":\"b\"}}";
char *json = "{\"foo\":\"bar\",\"barbar\":[1,2,3],\"obj\":{\"a\":\"b\"}}";

// 3 keys, 3 values, each with a start and offset --> 12
// Plus one for a terminating zero = 13.
unsigned short kvpairs[13];
printf("parsing '%s'\n", json);

printf("Parsing '%s'\n", s);
char *val = js0n("barbar", json, strlen(json), 0);

int rc = js0n((unsigned char*) s, strlen(s), kvpairs, 13);

printf("returned %d\n",rc);

for (int i = 0; kvpairs[i]; i += 2)

printf("%d: at %d len %d is %.*s\n", i,
kvpairs[i], kvpairs[i + 1], kvpairs[i + 1], s + kvpairs[i]);
printf("returned %s\n",val);

}

Expand Down

0 comments on commit cb40bd3

Please sign in to comment.