00001 #include "generator.h"
00002
00003 #ifdef HAVE_RUBY_ENCODING_H
00004 static VALUE CEncoding_UTF_8;
00005 static ID i_encoding, i_encode;
00006 #endif
00007
00008 #ifdef PRIsVALUE
00009 # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
00010 # define RB_OBJ_STRING(obj) (obj)
00011 #else
00012 # define PRIsVALUE "s"
00013 # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
00014 # define RB_OBJ_STRING(obj) StringValueCStr(obj)
00015 #endif
00016
00017 static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
00018 mHash, mArray, mFixnum, mBignum, mFloat, mString, mString_Extend,
00019 mTrueClass, mFalseClass, mNilClass, eGeneratorError,
00020 eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE,
00021 i_SAFE_STATE_PROTOTYPE;
00022
00023 static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
00024 i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
00025 i_quirks_mode, i_pack, i_unpack, i_create_id, i_extend, i_key_p,
00026 i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth, i_dup;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 static const char trailingBytesForUTF8[256] = {
00058 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,
00059 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,
00060 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,
00061 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,
00062 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,
00063 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,
00064 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,
00065 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
00066 };
00067
00068
00069
00070
00071
00072
00073 static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
00074 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length)
00087 {
00088 UTF8 a;
00089 const UTF8 *srcptr = source+length;
00090 switch (length) {
00091 default: return 0;
00092
00093 case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
00094 case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
00095 case 2: if ((a = (*--srcptr)) > 0xBF) return 0;
00096
00097 switch (*source) {
00098
00099 case 0xE0: if (a < 0xA0) return 0; break;
00100 case 0xED: if (a > 0x9F) return 0; break;
00101 case 0xF0: if (a < 0x90) return 0; break;
00102 case 0xF4: if (a > 0x8F) return 0; break;
00103 default: if (a < 0x80) return 0;
00104 }
00105
00106 case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
00107 }
00108 if (*source > 0xF4) return 0;
00109 return 1;
00110 }
00111
00112
00113 static void unicode_escape(char *buf, UTF16 character)
00114 {
00115 const char *digits = "0123456789abcdef";
00116
00117 buf[2] = digits[character >> 12];
00118 buf[3] = digits[(character >> 8) & 0xf];
00119 buf[4] = digits[(character >> 4) & 0xf];
00120 buf[5] = digits[character & 0xf];
00121 }
00122
00123
00124
00125 static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16
00126 character)
00127 {
00128 unicode_escape(buf, character);
00129 fbuffer_append(buffer, buf, 6);
00130 }
00131
00132
00133
00134 static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
00135 {
00136 const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
00137 const UTF8 *sourceEnd = source + RSTRING_LEN(string);
00138 char buf[6] = { '\\', 'u' };
00139
00140 while (source < sourceEnd) {
00141 UTF32 ch = 0;
00142 unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
00143 if (source + extraBytesToRead >= sourceEnd) {
00144 rb_raise(rb_path2class("JSON::GeneratorError"),
00145 "partial character in source, but hit end");
00146 }
00147 if (!isLegalUTF8(source, extraBytesToRead+1)) {
00148 rb_raise(rb_path2class("JSON::GeneratorError"),
00149 "source sequence is illegal/malformed utf-8");
00150 }
00151
00152
00153
00154 switch (extraBytesToRead) {
00155 case 5: ch += *source++; ch <<= 6;
00156 case 4: ch += *source++; ch <<= 6;
00157 case 3: ch += *source++; ch <<= 6;
00158 case 2: ch += *source++; ch <<= 6;
00159 case 1: ch += *source++; ch <<= 6;
00160 case 0: ch += *source++;
00161 }
00162 ch -= offsetsFromUTF8[extraBytesToRead];
00163
00164 if (ch <= UNI_MAX_BMP) {
00165
00166 if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
00167 #if UNI_STRICT_CONVERSION
00168 source -= (extraBytesToRead+1);
00169 rb_raise(rb_path2class("JSON::GeneratorError"),
00170 "source sequence is illegal/malformed utf-8");
00171 #else
00172 unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR);
00173 #endif
00174 } else {
00175
00176 if (ch >= 0x20 && ch <= 0x7f) {
00177 switch (ch) {
00178 case '\\':
00179 fbuffer_append(buffer, "\\\\", 2);
00180 break;
00181 case '"':
00182 fbuffer_append(buffer, "\\\"", 2);
00183 break;
00184 default:
00185 fbuffer_append_char(buffer, (char)ch);
00186 break;
00187 }
00188 } else {
00189 switch (ch) {
00190 case '\n':
00191 fbuffer_append(buffer, "\\n", 2);
00192 break;
00193 case '\r':
00194 fbuffer_append(buffer, "\\r", 2);
00195 break;
00196 case '\t':
00197 fbuffer_append(buffer, "\\t", 2);
00198 break;
00199 case '\f':
00200 fbuffer_append(buffer, "\\f", 2);
00201 break;
00202 case '\b':
00203 fbuffer_append(buffer, "\\b", 2);
00204 break;
00205 default:
00206 unicode_escape_to_buffer(buffer, buf, (UTF16) ch);
00207 break;
00208 }
00209 }
00210 }
00211 } else if (ch > UNI_MAX_UTF16) {
00212 #if UNI_STRICT_CONVERSION
00213 source -= (extraBytesToRead+1);
00214 rb_raise(rb_path2class("JSON::GeneratorError"),
00215 "source sequence is illegal/malformed utf8");
00216 #else
00217 unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR);
00218 #endif
00219 } else {
00220
00221 ch -= halfBase;
00222 unicode_escape_to_buffer(buffer, buf, (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START));
00223 unicode_escape_to_buffer(buffer, buf, (UTF16)((ch & halfMask) + UNI_SUR_LOW_START));
00224 }
00225 }
00226 }
00227
00228
00229
00230
00231
00232 static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
00233 {
00234 const char *ptr = RSTRING_PTR(string), *p;
00235 unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
00236 const char *escape = NULL;
00237 int escape_len;
00238 unsigned char c;
00239 char buf[6] = { '\\', 'u' };
00240
00241 for (start = 0, end = 0; end < len;) {
00242 p = ptr + end;
00243 c = (unsigned char) *p;
00244 if (c < 0x20) {
00245 switch (c) {
00246 case '\n':
00247 escape = "\\n";
00248 escape_len = 2;
00249 break;
00250 case '\r':
00251 escape = "\\r";
00252 escape_len = 2;
00253 break;
00254 case '\t':
00255 escape = "\\t";
00256 escape_len = 2;
00257 break;
00258 case '\f':
00259 escape = "\\f";
00260 escape_len = 2;
00261 break;
00262 case '\b':
00263 escape = "\\b";
00264 escape_len = 2;
00265 break;
00266 default:
00267 unicode_escape(buf, (UTF16) *p);
00268 escape = buf;
00269 escape_len = 6;
00270 break;
00271 }
00272 } else {
00273 switch (c) {
00274 case '\\':
00275 escape = "\\\\";
00276 escape_len = 2;
00277 break;
00278 case '"':
00279 escape = "\\\"";
00280 escape_len = 2;
00281 break;
00282 default:
00283 end++;
00284 continue;
00285 break;
00286 }
00287 }
00288 fbuffer_append(buffer, ptr + start, end - start);
00289 fbuffer_append(buffer, escape, escape_len);
00290 start = ++end;
00291 escape = NULL;
00292 }
00293 fbuffer_append(buffer, ptr + start, end - start);
00294 }
00295
00296 static char *fstrndup(const char *ptr, unsigned long len) {
00297 char *result;
00298 if (len <= 0) return NULL;
00299 result = ALLOC_N(char, len);
00300 memccpy(result, ptr, 0, len);
00301 return result;
00302 }
00303
00304
00305
00306 static FBuffer *fbuffer_alloc()
00307 {
00308 FBuffer *fb = ALLOC(FBuffer);
00309 memset((void *) fb, 0, sizeof(FBuffer));
00310 fb->initial_length = FBUFFER_INITIAL_LENGTH;
00311 return fb;
00312 }
00313
00314 static FBuffer *fbuffer_alloc_with_length(unsigned long initial_length)
00315 {
00316 FBuffer *fb;
00317 assert(initial_length > 0);
00318 fb = ALLOC(FBuffer);
00319 memset((void *) fb, 0, sizeof(FBuffer));
00320 fb->initial_length = initial_length;
00321 return fb;
00322 }
00323
00324 static void fbuffer_free(FBuffer *fb)
00325 {
00326 if (fb->ptr) ruby_xfree(fb->ptr);
00327 ruby_xfree(fb);
00328 }
00329
00330 static void fbuffer_clear(FBuffer *fb)
00331 {
00332 fb->len = 0;
00333 }
00334
00335 static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
00336 {
00337 unsigned long required;
00338
00339 if (!fb->ptr) {
00340 fb->ptr = ALLOC_N(char, fb->initial_length);
00341 fb->capa = fb->initial_length;
00342 }
00343
00344 for (required = fb->capa; requested > required - fb->len; required <<= 1);
00345
00346 if (required > fb->capa) {
00347 REALLOC_N(fb->ptr, char, required);
00348 fb->capa = required;
00349 }
00350 }
00351
00352 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
00353 {
00354 if (len > 0) {
00355 fbuffer_inc_capa(fb, len);
00356 MEMCPY(fb->ptr + fb->len, newstr, char, len);
00357 fb->len += len;
00358 }
00359 }
00360
00361 static void fbuffer_append_str(FBuffer *fb, VALUE str)
00362 {
00363 const char *newstr = StringValuePtr(str);
00364 unsigned long len = RSTRING_LEN(str);
00365
00366 RB_GC_GUARD(str);
00367
00368 fbuffer_append(fb, newstr, len);
00369 }
00370
00371 static void fbuffer_append_char(FBuffer *fb, char newchr)
00372 {
00373 fbuffer_inc_capa(fb, 1);
00374 *(fb->ptr + fb->len) = newchr;
00375 fb->len++;
00376 }
00377
00378 static void freverse(char *start, char *end)
00379 {
00380 char c;
00381
00382 while (end > start) {
00383 c = *end, *end-- = *start, *start++ = c;
00384 }
00385 }
00386
00387 static long fltoa(long number, char *buf)
00388 {
00389 static char digits[] = "0123456789";
00390 long sign = number;
00391 char* tmp = buf;
00392
00393 if (sign < 0) number = -number;
00394 do *tmp++ = digits[number % 10]; while (number /= 10);
00395 if (sign < 0) *tmp++ = '-';
00396 freverse(buf, tmp - 1);
00397 return tmp - buf;
00398 }
00399
00400 static void fbuffer_append_long(FBuffer *fb, long number)
00401 {
00402 char buf[20];
00403 unsigned long len = fltoa(number, buf);
00404 fbuffer_append(fb, buf, len);
00405 }
00406
00407 static FBuffer *fbuffer_dup(FBuffer *fb)
00408 {
00409 unsigned long len = fb->len;
00410 FBuffer *result;
00411
00412 if (len > 0) {
00413 result = fbuffer_alloc_with_length(len);
00414 fbuffer_append(result, FBUFFER_PAIR(fb));
00415 } else {
00416 result = fbuffer_alloc();
00417 }
00418 return result;
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
00442 {
00443 GENERATE_JSON(object);
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
00455 GENERATE_JSON(array);
00456 }
00457
00458
00459
00460
00461
00462
00463 static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
00464 {
00465 GENERATE_JSON(fixnum);
00466 }
00467
00468
00469
00470
00471
00472
00473 static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
00474 {
00475 GENERATE_JSON(bignum);
00476 }
00477
00478
00479
00480
00481
00482
00483 static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
00484 {
00485 GENERATE_JSON(float);
00486 }
00487
00488
00489
00490
00491
00492
00493 static VALUE mString_included_s(VALUE self, VALUE modul) {
00494 VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
00495 return result;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505 static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
00506 {
00507 GENERATE_JSON(string);
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 static VALUE mString_to_json_raw_object(VALUE self)
00519 {
00520 VALUE ary;
00521 VALUE result = rb_hash_new();
00522 rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self)));
00523 ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*"));
00524 rb_hash_aset(result, rb_str_new2("raw"), ary);
00525 return result;
00526 }
00527
00528
00529
00530
00531
00532
00533
00534 static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
00535 {
00536 VALUE obj = mString_to_json_raw_object(self);
00537 Check_Type(obj, T_HASH);
00538 return mHash_to_json(argc, argv, obj);
00539 }
00540
00541
00542
00543
00544
00545
00546
00547 static VALUE mString_Extend_json_create(VALUE self, VALUE o)
00548 {
00549 VALUE ary;
00550 Check_Type(o, T_HASH);
00551 ary = rb_hash_aref(o, rb_str_new2("raw"));
00552 return rb_funcall(ary, i_pack, 1, rb_str_new2("C*"));
00553 }
00554
00555
00556
00557
00558
00559
00560 static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
00561 {
00562 GENERATE_JSON(true);
00563 }
00564
00565
00566
00567
00568
00569
00570 static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
00571 {
00572 GENERATE_JSON(false);
00573 }
00574
00575
00576
00577
00578
00579
00580 static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
00581 {
00582 GENERATE_JSON(null);
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592 static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
00593 {
00594 VALUE state;
00595 VALUE string = rb_funcall(self, i_to_s, 0);
00596 rb_scan_args(argc, argv, "01", &state);
00597 Check_Type(string, T_STRING);
00598 state = cState_from_state_s(cState, state);
00599 return cState_partial_generate(state, string);
00600 }
00601
00602 static void State_free(JSON_Generator_State *state)
00603 {
00604 if (state->indent) ruby_xfree(state->indent);
00605 if (state->space) ruby_xfree(state->space);
00606 if (state->space_before) ruby_xfree(state->space_before);
00607 if (state->object_nl) ruby_xfree(state->object_nl);
00608 if (state->array_nl) ruby_xfree(state->array_nl);
00609 if (state->array_delim) fbuffer_free(state->array_delim);
00610 if (state->object_delim) fbuffer_free(state->object_delim);
00611 if (state->object_delim2) fbuffer_free(state->object_delim2);
00612 ruby_xfree(state);
00613 }
00614
00615 static JSON_Generator_State *State_allocate()
00616 {
00617 JSON_Generator_State *state = ALLOC(JSON_Generator_State);
00618 MEMZERO(state, JSON_Generator_State, 1);
00619 return state;
00620 }
00621
00622 static VALUE cState_s_allocate(VALUE klass)
00623 {
00624 JSON_Generator_State *state = State_allocate();
00625 return Data_Wrap_Struct(klass, NULL, State_free, state);
00626 }
00627
00628
00629
00630
00631
00632
00633
00634 static VALUE cState_configure(VALUE self, VALUE opts)
00635 {
00636 VALUE tmp;
00637 GET_STATE(self);
00638 tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
00639 if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
00640 if (NIL_P(tmp)) {
00641 rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash");
00642 }
00643 opts = tmp;
00644 tmp = rb_hash_aref(opts, ID2SYM(i_indent));
00645 if (RTEST(tmp)) {
00646 unsigned long len;
00647 Check_Type(tmp, T_STRING);
00648 len = RSTRING_LEN(tmp);
00649 state->indent = fstrndup(RSTRING_PTR(tmp), len);
00650 state->indent_len = len;
00651 }
00652 tmp = rb_hash_aref(opts, ID2SYM(i_space));
00653 if (RTEST(tmp)) {
00654 unsigned long len;
00655 Check_Type(tmp, T_STRING);
00656 len = RSTRING_LEN(tmp);
00657 state->space = fstrndup(RSTRING_PTR(tmp), len);
00658 state->space_len = len;
00659 }
00660 tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
00661 if (RTEST(tmp)) {
00662 unsigned long len;
00663 Check_Type(tmp, T_STRING);
00664 len = RSTRING_LEN(tmp);
00665 state->space_before = fstrndup(RSTRING_PTR(tmp), len);
00666 state->space_before_len = len;
00667 }
00668 tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
00669 if (RTEST(tmp)) {
00670 unsigned long len;
00671 Check_Type(tmp, T_STRING);
00672 len = RSTRING_LEN(tmp);
00673 state->array_nl = fstrndup(RSTRING_PTR(tmp), len);
00674 state->array_nl_len = len;
00675 }
00676 tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
00677 if (RTEST(tmp)) {
00678 unsigned long len;
00679 Check_Type(tmp, T_STRING);
00680 len = RSTRING_LEN(tmp);
00681 state->object_nl = fstrndup(RSTRING_PTR(tmp), len);
00682 state->object_nl_len = len;
00683 }
00684 tmp = ID2SYM(i_max_nesting);
00685 state->max_nesting = 19;
00686 if (option_given_p(opts, tmp)) {
00687 VALUE max_nesting = rb_hash_aref(opts, tmp);
00688 if (RTEST(max_nesting)) {
00689 Check_Type(max_nesting, T_FIXNUM);
00690 state->max_nesting = FIX2LONG(max_nesting);
00691 } else {
00692 state->max_nesting = 0;
00693 }
00694 }
00695 tmp = ID2SYM(i_depth);
00696 state->depth = 0;
00697 if (option_given_p(opts, tmp)) {
00698 VALUE depth = rb_hash_aref(opts, tmp);
00699 if (RTEST(depth)) {
00700 Check_Type(depth, T_FIXNUM);
00701 state->depth = FIX2LONG(depth);
00702 } else {
00703 state->depth = 0;
00704 }
00705 }
00706 tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
00707 state->allow_nan = RTEST(tmp);
00708 tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
00709 state->ascii_only = RTEST(tmp);
00710 tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode));
00711 state->quirks_mode = RTEST(tmp);
00712 return self;
00713 }
00714
00715
00716
00717
00718
00719
00720
00721 static VALUE cState_to_h(VALUE self)
00722 {
00723 VALUE result = rb_hash_new();
00724 GET_STATE(self);
00725 rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len));
00726 rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len));
00727 rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len));
00728 rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new(state->object_nl, state->object_nl_len));
00729 rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
00730 rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
00731 rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
00732 rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse);
00733 rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
00734 rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
00735 return result;
00736 }
00737
00738
00739
00740
00741
00742
00743 static VALUE cState_aref(VALUE self, VALUE name)
00744 {
00745 GET_STATE(self);
00746 if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
00747 return rb_funcall(self, i_send, 1, name);
00748 } else {
00749 return Qnil;
00750 }
00751 }
00752
00753 static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00754 {
00755 char *object_nl = state->object_nl;
00756 long object_nl_len = state->object_nl_len;
00757 char *indent = state->indent;
00758 long indent_len = state->indent_len;
00759 long max_nesting = state->max_nesting;
00760 char *delim = FBUFFER_PTR(state->object_delim);
00761 long delim_len = FBUFFER_LEN(state->object_delim);
00762 char *delim2 = FBUFFER_PTR(state->object_delim2);
00763 long delim2_len = FBUFFER_LEN(state->object_delim2);
00764 long depth = ++state->depth;
00765 int i, j;
00766 VALUE key, key_to_s, keys;
00767 if (max_nesting != 0 && depth > max_nesting) {
00768 fbuffer_free(buffer);
00769 rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
00770 }
00771 fbuffer_append_char(buffer, '{');
00772 keys = rb_funcall(obj, i_keys, 0);
00773 for(i = 0; i < RARRAY_LEN(keys); i++) {
00774 if (i > 0) fbuffer_append(buffer, delim, delim_len);
00775 if (object_nl) {
00776 fbuffer_append(buffer, object_nl, object_nl_len);
00777 }
00778 if (indent) {
00779 for (j = 0; j < depth; j++) {
00780 fbuffer_append(buffer, indent, indent_len);
00781 }
00782 }
00783 key = rb_ary_entry(keys, i);
00784 key_to_s = rb_funcall(key, i_to_s, 0);
00785 Check_Type(key_to_s, T_STRING);
00786 generate_json(buffer, Vstate, state, key_to_s);
00787 fbuffer_append(buffer, delim2, delim2_len);
00788 generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
00789 }
00790 depth = --state->depth;
00791 if (object_nl) {
00792 fbuffer_append(buffer, object_nl, object_nl_len);
00793 if (indent) {
00794 for (j = 0; j < depth; j++) {
00795 fbuffer_append(buffer, indent, indent_len);
00796 }
00797 }
00798 }
00799 fbuffer_append_char(buffer, '}');
00800 }
00801
00802 static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00803 {
00804 char *array_nl = state->array_nl;
00805 long array_nl_len = state->array_nl_len;
00806 char *indent = state->indent;
00807 long indent_len = state->indent_len;
00808 long max_nesting = state->max_nesting;
00809 char *delim = FBUFFER_PTR(state->array_delim);
00810 long delim_len = FBUFFER_LEN(state->array_delim);
00811 long depth = ++state->depth;
00812 int i, j;
00813 if (max_nesting != 0 && depth > max_nesting) {
00814 fbuffer_free(buffer);
00815 rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
00816 }
00817 fbuffer_append_char(buffer, '[');
00818 if (array_nl) fbuffer_append(buffer, array_nl, array_nl_len);
00819 for(i = 0; i < RARRAY_LEN(obj); i++) {
00820 if (i > 0) fbuffer_append(buffer, delim, delim_len);
00821 if (indent) {
00822 for (j = 0; j < depth; j++) {
00823 fbuffer_append(buffer, indent, indent_len);
00824 }
00825 }
00826 generate_json(buffer, Vstate, state, rb_ary_entry(obj, i));
00827 }
00828 state->depth = --depth;
00829 if (array_nl) {
00830 fbuffer_append(buffer, array_nl, array_nl_len);
00831 if (indent) {
00832 for (j = 0; j < depth; j++) {
00833 fbuffer_append(buffer, indent, indent_len);
00834 }
00835 }
00836 }
00837 fbuffer_append_char(buffer, ']');
00838 }
00839
00840 static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00841 {
00842 fbuffer_append_char(buffer, '"');
00843 #ifdef HAVE_RUBY_ENCODING_H
00844 obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
00845 #endif
00846 if (state->ascii_only) {
00847 convert_UTF8_to_JSON_ASCII(buffer, obj);
00848 } else {
00849 convert_UTF8_to_JSON(buffer, obj);
00850 }
00851 fbuffer_append_char(buffer, '"');
00852 }
00853
00854 static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00855 {
00856 fbuffer_append(buffer, "null", 4);
00857 }
00858
00859 static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00860 {
00861 fbuffer_append(buffer, "false", 5);
00862 }
00863
00864 static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00865 {
00866 fbuffer_append(buffer, "true", 4);
00867 }
00868
00869 static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00870 {
00871 fbuffer_append_long(buffer, FIX2LONG(obj));
00872 }
00873
00874 static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00875 {
00876 VALUE tmp = rb_funcall(obj, i_to_s, 0);
00877 fbuffer_append_str(buffer, tmp);
00878 }
00879
00880 static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00881 {
00882 double value = RFLOAT_VALUE(obj);
00883 char allow_nan = state->allow_nan;
00884 VALUE tmp = rb_funcall(obj, i_to_s, 0);
00885 if (!allow_nan) {
00886 if (isinf(value)) {
00887 fbuffer_free(buffer);
00888 rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp));
00889 } else if (isnan(value)) {
00890 fbuffer_free(buffer);
00891 rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp));
00892 }
00893 }
00894 fbuffer_append_str(buffer, tmp);
00895 }
00896
00897 static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
00898 {
00899 VALUE tmp;
00900 VALUE klass = CLASS_OF(obj);
00901 if (klass == rb_cHash) {
00902 generate_json_object(buffer, Vstate, state, obj);
00903 } else if (klass == rb_cArray) {
00904 generate_json_array(buffer, Vstate, state, obj);
00905 } else if (klass == rb_cString) {
00906 generate_json_string(buffer, Vstate, state, obj);
00907 } else if (obj == Qnil) {
00908 generate_json_null(buffer, Vstate, state, obj);
00909 } else if (obj == Qfalse) {
00910 generate_json_false(buffer, Vstate, state, obj);
00911 } else if (obj == Qtrue) {
00912 generate_json_true(buffer, Vstate, state, obj);
00913 } else if (klass == rb_cFixnum) {
00914 generate_json_fixnum(buffer, Vstate, state, obj);
00915 } else if (klass == rb_cBignum) {
00916 generate_json_bignum(buffer, Vstate, state, obj);
00917 } else if (klass == rb_cFloat) {
00918 generate_json_float(buffer, Vstate, state, obj);
00919 } else if (rb_respond_to(obj, i_to_json)) {
00920 tmp = rb_funcall(obj, i_to_json, 1, Vstate);
00921 Check_Type(tmp, T_STRING);
00922 fbuffer_append_str(buffer, tmp);
00923 } else {
00924 tmp = rb_funcall(obj, i_to_s, 0);
00925 Check_Type(tmp, T_STRING);
00926 generate_json(buffer, Vstate, state, tmp);
00927 }
00928 }
00929
00930 static FBuffer *cState_prepare_buffer(VALUE self)
00931 {
00932 FBuffer *buffer = fbuffer_alloc();
00933 GET_STATE(self);
00934
00935 if (state->object_delim) {
00936 fbuffer_clear(state->object_delim);
00937 } else {
00938 state->object_delim = fbuffer_alloc_with_length(16);
00939 }
00940 fbuffer_append_char(state->object_delim, ',');
00941 if (state->object_delim2) {
00942 fbuffer_clear(state->object_delim2);
00943 } else {
00944 state->object_delim2 = fbuffer_alloc_with_length(16);
00945 }
00946 fbuffer_append_char(state->object_delim2, ':');
00947 if (state->space) fbuffer_append(state->object_delim2, state->space, state->space_len);
00948
00949 if (state->array_delim) {
00950 fbuffer_clear(state->array_delim);
00951 } else {
00952 state->array_delim = fbuffer_alloc_with_length(16);
00953 }
00954 fbuffer_append_char(state->array_delim, ',');
00955 if (state->array_nl) fbuffer_append(state->array_delim, state->array_nl, state->array_nl_len);
00956 return buffer;
00957 }
00958
00959 static VALUE fbuffer_to_s(FBuffer *fb)
00960 {
00961 VALUE result = rb_str_new(FBUFFER_PAIR(fb));
00962 fbuffer_free(fb);
00963 FORCE_UTF8(result);
00964 return result;
00965 }
00966
00967 static VALUE cState_partial_generate(VALUE self, VALUE obj)
00968 {
00969 FBuffer *buffer = cState_prepare_buffer(self);
00970 GET_STATE(self);
00971 generate_json(buffer, self, state, obj);
00972 return fbuffer_to_s(buffer);
00973 }
00974
00975
00976
00977
00978
00979
00980
00981
00982 static VALUE cState_generate(VALUE self, VALUE obj)
00983 {
00984 VALUE result = cState_partial_generate(self, obj);
00985 VALUE re, args[2];
00986 GET_STATE(self);
00987 if (!state->quirks_mode) {
00988 args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
00989 args[1] = CRegexp_MULTILINE;
00990 re = rb_class_new_instance(2, args, rb_cRegexp);
00991 if (NIL_P(rb_funcall(re, i_match, 1, result))) {
00992 rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
00993 }
00994 }
00995 return result;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
01017 {
01018 VALUE opts;
01019 GET_STATE(self);
01020 state->max_nesting = 19;
01021 rb_scan_args(argc, argv, "01", &opts);
01022 if (!NIL_P(opts)) cState_configure(self, opts);
01023 return self;
01024 }
01025
01026
01027
01028
01029
01030
01031
01032 static VALUE cState_init_copy(VALUE obj, VALUE orig)
01033 {
01034 JSON_Generator_State *objState, *origState;
01035
01036 if (obj == orig) return obj;
01037 Data_Get_Struct(obj, JSON_Generator_State, objState);
01038 Data_Get_Struct(orig, JSON_Generator_State, origState);
01039 if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State");
01040
01041 MEMCPY(objState, origState, JSON_Generator_State, 1);
01042 objState->indent = fstrndup(origState->indent, origState->indent_len);
01043 objState->space = fstrndup(origState->space, origState->space_len);
01044 objState->space_before = fstrndup(origState->space_before, origState->space_before_len);
01045 objState->object_nl = fstrndup(origState->object_nl, origState->object_nl_len);
01046 objState->array_nl = fstrndup(origState->array_nl, origState->array_nl_len);
01047 if (origState->array_delim) objState->array_delim = fbuffer_dup(origState->array_delim);
01048 if (origState->object_delim) objState->object_delim = fbuffer_dup(origState->object_delim);
01049 if (origState->object_delim2) objState->object_delim2 = fbuffer_dup(origState->object_delim2);
01050 return obj;
01051 }
01052
01053
01054
01055
01056
01057
01058
01059
01060 static VALUE cState_from_state_s(VALUE self, VALUE opts)
01061 {
01062 if (rb_obj_is_kind_of(opts, self)) {
01063 return opts;
01064 } else if (rb_obj_is_kind_of(opts, rb_cHash)) {
01065 return rb_funcall(self, i_new, 1, opts);
01066 } else {
01067 if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
01068 CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
01069 }
01070 return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
01071 }
01072 }
01073
01074
01075
01076
01077
01078
01079 static VALUE cState_indent(VALUE self)
01080 {
01081 GET_STATE(self);
01082 return state->indent ? rb_str_new2(state->indent) : rb_str_new2("");
01083 }
01084
01085
01086
01087
01088
01089
01090 static VALUE cState_indent_set(VALUE self, VALUE indent)
01091 {
01092 unsigned long len;
01093 GET_STATE(self);
01094 Check_Type(indent, T_STRING);
01095 len = RSTRING_LEN(indent);
01096 if (len == 0) {
01097 if (state->indent) {
01098 ruby_xfree(state->indent);
01099 state->indent = NULL;
01100 state->indent_len = 0;
01101 }
01102 } else {
01103 if (state->indent) ruby_xfree(state->indent);
01104 state->indent = strdup(RSTRING_PTR(indent));
01105 state->indent_len = len;
01106 }
01107 return Qnil;
01108 }
01109
01110
01111
01112
01113
01114
01115
01116 static VALUE cState_space(VALUE self)
01117 {
01118 GET_STATE(self);
01119 return state->space ? rb_str_new2(state->space) : rb_str_new2("");
01120 }
01121
01122
01123
01124
01125
01126
01127
01128 static VALUE cState_space_set(VALUE self, VALUE space)
01129 {
01130 unsigned long len;
01131 GET_STATE(self);
01132 Check_Type(space, T_STRING);
01133 len = RSTRING_LEN(space);
01134 if (len == 0) {
01135 if (state->space) {
01136 ruby_xfree(state->space);
01137 state->space = NULL;
01138 state->space_len = 0;
01139 }
01140 } else {
01141 if (state->space) ruby_xfree(state->space);
01142 state->space = strdup(RSTRING_PTR(space));
01143 state->space_len = len;
01144 }
01145 return Qnil;
01146 }
01147
01148
01149
01150
01151
01152
01153 static VALUE cState_space_before(VALUE self)
01154 {
01155 GET_STATE(self);
01156 return state->space_before ? rb_str_new2(state->space_before) : rb_str_new2("");
01157 }
01158
01159
01160
01161
01162
01163
01164 static VALUE cState_space_before_set(VALUE self, VALUE space_before)
01165 {
01166 unsigned long len;
01167 GET_STATE(self);
01168 Check_Type(space_before, T_STRING);
01169 len = RSTRING_LEN(space_before);
01170 if (len == 0) {
01171 if (state->space_before) {
01172 ruby_xfree(state->space_before);
01173 state->space_before = NULL;
01174 state->space_before_len = 0;
01175 }
01176 } else {
01177 if (state->space_before) ruby_xfree(state->space_before);
01178 state->space_before = strdup(RSTRING_PTR(space_before));
01179 state->space_before_len = len;
01180 }
01181 return Qnil;
01182 }
01183
01184
01185
01186
01187
01188
01189
01190 static VALUE cState_object_nl(VALUE self)
01191 {
01192 GET_STATE(self);
01193 return state->object_nl ? rb_str_new2(state->object_nl) : rb_str_new2("");
01194 }
01195
01196
01197
01198
01199
01200
01201
01202 static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
01203 {
01204 unsigned long len;
01205 GET_STATE(self);
01206 Check_Type(object_nl, T_STRING);
01207 len = RSTRING_LEN(object_nl);
01208 if (len == 0) {
01209 if (state->object_nl) {
01210 ruby_xfree(state->object_nl);
01211 state->object_nl = NULL;
01212 }
01213 } else {
01214 if (state->object_nl) ruby_xfree(state->object_nl);
01215 state->object_nl = strdup(RSTRING_PTR(object_nl));
01216 state->object_nl_len = len;
01217 }
01218 return Qnil;
01219 }
01220
01221
01222
01223
01224
01225
01226 static VALUE cState_array_nl(VALUE self)
01227 {
01228 GET_STATE(self);
01229 return state->array_nl ? rb_str_new2(state->array_nl) : rb_str_new2("");
01230 }
01231
01232
01233
01234
01235
01236
01237 static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
01238 {
01239 unsigned long len;
01240 GET_STATE(self);
01241 Check_Type(array_nl, T_STRING);
01242 len = RSTRING_LEN(array_nl);
01243 if (len == 0) {
01244 if (state->array_nl) {
01245 ruby_xfree(state->array_nl);
01246 state->array_nl = NULL;
01247 }
01248 } else {
01249 if (state->array_nl) ruby_xfree(state->array_nl);
01250 state->array_nl = strdup(RSTRING_PTR(array_nl));
01251 state->array_nl_len = len;
01252 }
01253 return Qnil;
01254 }
01255
01256
01257
01258
01259
01260
01261
01262
01263 static VALUE cState_check_circular_p(VALUE self)
01264 {
01265 GET_STATE(self);
01266 return state->max_nesting ? Qtrue : Qfalse;
01267 }
01268
01269
01270
01271
01272
01273
01274
01275 static VALUE cState_max_nesting(VALUE self)
01276 {
01277 GET_STATE(self);
01278 return LONG2FIX(state->max_nesting);
01279 }
01280
01281
01282
01283
01284
01285
01286
01287 static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
01288 {
01289 GET_STATE(self);
01290 Check_Type(depth, T_FIXNUM);
01291 return state->max_nesting = FIX2LONG(depth);
01292 }
01293
01294
01295
01296
01297
01298
01299
01300 static VALUE cState_allow_nan_p(VALUE self)
01301 {
01302 GET_STATE(self);
01303 return state->allow_nan ? Qtrue : Qfalse;
01304 }
01305
01306
01307
01308
01309
01310
01311
01312 static VALUE cState_ascii_only_p(VALUE self)
01313 {
01314 GET_STATE(self);
01315 return state->ascii_only ? Qtrue : Qfalse;
01316 }
01317
01318
01319
01320
01321
01322
01323 static VALUE cState_quirks_mode_p(VALUE self)
01324 {
01325 GET_STATE(self);
01326 return state->quirks_mode ? Qtrue : Qfalse;
01327 }
01328
01329
01330
01331
01332
01333
01334 static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
01335 {
01336 GET_STATE(self);
01337 state->quirks_mode = RTEST(enable);
01338 return Qnil;
01339 }
01340
01341
01342
01343
01344
01345
01346 static VALUE cState_depth(VALUE self)
01347 {
01348 GET_STATE(self);
01349 return LONG2FIX(state->depth);
01350 }
01351
01352
01353
01354
01355
01356
01357
01358 static VALUE cState_depth_set(VALUE self, VALUE depth)
01359 {
01360 GET_STATE(self);
01361 Check_Type(depth, T_FIXNUM);
01362 return state->depth = FIX2LONG(depth);
01363 }
01364
01365
01366
01367
01368 void Init_generator()
01369 {
01370 rb_require("json/common");
01371
01372 mJSON = rb_define_module("JSON");
01373 mExt = rb_define_module_under(mJSON, "Ext");
01374 mGenerator = rb_define_module_under(mExt, "Generator");
01375
01376 eGeneratorError = rb_path2class("JSON::GeneratorError");
01377 eNestingError = rb_path2class("JSON::NestingError");
01378
01379 cState = rb_define_class_under(mGenerator, "State", rb_cObject);
01380 rb_define_alloc_func(cState, cState_s_allocate);
01381 rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1);
01382 rb_define_method(cState, "initialize", cState_initialize, -1);
01383 rb_define_method(cState, "initialize_copy", cState_init_copy, 1);
01384 rb_define_method(cState, "indent", cState_indent, 0);
01385 rb_define_method(cState, "indent=", cState_indent_set, 1);
01386 rb_define_method(cState, "space", cState_space, 0);
01387 rb_define_method(cState, "space=", cState_space_set, 1);
01388 rb_define_method(cState, "space_before", cState_space_before, 0);
01389 rb_define_method(cState, "space_before=", cState_space_before_set, 1);
01390 rb_define_method(cState, "object_nl", cState_object_nl, 0);
01391 rb_define_method(cState, "object_nl=", cState_object_nl_set, 1);
01392 rb_define_method(cState, "array_nl", cState_array_nl, 0);
01393 rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
01394 rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
01395 rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
01396 rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
01397 rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
01398 rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
01399 rb_define_method(cState, "quirks_mode?", cState_quirks_mode_p, 0);
01400 rb_define_method(cState, "quirks_mode", cState_quirks_mode_p, 0);
01401 rb_define_method(cState, "quirks_mode=", cState_quirks_mode_set, 1);
01402 rb_define_method(cState, "depth", cState_depth, 0);
01403 rb_define_method(cState, "depth=", cState_depth_set, 1);
01404 rb_define_method(cState, "configure", cState_configure, 1);
01405 rb_define_alias(cState, "merge", "configure");
01406 rb_define_method(cState, "to_h", cState_to_h, 0);
01407 rb_define_method(cState, "[]", cState_aref, 1);
01408 rb_define_method(cState, "generate", cState_generate, 1);
01409
01410 mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
01411 mObject = rb_define_module_under(mGeneratorMethods, "Object");
01412 rb_define_method(mObject, "to_json", mObject_to_json, -1);
01413 mHash = rb_define_module_under(mGeneratorMethods, "Hash");
01414 rb_define_method(mHash, "to_json", mHash_to_json, -1);
01415 mArray = rb_define_module_under(mGeneratorMethods, "Array");
01416 rb_define_method(mArray, "to_json", mArray_to_json, -1);
01417 mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
01418 rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
01419 mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
01420 rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
01421 mFloat = rb_define_module_under(mGeneratorMethods, "Float");
01422 rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
01423 mString = rb_define_module_under(mGeneratorMethods, "String");
01424 rb_define_singleton_method(mString, "included", mString_included_s, 1);
01425 rb_define_method(mString, "to_json", mString_to_json, -1);
01426 rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1);
01427 rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0);
01428 mString_Extend = rb_define_module_under(mString, "Extend");
01429 rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1);
01430 mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass");
01431 rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1);
01432 mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass");
01433 rb_define_method(mFalseClass, "to_json", mFalseClass_to_json, -1);
01434 mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
01435 rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
01436
01437 CRegexp_MULTILINE = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
01438 i_to_s = rb_intern("to_s");
01439 i_to_json = rb_intern("to_json");
01440 i_new = rb_intern("new");
01441 i_indent = rb_intern("indent");
01442 i_space = rb_intern("space");
01443 i_space_before = rb_intern("space_before");
01444 i_object_nl = rb_intern("object_nl");
01445 i_array_nl = rb_intern("array_nl");
01446 i_max_nesting = rb_intern("max_nesting");
01447 i_allow_nan = rb_intern("allow_nan");
01448 i_ascii_only = rb_intern("ascii_only");
01449 i_quirks_mode = rb_intern("quirks_mode");
01450 i_depth = rb_intern("depth");
01451 i_pack = rb_intern("pack");
01452 i_unpack = rb_intern("unpack");
01453 i_create_id = rb_intern("create_id");
01454 i_extend = rb_intern("extend");
01455 i_key_p = rb_intern("key?");
01456 i_aref = rb_intern("[]");
01457 i_send = rb_intern("__send__");
01458 i_respond_to_p = rb_intern("respond_to?");
01459 i_match = rb_intern("match");
01460 i_keys = rb_intern("keys");
01461 i_dup = rb_intern("dup");
01462 #ifdef HAVE_RUBY_ENCODING_H
01463 CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
01464 i_encoding = rb_intern("encoding");
01465 i_encode = rb_intern("encode");
01466 #endif
01467 i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
01468 CJSON_SAFE_STATE_PROTOTYPE = Qnil;
01469 }
01470