1 #include "../fbuffer/fbuffer.h"
4 #ifdef HAVE_RUBY_ENCODING_H
51 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
52 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
53 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
54 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
56 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
57 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
58 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
67 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
82 const UTF8 *srcptr = source+length;
86 case 4:
if ((a = (*--srcptr)) < 0x80 || a > 0xBF)
return 0;
87 case 3:
if ((a = (*--srcptr)) < 0x80 || a > 0xBF)
return 0;
88 case 2:
if ((a = (*--srcptr)) > 0xBF)
return 0;
92 case 0xE0:
if (a < 0xA0)
return 0;
break;
93 case 0xED:
if (a > 0x9F)
return 0;
break;
94 case 0xF0:
if (a < 0x90)
return 0;
break;
95 case 0xF4:
if (a > 0x8F)
return 0;
break;
96 default:
if (a < 0x80)
return 0;
99 case 1:
if (*source >= 0x80 && *source < 0xC2)
return 0;
101 if (*source > 0xF4)
return 0;
108 const char *digits =
"0123456789abcdef";
110 buf[2] = digits[character >> 12];
111 buf[3] = digits[(character >> 8) & 0xf];
112 buf[4] = digits[(character >> 4) & 0xf];
113 buf[5] = digits[character & 0xf];
131 char buf[6] = {
'\\',
'u' };
133 while (source < sourceEnd) {
136 if (source + extraBytesToRead >= sourceEnd) {
138 "partial character in source, but hit end");
142 "source sequence is illegal/malformed utf-8");
147 switch (extraBytesToRead) {
148 case 5: ch += *source++; ch <<= 6;
149 case 4: ch += *source++; ch <<= 6;
150 case 3: ch += *source++; ch <<= 6;
151 case 2: ch += *source++; ch <<= 6;
152 case 1: ch += *source++; ch <<= 6;
153 case 0: ch += *source++;
160 #if UNI_STRICT_CONVERSION
161 source -= (extraBytesToRead+1);
163 "source sequence is illegal/malformed utf-8");
169 if (ch >= 0x20 && ch <= 0x7f) {
205 #if UNI_STRICT_CONVERSION
206 source -= (extraBytesToRead+1);
208 "source sequence is illegal/malformed utf8");
228 unsigned long len =
RSTRING_LEN(
string), start = 0, end = 0;
229 const char *escape =
NULL;
232 char buf[6] = {
'\\',
'u' };
234 for (start = 0, end = 0; end < len;) {
236 c = (
unsigned char) *
p;
289 static char *
fstrndup(
const char *ptr,
unsigned long len) {
291 if (len <= 0)
return NULL;
293 memccpy(result, ptr, 0, len);
526 state->indent_len = len;
534 state->space_len = len;
542 state->space_before_len = len;
550 state->array_nl_len = len;
558 state->object_nl_len = len;
561 state->max_nesting = 100;
564 if (
RTEST(max_nesting)) {
566 state->max_nesting =
FIX2LONG(max_nesting);
568 state->max_nesting = 0;
585 if (
RTEST(buffer_initial_length)) {
588 initial_length =
FIX2LONG(buffer_initial_length);
589 if (initial_length > 0) state->buffer_initial_length = initial_length;
593 state->allow_nan =
RTEST(tmp);
595 state->ascii_only =
RTEST(tmp);
597 state->quirks_mode =
RTEST(tmp);
676 char *indent = state->
indent;
683 long depth = ++state->
depth;
686 if (max_nesting != 0 && depth > max_nesting) {
698 for (j = 0; j < depth; j++) {
709 depth = --state->
depth;
713 for (j = 0; j < depth; j++) {
725 char *indent = state->
indent;
730 long depth = ++state->
depth;
732 if (max_nesting != 0 && depth > max_nesting) {
741 for (j = 0; j < depth; j++) {
747 state->
depth = --depth;
751 for (j = 0; j < depth; j++) {
762 #ifdef HAVE_RUBY_ENCODING_H
790 fbuffer_append_long(buffer,
FIX2LONG(obj));
796 fbuffer_append_str(buffer, tmp);
808 }
else if (
isnan(value)) {
813 fbuffer_append_str(buffer, tmp);
826 }
else if (obj ==
Qnil) {
828 }
else if (obj ==
Qfalse) {
830 }
else if (obj ==
Qtrue) {
841 fbuffer_append_str(buffer, tmp);
855 if (state->object_delim) {
861 if (state->object_delim2) {
867 if (state->space)
fbuffer_append(state->object_delim2, state->space, state->space_len);
869 if (state->array_delim) {
875 if (state->array_nl)
fbuffer_append(state->array_delim, state->array_nl, state->array_nl_len);
884 return fbuffer_to_s(buffer);
896 if (string_len < 2)
return 0;
897 for (; p < q && isspace(*p); p++);
898 for (; q > p && isspace(*q); q--);
899 return (*p ==
'[' && *q ==
']') || (*p ==
'{' && *q ==
'}');
943 state->max_nesting = 100;
960 if (obj == orig)
return obj;
1021 if (state->indent) {
1023 state->indent =
NULL;
1024 state->indent_len = 0;
1027 if (state->indent)
ruby_xfree(state->indent);
1029 state->indent_len = len;
1061 state->space =
NULL;
1062 state->space_len = 0;
1067 state->space_len = len;
1080 return state->space_before ?
rb_str_new(state->space_before, state->space_before_len) :
rb_str_new2(
"");
1095 if (state->space_before) {
1097 state->space_before =
NULL;
1098 state->space_before_len = 0;
1101 if (state->space_before)
ruby_xfree(state->space_before);
1103 state->space_before_len = len;
1133 if (state->object_nl) {
1135 state->object_nl =
NULL;
1138 if (state->object_nl)
ruby_xfree(state->object_nl);
1140 state->object_nl_len = len;
1168 if (state->array_nl) {
1170 state->array_nl =
NULL;
1173 if (state->array_nl)
ruby_xfree(state->array_nl);
1175 state->array_nl_len = len;
1202 return LONG2FIX(state->max_nesting);
1215 return state->max_nesting =
FIX2LONG(depth);
1261 state->quirks_mode =
RTEST(enable);
1298 return LONG2FIX(state->buffer_initial_length);
1309 long initial_length;
1312 initial_length =
FIX2LONG(buffer_initial_length);
1313 if (initial_length > 0) {
1314 state->buffer_initial_length = initial_length;
1421 #ifdef HAVE_RUBY_ENCODING_H
static void fbuffer_clear(FBuffer *fb)
static VALUE eGeneratorError
static JSON_Generator_State * State_allocate()
VALUE rb_ary_entry(VALUE ary, long offset)
static VALUE i_SAFE_STATE_PROTOTYPE
static VALUE cState_array_nl(VALUE self)
static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static VALUE CRegexp_MULTILINE
static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self)
static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character)
static VALUE CEncoding_UTF_8
static const char trailingBytesForUTF8[256]
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
static VALUE cState_from_state_s(VALUE self, VALUE opts)
static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
VALUE rb_const_get(VALUE, ID)
static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length)
#define option_given_p(opts, key)
static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static VALUE mString_Extend_json_create(VALUE self, VALUE o)
static const UTF32 offsetsFromUTF8[6]
VALUE rb_iv_get(VALUE, const char *)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static VALUE cState_object_nl(VALUE self)
static VALUE cState_check_circular_p(VALUE self)
static VALUE cState_max_nesting(VALUE self)
VALUE rb_require(const char *)
#define RB_OBJ_STRING(obj)
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
static VALUE cState_space_before_set(VALUE self, VALUE space_before)
static const UTF32 halfBase
static VALUE mGeneratorMethods
static void fbuffer_append_char(FBuffer *fb, char newchr)
static VALUE cState_configure(VALUE self, VALUE opts)
RUBY_EXTERN VALUE rb_cFloat
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_raise(VALUE exc, const char *fmt,...)
static VALUE cState_quirks_mode_p(VALUE self)
VALUE rb_obj_class(VALUE)
VALUE rb_class_name(VALUE)
static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
static VALUE cState_s_allocate(VALUE klass)
static VALUE cState_allow_nan_p(VALUE self)
static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
VALUE rb_str_substr(VALUE, long, long)
VALUE rb_path2class(const char *)
#define FBUFFER_INITIAL_LENGTH_DEFAULT
VALUE rb_ivar_get(VALUE, ID)
VALUE rb_str_concat(VALUE, VALUE)
RUBY_EXTERN VALUE rb_cRegexp
static VALUE cState_indent(VALUE self)
static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static VALUE cState_space_set(VALUE self, VALUE space)
#define MEMZERO(p, type, n)
static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static VALUE cState_generate(VALUE self, VALUE obj)
#define rb_intern_str(string)
static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
static VALUE cState_depth(VALUE self)
RUBY_EXTERN VALUE rb_cHash
#define StringValueCStr(v)
VALUE rb_str_cat2(VALUE, const char *)
static VALUE cState_indent_set(VALUE self, VALUE indent)
static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
static VALUE cState_depth_set(VALUE self, VALUE depth)
static int isArrayOrObject(VALUE string)
static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static FBuffer * fbuffer_alloc(unsigned long initial_length)
static VALUE mString_to_json_raw_object(VALUE self)
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
static const int halfShift
static char * fstrndup(const char *ptr, unsigned long len)
RUBY_EXTERN VALUE rb_cFixnum
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
static VALUE cState_to_h(VALUE self)
static VALUE cState_space_before(VALUE self)
unsigned char buf[MIME_BUF_SIZE]
static VALUE cState_partial_generate(VALUE self, VALUE obj)
static const UTF32 halfMask
static VALUE cState_ascii_only_p(VALUE self)
static void unicode_escape(char *buf, UTF16 character)
#define UNI_SUR_HIGH_START
RUBY_EXTERN int isinf(double)
static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
RUBY_EXTERN VALUE rb_cString
#define MEMCPY(p1, p2, type, n)
VALUE rb_define_module_under(VALUE outer, const char *name)
static VALUE CJSON_SAFE_STATE_PROTOTYPE
static ID i_buffer_initial_length
static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
VALUE rb_ivar_set(VALUE, ID, VALUE)
static FBuffer * cState_prepare_buffer(VALUE self)
static VALUE cState_aref(VALUE self, VALUE name)
static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
static VALUE mString_Extend
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
#define GENERATE_JSON(type)
static void fbuffer_free(FBuffer *fb)
static void set_state_ivars(VALUE hash, VALUE state)
static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
RUBY_EXTERN VALUE rb_cObject
#define Data_Get_Struct(obj, type, sval)
int rb_respond_to(VALUE, ID)
#define UNI_SUR_LOW_START
static VALUE eNestingError
#define UNI_REPLACEMENT_CHAR
static unsigned int hash(const char *str, unsigned int len)
static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length)
VALUE rb_str_new(const char *, long)
VALUE rb_str_intern(VALUE)
static VALUE cState_buffer_initial_length(VALUE self)
static VALUE cState_init_copy(VALUE obj, VALUE orig)
static VALUE cState_space(VALUE self)
VALUE rb_hash_aref(VALUE, VALUE)
static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
#define Data_Wrap_Struct(klass, mark, free, sval)
VALUE rb_define_module(const char *name)
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
#define rb_obj_instance_variables(object)
VALUE rb_convert_type(VALUE, int, const char *, const char *)
static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
static VALUE mString_included_s(VALUE self, VALUE modul)
static void State_free(JSON_Generator_State *state)