Implement json_load, json_loadf and json_loadfd
This commit is contained in:
parent
8c697312e4
commit
d135a80e07
@ -90,6 +90,7 @@ typedef struct {
|
|||||||
json_t *json_load(const char *path, json_error_t *error);
|
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_loads(const char *input, json_error_t *error);
|
||||||
json_t *json_loadf(FILE *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_INDENT(n) (n & 0xFF)
|
||||||
#define JSON_SORT_KEYS 0x100
|
#define JSON_SORT_KEYS 0x100
|
||||||
|
113
src/load.c
113
src/load.c
@ -1,11 +1,15 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
#include "strbuffer.h"
|
||||||
|
|
||||||
|
|
||||||
#define JSON_TOKEN_INVALID -1
|
#define JSON_TOKEN_INVALID -1
|
||||||
@ -31,23 +35,35 @@ typedef struct {
|
|||||||
/*** error reporting ***/
|
/*** error reporting ***/
|
||||||
|
|
||||||
static void json_set_error(json_error_t *error, const json_lex *lex,
|
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)
|
if(!error)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if(lex)
|
||||||
|
{
|
||||||
|
error->line = lex->line;
|
||||||
if(*lex->start)
|
if(*lex->start)
|
||||||
{
|
{
|
||||||
int n = (int)(lex->input - lex->start);
|
int n = (int)(lex->input - lex->start);
|
||||||
error->line = lex->line;
|
|
||||||
snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
|
snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
|
||||||
"%s near '%.*s'", msg, n, lex->start);
|
"%s near '%.*s'", text, n, lex->start);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
|
snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
|
||||||
"%s near end of file", msg);
|
"%s near end of file", text);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
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;
|
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_t *json_loads(const char *string, json_error_t *error)
|
||||||
{
|
{
|
||||||
json_lex lex;
|
json_lex lex;
|
||||||
@ -445,3 +480,71 @@ out:
|
|||||||
json_lex_close(&lex);
|
json_lex_close(&lex);
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user