From d135a80e07359a769e007347433f5157bb1f1fc1 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Sat, 13 Jun 2009 22:28:26 +0300 Subject: [PATCH] Implement json_load, json_loadf and json_loadfd --- src/jansson.h | 1 + src/load.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 114 insertions(+), 10 deletions(-) diff --git a/src/jansson.h b/src/jansson.h index bb15b6c..e6ece0c 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -90,6 +90,7 @@ typedef struct { json_t *json_load(const char *path, json_error_t *error); json_t *json_loads(const char *input, json_error_t *error); json_t *json_loadf(FILE *input, json_error_t *error); +json_t *json_loadfd(int fd, json_error_t *error); #define JSON_INDENT(n) (n & 0xFF) #define JSON_SORT_KEYS 0x100 diff --git a/src/load.c b/src/load.c index 2104e8a..912f97d 100644 --- a/src/load.c +++ b/src/load.c @@ -1,11 +1,15 @@ #define _GNU_SOURCE +#include +#include #include #include #include -#include +#include +#include #include #include +#include "strbuffer.h" #define JSON_TOKEN_INVALID -1 @@ -31,23 +35,35 @@ typedef struct { /*** error reporting ***/ static void json_set_error(json_error_t *error, const json_lex *lex, - const char *msg) + const char *msg, ...) { + va_list ap; + char text[JSON_ERROR_TEXT_LENGTH]; + if(!error) return; - if(*lex->start) + va_start(ap, msg); + vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap); + va_end(ap); + + if(lex) { - int n = (int)(lex->input - lex->start); error->line = lex->line; - snprintf(error->text, JSON_ERROR_TEXT_LENGTH, - "%s near '%.*s'", msg, n, lex->start); + if(*lex->start) + { + int n = (int)(lex->input - lex->start); + snprintf(error->text, JSON_ERROR_TEXT_LENGTH, + "%s near '%.*s'", text, n, lex->start); + } + else + { + snprintf(error->text, JSON_ERROR_TEXT_LENGTH, + "%s near end of file", text); + } } else - { - snprintf(error->text, JSON_ERROR_TEXT_LENGTH, - "%s near end of file", msg); - } + snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", msg); } @@ -418,6 +434,25 @@ static json_t *json_parse(json_lex *lex, json_error_t *error) return json; } +json_t *json_load(const char *path, json_error_t *error) +{ + json_t *result; + FILE *fp; + + fp = fopen(path, "r"); + if(!fp) + { + json_set_error(error, NULL, "unable to open %s: %s", + path, strerror(errno)); + return NULL; + } + + result = json_loadf(fp, error); + + fclose(fp); + return result; +} + json_t *json_loads(const char *string, json_error_t *error) { json_lex lex; @@ -445,3 +480,71 @@ out: json_lex_close(&lex); return result; } + +#define BUFFER_SIZE 4096 + +json_t *json_loadf(FILE *input, json_error_t *error) +{ + strbuffer_t strbuff; + char buffer[BUFFER_SIZE]; + size_t length; + json_t *result = NULL; + + strbuffer_init(&strbuff); + + while(1) + { + length = fread(buffer, 1, BUFFER_SIZE, input); + if(length == 0) + { + if(ferror(input)) + { + json_set_error(error, NULL, "read error"); + goto out; + } + break; + } + if(strbuffer_append_bytes(&strbuff, buffer, length)) + goto out; + } + + result = json_loads(strbuffer_value(&strbuff), error); + +out: + strbuffer_close(&strbuff); + return result; +} + +json_t *json_loadfd(int fd, json_error_t *error) +{ + strbuffer_t strbuff; + char buffer[BUFFER_SIZE]; + ssize_t length; + json_t *result = NULL; + + strbuffer_init(&strbuff); + + while(1) + { + length = read(fd, buffer, BUFFER_SIZE); + if(length == -1) + { + json_set_error(error, NULL, "read error: %s", strerror(errno)); + goto out; + } + else if(length == 0) + break; + + if(strbuffer_append_bytes(&strbuff, buffer, length)) + { + json_set_error(error, NULL, "error allocating memory"); + goto out; + } + } + + result = json_loads(strbuffer_value(&strbuff), error); + +out: + strbuffer_close(&strbuff); + return result; +} -- 2.1.4