commit e4bca9fdb2cde1e67f1bfbaf7e5eb2515b0d53a2
parent 920214b0e043697cbb95309ee82ae66465a96b21
Author: William Casarin <jb55@jb55.com>
Date: Sat, 11 Aug 2018 11:27:35 -0700
json: token parsing working
Diffstat:
4 files changed, 73 insertions(+), 33 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
BIN = lnvis
PREFIX ?= /usr/local
-CFLAGS = -Ideps -ggdb -Os -Wall -Wextra -std=c99 \
+CFLAGS = -Ideps -ggdb -O2 -Wall -Wextra -std=c99 \
-Wno-implicit-fallthrough
LDFLAGS = -lglfw -lGL
diff --git a/deps/jsmn.c b/deps/jsmn.c
@@ -149,11 +149,11 @@ static int jsmn_parse_string(jsmn_parser *parser, const char *js,
* Parse JSON string and fill tokens.
*/
int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
- jsmntok_t *tokens, unsigned int num_tokens, int *count) {
+ jsmntok_t *tokens, unsigned int num_tokens) {
int r;
int i;
jsmntok_t *token;
- *count = parser->toknext;
+ int count = parser->toknext;
for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
char c;
@@ -162,7 +162,7 @@ int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
c = js[parser->pos];
switch (c) {
case '{': case '[':
- (*count)++;
+ count++;
if (tokens == NULL) {
break;
}
@@ -231,7 +231,7 @@ int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
case '\"':
r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
if (r < 0) return r;
- (*count)++;
+ count++;
if (parser->toksuper != -1 && tokens != NULL)
tokens[parser->toksuper].size++;
break;
@@ -277,7 +277,7 @@ int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
#endif
r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
if (r < 0) return r;
- (*count)++;
+ count++;
if (parser->toksuper != -1 && tokens != NULL)
tokens[parser->toksuper].size++;
break;
@@ -299,7 +299,7 @@ int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
}
}
- return *count;
+ return count;
}
/**
@@ -311,3 +311,4 @@ void jsmn_init(jsmn_parser *parser) {
parser->toknext = 0;
parser->toksuper = -1;
}
+
diff --git a/deps/jsmn.h b/deps/jsmn.h
@@ -67,7 +67,7 @@ void jsmn_init(jsmn_parser *parser);
* a single JSON object.
*/
int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
- jsmntok_t *tokens, unsigned int num_tokens, int *count);
+ jsmntok_t *tokens, unsigned int num_tokens);
#ifdef __cplusplus
}
diff --git a/json.c b/json.c
@@ -1,42 +1,81 @@
#include "jsmn.h"
+#include "ln.h"
#include <stdio.h>
#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
-#define NUM_TOKENS 2048
-#define READ_BUFSIZE 4096
+#define ERROR_READING_CHANNELS -2
+#define ERROR_ALLOCATING_CHANNELS -3
-int parse_clightning_channels(FILE *fd)
+int parse_clightning_channels(FILE *fd, int *nchannels, struct channel **channels)
{
- static char buffer[READ_BUFSIZE] = {0};
- static jsmntok_t tokens[NUM_TOKENS];
- jsmntok_t *token;
- int ntok = 0;
- size_t bytes = 0;
- int count = 1;
-
+ int off, parserr, i;
+ void *res;
+ char *buffer;
+ jsmntok_t *toks;
jsmn_parser parser;
jsmn_init(&parser);
- while ((bytes = fread(buffer, 1, READ_BUFSIZE, fd))) {
- int parse_err = jsmn_parse(&parser, buffer, bytes, tokens, NUM_TOKENS, &ntok);
+ int bufsize = 4096 * 4096;
+ int toksize = 512 * 4096;
- printf("parse_err %d ntok %d\n", parse_err, ntok);
+ buffer = malloc(bufsize);
+ toks = calloc(toksize, sizeof(jsmntok_t));
+ off = 0;
+ parserr = 0;
+
+ while (parserr <= 0) {
+ /* Read more if parser says, or we have 0 tokens. */
+ if (parserr == 0 || parserr == JSMN_ERROR_PART) {
+ i = fread(buffer + off, 1, bufsize - 1 - off, fd);
+ if (i <= 0)
+ return ERROR_READING_CHANNELS;
+ off += i;
+ /* NUL terminate */
+ buffer[off] = '\0';
+ }
- if (parse_err != JSMN_ERROR_PART && parse_err < 0)
- return parse_err;
+ /* (Continue) parsing */
+ parserr = jsmn_parse(&parser, buffer, off, toks, toksize);
- for (int i = 0; i < ntok; ++i, count++) {
- token = &tokens[i];
- if (token->type == JSMN_ARRAY || token->type == JSMN_OBJECT)
- continue;
- printf("%d %d: %.*s\n",
- token->type,
- count,
- token->end - token->start,
- &buffer[token->start]);
+ switch (parserr) {
+ case JSMN_ERROR_INVAL:
+ return ERROR_READING_CHANNELS;
+ case JSMN_ERROR_NOMEM:
+ /* Need more tokens, double it */
+ toksize *= 2;
+ res = realloc(toks, toksize * sizeof(jsmntok_t));
+ if (res == NULL) {
+ free(toks);
+ return ERROR_ALLOCATING_CHANNELS;
+ }
+ toks = res;
+ break;
+ case JSMN_ERROR_PART:
+ /* Need more data: make room if necessary */
+ if (off == bufsize - 1) {
+ bufsize *= 2;
+ res = realloc(buffer, bufsize);
+ if (res == NULL) {
+ free(buffer);
+ return ERROR_ALLOCATING_CHANNELS;
+ }
+ buffer = res;
+ }
+ break;
}
}
- return ntok;
+ printf("got %d tokens\n", parserr);
+
+ // parse tokens
+ for (i = 0; i < parserr; ++i) {
+ }
+
+ free(buffer);
+ free(toks);
+
+ return 0;
}