Home | History | Annotate | Line # | Download | only in example
      1  1.2  christos /*	$NetBSD: simple.c,v 1.2 2020/05/25 20:47:24 christos Exp $	*/
      2  1.2  christos 
      3  1.1  christos #include <stdio.h>
      4  1.1  christos #include <string.h>
      5  1.1  christos #include "../jsmn.h"
      6  1.1  christos 
      7  1.1  christos /*
      8  1.1  christos  * A small example of jsmn parsing when JSON structure is known and number of
      9  1.1  christos  * tokens is predictable.
     10  1.1  christos  */
     11  1.1  christos 
     12  1.1  christos const char *JSON_STRING =
     13  1.1  christos 	"{\"user\": \"johndoe\", \"admin\": false, \"uid\": 1000,\n  "
     14  1.1  christos 	"\"groups\": [\"users\", \"wheel\", \"audio\", \"video\"]}";
     15  1.1  christos 
     16  1.1  christos static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
     17  1.1  christos 	if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
     18  1.1  christos 			strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
     19  1.1  christos 		return 0;
     20  1.1  christos 	}
     21  1.1  christos 	return -1;
     22  1.1  christos }
     23  1.1  christos 
     24  1.1  christos int main() {
     25  1.1  christos 	int i;
     26  1.1  christos 	int r;
     27  1.1  christos 	jsmn_parser p;
     28  1.1  christos 	jsmntok_t t[128]; /* We expect no more than 128 tokens */
     29  1.1  christos 
     30  1.1  christos 	jsmn_init(&p);
     31  1.1  christos 	r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, sizeof(t)/sizeof(t[0]));
     32  1.1  christos 	if (r < 0) {
     33  1.1  christos 		printf("Failed to parse JSON: %d\n", r);
     34  1.1  christos 		return 1;
     35  1.1  christos 	}
     36  1.1  christos 
     37  1.1  christos 	/* Assume the top-level element is an object */
     38  1.1  christos 	if (r < 1 || t[0].type != JSMN_OBJECT) {
     39  1.1  christos 		printf("Object expected\n");
     40  1.1  christos 		return 1;
     41  1.1  christos 	}
     42  1.1  christos 
     43  1.1  christos 	/* Loop over all keys of the root object */
     44  1.1  christos 	for (i = 1; i < r; i++) {
     45  1.1  christos 		if (jsoneq(JSON_STRING, &t[i], "user") == 0) {
     46  1.1  christos 			/* We may use strndup() to fetch string value */
     47  1.1  christos 			printf("- User: %.*s\n", t[i+1].end-t[i+1].start,
     48  1.1  christos 					JSON_STRING + t[i+1].start);
     49  1.1  christos 			i++;
     50  1.1  christos 		} else if (jsoneq(JSON_STRING, &t[i], "admin") == 0) {
     51  1.1  christos 			/* We may additionally check if the value is either "true" or "false" */
     52  1.1  christos 			printf("- Admin: %.*s\n", t[i+1].end-t[i+1].start,
     53  1.1  christos 					JSON_STRING + t[i+1].start);
     54  1.1  christos 			i++;
     55  1.1  christos 		} else if (jsoneq(JSON_STRING, &t[i], "uid") == 0) {
     56  1.1  christos 			/* We may want to do strtol() here to get numeric value */
     57  1.1  christos 			printf("- UID: %.*s\n", t[i+1].end-t[i+1].start,
     58  1.1  christos 					JSON_STRING + t[i+1].start);
     59  1.1  christos 			i++;
     60  1.1  christos 		} else if (jsoneq(JSON_STRING, &t[i], "groups") == 0) {
     61  1.1  christos 			int j;
     62  1.1  christos 			printf("- Groups:\n");
     63  1.1  christos 			if (t[i+1].type != JSMN_ARRAY) {
     64  1.1  christos 				continue; /* We expect groups to be an array of strings */
     65  1.1  christos 			}
     66  1.1  christos 			for (j = 0; j < t[i+1].size; j++) {
     67  1.1  christos 				jsmntok_t *g = &t[i+j+2];
     68  1.1  christos 				printf("  * %.*s\n", g->end - g->start, JSON_STRING + g->start);
     69  1.1  christos 			}
     70  1.1  christos 			i += t[i+1].size + 1;
     71  1.1  christos 		} else {
     72  1.1  christos 			printf("Unexpected key: %.*s\n", t[i].end-t[i].start,
     73  1.1  christos 					JSON_STRING + t[i].start);
     74  1.1  christos 		}
     75  1.1  christos 	}
     76  1.1  christos 	return 0;
     77  1.1  christos }
     78