diff options
Diffstat (limited to 'debian/vendor-h2o/deps/mruby-iijson/src')
-rw-r--r-- | debian/vendor-h2o/deps/mruby-iijson/src/json.c | 641 |
1 files changed, 0 insertions, 641 deletions
diff --git a/debian/vendor-h2o/deps/mruby-iijson/src/json.c b/debian/vendor-h2o/deps/mruby-iijson/src/json.c deleted file mode 100644 index 6836e09..0000000 --- a/debian/vendor-h2o/deps/mruby-iijson/src/json.c +++ /dev/null @@ -1,641 +0,0 @@ -#include <ctype.h> -#include <inttypes.h> -#include <string.h> - -#include "mruby.h" -#include "mruby/array.h" -#include "mruby/hash.h" -#include "mruby/string.h" -#include "mruby/value.h" - -#define E_JSON_PARSER_ERROR (mrb_class_get_under(mrb, mrb_module_get(mrb, "JSON"), "ParserError")) - -#define JSON_EOF -1 - -#define DEFAULT_MAX_NESTING 100 - -struct json_parser { - mrb_state *mrb; - mrb_value src; - unsigned int cursor; - unsigned int lineno; - int nesting; - - int max_nesting; -}; - -static void json_check_nesting(struct json_parser *); -static int json_delimiter_p(char ch); -static int json_getc(struct json_parser *); -static void json_skip_ws(struct json_parser *); -static void json_ungetc(struct json_parser *); -static int json_unicode2utf8(uint32_t, char *); -static int json_whitespace_p(char ch); - -static int json_parse_array(struct json_parser *, mrb_value *); -static int json_parse_object(struct json_parser *, mrb_value *); -static int json_parse_number2(struct json_parser *, int, mrb_value *, mrb_int, int); -static int json_parse_string(struct json_parser *, mrb_value *); -static int json_parse_value(struct json_parser *, mrb_value *); - -#if MRUBY_RELEASE_NO < 10000 -static struct RClass * -mrb_module_get(mrb_state *mrb, const char *name) -{ - return mrb_class_get(mrb, name); -} -#endif -#if !defined(MRB_PRId) -#if defined(MRB_INT64) -# define MRB_PRId PRId64 -#elif defined(MRB_INT16) -# define MRB_PRId PRId16 -#else -# define MRB_PRId PRId32 -#endif -#endif /* !defined(MRB_PRId) */ - -static void -json_check_nesting(struct json_parser *parser) -{ - mrb_state *mrb = parser->mrb; - - if (parser->max_nesting != -1) { - if (parser->nesting >= parser->max_nesting) { - // +1 for compatibility with CRuby - mrb_raisef(mrb, E_JSON_PARSER_ERROR, "nesting of %S is too deep", mrb_fixnum_value(parser->nesting+1)); - } - } -} - -static int -json_delimiter_p(char ch) -{ - return (json_whitespace_p(ch) || ch == ',' || ch == ']' || ch == '}'); -} - -static int -json_getc(struct json_parser *parser) -{ - if (parser->cursor < RSTRING_LEN(parser->src)) { - unsigned char ch = RSTRING_PTR(parser->src)[parser->cursor]; - parser->cursor++; - return ch; - } else { - return JSON_EOF; - } -} - -static int -json_parse_readstring(struct json_parser *parser, const char *str) -{ - size_t len; - int ch; - - len = strlen(str); - if (parser->cursor + len > RSTRING_LEN(parser->src)) - return 0; - if (memcmp(str, RSTRING_PTR(parser->src) + parser->cursor, len) != 0) - return -1; - parser->cursor += len; - if (parser->cursor == RSTRING_LEN(parser->src)) - return 1; - ch = RSTRING_PTR(parser->src)[parser->cursor]; - if (!json_delimiter_p(ch)) - return -1; - return 1; -} - -static void -json_skip_ws(struct json_parser *parser) -{ - int ch; - - do { - ch = json_getc(parser); - if (ch == 0x0a) - parser->lineno++; - } while (json_whitespace_p(ch)); - if (ch != JSON_EOF) { - json_ungetc(parser); - } -} - -static void -json_ungetc(struct json_parser *parser) -{ - if (parser->cursor > 0) - parser->cursor--; -} - -static int -json_unicode2utf8(uint32_t unicode, char *cp) -{ - int n = 0; - if (unicode < 0x80) { - cp[n++] = unicode; - } else if (unicode < 0x800) { - cp[n++] = 0xc0 + (unicode >> 6); - cp[n++] = 0x80 + (unicode & 0x3f); - } else if (unicode < 0x10000) { - cp[n++] = 0xe0 + (unicode >> 12); - cp[n++] = 0x80 + ((unicode >> 6) & 0x3f); - cp[n++] = 0x80 + (unicode & 0x3f); - } else { - cp[n++] = 0xf0 + (unicode >> 18); - cp[n++] = 0x80 + ((unicode >> 12) & 0x3f); - cp[n++] = 0x80 + ((unicode >> 6) & 0x3f); - cp[n++] = 0x80 + (unicode & 0x3f); - } - return n; -} - -static int -json_whitespace_p(char ch) -{ - return (ch == 0x20 || ch == 0x09 || ch == 0x0a || ch == 0x0d); -} - -static int -json_parse_array(struct json_parser *parser, mrb_value *result) -{ - mrb_state *mrb = parser->mrb; - mrb_value ary, v; - int ch; - - json_check_nesting(parser); - - ary = mrb_ary_new(mrb); - - json_skip_ws(parser); - ch = json_getc(parser); - if (ch == ']') { /* easy case */ - *result = ary; - return 1; - } - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "JSON_EOF in array(1)"); - } - json_ungetc(parser); - - while (1) { - parser->nesting++; - if (json_parse_value(parser, &v) != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in array"); - } - parser->nesting--; - - mrb_ary_push(mrb, ary, v); - - json_skip_ws(parser); - ch = json_getc(parser); - if (ch == ']') { - break; - } - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "JSON_EOF in array(2)"); - } - if (ch != ',') { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "not ',' in array"); - } - } - *result = ary; - return 1; -} - -static int -json_parse_object(struct json_parser *parser, mrb_value *result) -{ - mrb_state *mrb = parser->mrb; - mrb_value h, k, v; - int ch; - - json_check_nesting(parser); - - h = mrb_hash_new(mrb); - - json_skip_ws(parser); - ch = json_getc(parser); - if (ch == '}') { /* easy case */ - *result = h; - return 1; - } - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(1)"); - } - json_ungetc(parser); - - while (1) { - parser->nesting++; - if (json_parse_value(parser, &k) != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in object key"); - } - parser->nesting--; - if (! mrb_string_p(k)) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "key is not a string"); - } - - json_skip_ws(parser); - - ch = json_getc(parser); - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(2)"); - } - if (ch != ':') { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "no ':' in object"); - } - - parser->nesting++; - if (json_parse_value(parser, &v) != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in object value"); - } - parser->nesting--; - - mrb_hash_set(mrb, h, k, v); - - json_skip_ws(parser); - ch = json_getc(parser); - if (ch == '}') { - break; - } - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(3)"); - } - if (ch != ',') { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "no ',' in object"); - } - } - *result = h; - return 1; -} - -static int -json_parse_number(struct json_parser *parser, int ch, mrb_value *result) -{ - mrb_state *mrb = parser->mrb; - mrb_int num; - int d, sign; - - if (ch == '-') { - sign = -1; - ch = json_getc(parser); - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "no character following minus"); - } - if (!isdigit(ch)) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "character following minus is not a digit"); - } - } else { - sign = 1; - } - num = (ch - '0') * sign; - while (1) { - ch = json_getc(parser); - if (ch == JSON_EOF) { - break; - } - if (isdigit(ch)) { - if (num == 0) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "leading zeros are not allowed"); - } - d = (ch - '0') * sign; - if (num < MRB_INT_MIN / 10 || - (num == MRB_INT_MIN / 10 && d < MRB_INT_MIN - num * 10) || - num > MRB_INT_MAX / 10 || - (num == MRB_INT_MAX / 10 && d > MRB_INT_MAX - num * 10)) { - return json_parse_number2(parser, ch, result, num, sign); - } - num = num * 10 + d; - } else if (ch == '.' || ch == 'e' || ch == 'E') { - return json_parse_number2(parser, ch, result, num, sign); - } else if (json_delimiter_p(ch)) { - json_ungetc(parser); - break; - } else { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid number"); - } - } - *result = mrb_fixnum_value(num); - return 1; -} - -static int -json_parse_number2(struct json_parser *parser, int ch, mrb_value *result, mrb_int num, int sign) -{ - mrb_state *mrb = parser->mrb; - double d; - int i, state; - char buf[64]; - - /* - * "-"? ("0" | [1-9] digit* ) ("." digit+ )? ([eE][-+] digit+)? - * state: 000000 111 222222 33334444 555555 - */ - i = snprintf(buf, sizeof(buf), "%s%"MRB_PRId"%c", - (num == 0 && sign < 0) ? "-" : "", - num, ch); - - if (isdigit(ch)) - state = 0; - else if (ch == '.') - state = 1; - else /* (ch == 'e' || ch == 'E') */ - state = 3; - - while (1) { - ch = json_getc(parser); - if (ch == JSON_EOF) - break; - switch (state) { - case 0: - if (isdigit(ch)) - ; /* read more digits */ - else if (ch == '.') - state = 1; - else if (ch == 'e' || ch == 'E') - state = 3; - else if (json_delimiter_p(ch)) { - json_ungetc(parser); - state = -1; - } else - goto formaterr; - break; - case 1: - if (!isdigit(ch)) - goto formaterr; - state = 2; - break; - case 2: - if (isdigit(ch)) - ; /* read more digits */ - else if (ch == 'e' || ch == 'E') - state = 3; - else if (json_delimiter_p(ch)) { - json_ungetc(parser); - state = -1; - } else - goto formaterr; - break; - case 3: - if (ch == '-' || ch == '+') - state = 4; - else if (isdigit(ch)) - state = 5; - else - goto formaterr; - break; - case 4: - if (!isdigit(ch)) - goto formaterr; - state = 5; - break; - case 5: - default: - if (isdigit(ch)) - ; /* read more digits */ - else { - json_ungetc(parser); - state = -1; - } - break; - } - if (state == -1) - break; - if (i == sizeof(buf) - 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "floating point number too long"); - } - buf[i++] = ch; - } - buf[i] = '\0'; - sscanf(buf, "%lf", &d); - *result = mrb_float_value(mrb, d); - return 1; - -formaterr: - mrb_raise(mrb, E_JSON_PARSER_ERROR, "floating point number error"); - return -1; -} - -static int -json_parse_string(struct json_parser *parser, mrb_value *result) -{ - mrb_state *mrb = parser->mrb; - mrb_value str; - uint32_t unicode; - uint16_t utf16; - int ch, i, n; - char *cp; - - str = mrb_str_buf_new(mrb, 30); - cp = RSTRING_PTR(str); - n = 0; - unicode = 0; - - while (1) { - ch = json_getc(parser); - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in string"); - } - - if (ch == '"') { - break; - } else if (ch == '\\') { - ch = json_getc(parser); - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF following escape char"); - } - switch (ch) { - case '"': - case '\\': - case '/': - break; - case 'b': - ch = 0x08; - break; - case 'f': - ch = 0x0c; - break; - case 'n': - ch = 0x0a; - break; - case 'r': - ch = 0x0d; - break; - case 't': - ch = 0x09; - break; - case 'u': - utf16 = 0; - for (i = 0; i < 4; i++) { - ch = json_getc(parser); - if (ch == JSON_EOF) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid unicode escape"); - } - if (ch >= '0' && ch <= '9') { - ch -= '0'; - } else if (ch >= 'A' && ch <= 'F') { - ch = (ch - 'A') + 10; - } else if (ch >= 'a' && ch <= 'f') { - ch = (ch - 'a') + 10; - } else { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid unicode character"); - } - utf16 *= 16; - utf16 += ch; - } - - if (n + 8 >= RSTRING_CAPA(str)) { - mrb_str_resize(mrb, str, RSTRING_CAPA(str)*2); - cp = RSTRING_PTR(str); - } - - if ((utf16 & 0xf800) == 0xd800) { - if ((utf16 & 0xfc00) == 0xd800) { - /* high surrogate */ - unicode = utf16; - continue; - } else { - /* low surrogate */ - if (unicode > 0) { - unicode = ((unicode & 0x03ff) + 0x040) << 10; - unicode += utf16 & 0x03ff; - } else { - /* error: low surrogate comes first... */ - } - } - } else { - if (unicode > 0) { - /* error: high surrogate not followed by low surrogate */ - n += json_unicode2utf8(unicode, &cp[n]); - } - unicode = utf16; - } - - n += json_unicode2utf8(unicode, &cp[n]); - unicode = 0; - continue; - default: - mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid escape char"); - break; - } - } else if (ch < 0x20) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid char"); - } - - if (n + 1 == RSTRING_CAPA(str)) { - mrb_str_resize(mrb, str, RSTRING_CAPA(str)*2); - cp = RSTRING_PTR(str); - } - cp[n++] = ch; - } - cp[n] = '\0'; - mrb_str_resize(mrb, str, n); - *result = str; - return 1; -} - -static int -json_parse_value(struct json_parser *parser, mrb_value *result) -{ - mrb_state *mrb = parser->mrb; - int ch; - - do { - ch = json_getc(parser); - if (ch == JSON_EOF) - return 0; - } while (json_whitespace_p(ch)); - - switch (ch) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '-': - if (json_parse_number(parser, ch, result) != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "number...?"); - } - break; - - case '"': - if (json_parse_string(parser, result) != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "string...?"); - } - break; - - case '[': - if (json_parse_array(parser, result) != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "array...?"); - } - break; - - case '{': - if (json_parse_object(parser, result) != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "object...?"); - } - break; - - case 'f': - if (json_parse_readstring(parser, "alse") != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected f"); - } - *result = mrb_false_value(); - break; - - case 'n': - if (json_parse_readstring(parser, "ull") != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected n"); - } - *result = mrb_nil_value(); - break; - - case 't': - if (json_parse_readstring(parser, "rue") != 1) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected t"); - } - *result = mrb_true_value(); - break; - - default: - mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected character"); - } - - return 1; -} - -static mrb_value -mrb_json_parse(mrb_state *mrb, mrb_value mod) -{ - struct json_parser parser; - mrb_value obj, options, source; - - mrb_get_args(mrb, "S|H", &source, &options); - - parser.mrb = mrb; - parser.src = source; - parser.cursor = 0; - parser.lineno = 0; - parser.nesting = 0; - parser.max_nesting = DEFAULT_MAX_NESTING; - - if (json_parse_value(&parser, &obj) == 0) { - mrb_raise(mrb, E_JSON_PARSER_ERROR, "no JSON value"); - } - - // if we have extra characters: - // unexpected token at '3' (JSON::ParserError) - - return obj; -} - -void -mrb_mruby_iijson_gem_init(mrb_state *mrb) -{ - struct RClass *m; - - m = mrb_define_module(mrb, "JSON"); - mrb_define_module_function(mrb, m, "parse", mrb_json_parse, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); -} - -void -mrb_mruby_iijson_gem_final(mrb_state *mrb) -{ -} |