json-parser.c revision e0ba54c7f985fc403b41c6e36d6a7f44908b23f0
/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "str.h"
#include "hex-dec.h"
#include "unichar.h"
#include "json-parser.h"
enum json_state {
JSON_STATE_ROOT = 0,
};
struct json_parser {
const char *error;
enum json_state state;
};
struct json_parser *
{
struct json_parser *parser;
return parser;
}
{
}
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
default:
return TRUE;
}
}
return FALSE;
}
{
const unsigned char *p;
return -1;
if (*p == '"') {
return 0;
}
if (*p != '\\')
else {
switch (*++p) {
case '"':
case '\\':
case '/':
break;
case 'b':
break;
case 'f':
break;
case 'n':
break;
case 'r':
break;
case 't':
break;
case 'u':
return -1;
p += 3;
break;
default:
return -1;
}
}
}
return -1;
}
static int
{
const unsigned char *p = *_p;
return -1;
*_p = p;
return 0;
}
{
const unsigned char *p = *_p;
if (*p == '-') {
return -1;
}
if (*p == '0')
else {
if (json_parse_digits(parser, &p) < 0)
return -1;
}
*_p = p;
return 0;
}
{
if (json_parse_int(parser, &p) < 0)
return -1;
/* frac */
if (json_parse_digits(parser, &p) < 0)
return -1;
}
/* exp */
return -1;
if (*p == '+' || *p == '-')
if (json_parse_digits(parser, &p) < 0)
return -1;
}
return 0;
}
{
return -1;
return -1;
return 0;
}
const char **value_r)
{
return FALSE;
case JSON_STATE_ROOT:
}
/* fall through */
case JSON_STATE_OBJECT_VALUE:
*type_r = JSON_TYPE_TRUE;
*value_r = "true";
*value_r = "false";
*type_r = JSON_TYPE_NULL;
return FALSE;
return FALSE;
} else {
return FALSE;
}
break;
case JSON_STATE_OBJECT_KEY:
return FALSE;
}
break;
case JSON_STATE_OBJECT_COLON:
return FALSE;
}
else {
return FALSE;
}
case JSON_STATE_DONE:
return FALSE;
}
return TRUE;
}