Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

generator.c
Go to the documentation of this file.
1 #include "../fbuffer/fbuffer.h"
2 #include "generator.h"
3
4 #ifdef HAVE_RUBY_ENCODING_H
5 static VALUE CEncoding_UTF_8;
6 static ID i_encoding, i_encode;
7 #endif
8
9 static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
10 mHash, mArray, mFixnum, mBignum, mFloat, mString, mString_Extend,
11 mTrueClass, mFalseClass, mNilClass, eGeneratorError,
12 eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE,
13 i_SAFE_STATE_PROTOTYPE;
14
15 static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
16 i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
17 i_quirks_mode, i_pack, i_unpack, i_create_id, i_extend, i_key_p,
18 i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
19 i_buffer_initial_length, i_dup;
20
21 /*
22 * Copyright 2001-2004 Unicode, Inc.
23 *
24 * Disclaimer
25 *
26 * This source code is provided as is by Unicode, Inc. No claims are
27 * made as to fitness for any particular purpose. No warranties of any
28 * kind are expressed or implied. The recipient agrees to determine
29 * applicability of information provided. If this file has been
30 * purchased on magnetic or optical media from Unicode, Inc., the
31 * sole remedy for any claim will be exchange of defective media
32 * within 90 days of receipt.
33 *
34 * Limitations on Rights to Redistribute This Code
35 *
36 * Unicode, Inc. hereby grants the right to freely use the information
37 * supplied in this file in the creation of products supporting the
38 * Unicode Standard, and to make copies of this file in any form
39 * for internal or external distribution as long as this notice
40 * remains attached.
41 */
42
43 /*
44 * Index into the table below with the first byte of a UTF-8 sequence to
45 * get the number of trailing bytes that are supposed to follow it.
46 * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
47 * left as-is for anyone who may want to do such conversion, which was
48 * allowed in earlier algorithms.
49 */
50 static const char trailingBytesForUTF8[256] = {
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
59 };
60
61 /*
62 * Magic values subtracted from a buffer value during UTF8 conversion.
63 * This table contains as many values as there might be trailing bytes
64 * in a UTF-8 sequence.
65 */
66 static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
67 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
68
69 /*
70 * Utility routine to tell whether a sequence of bytes is legal UTF-8.
71 * This must be called with the length pre-determined by the first byte.
72 * If not calling this from ConvertUTF8to*, then the length can be set by:
73 * length = trailingBytesForUTF8[*source]+1;
74 * and the sequence is illegal right away if there aren't that many bytes
75 * available.
76 * If presented with a length > 4, this returns 0. The Unicode
77 * definition of UTF-8 goes up to 4-byte sequences.
78 */
79 static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length)
80 {
81 UTF8 a;
82 const UTF8 *srcptr = source+length;
83 switch (length) {
84 default: return 0;
85 /* Everything else falls through when "1"... */
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;
89
90 switch (*source) {
91 /* no fall-through in this inner switch */
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;
97 }
98
99 case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
100 }
101 if (*source > 0xF4) return 0;
102 return 1;
103 }
104
105 /* Escapes the UTF16 character and stores the result in the buffer buf. */
106 static void unicode_escape(char *buf, UTF16 character)
107 {
108 const char *digits = "0123456789abcdef";
109
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];
114 }
115
116 /* Escapes the UTF16 character and stores the result in the buffer buf, then
117 * the buffer buf is appended to the FBuffer buffer. */
118 static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16
119 character)
120 {
121 unicode_escape(buf, character);
122 fbuffer_append(buffer, buf, 6);
123 }
124
125 /* Converts string to a JSON string in FBuffer buffer, where all but the ASCII
126 * and control characters are JSON escaped. */
127 static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
128 {
129 const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
130 const UTF8 *sourceEnd = source + RSTRING_LEN(string);
131 char buf[6] = { '\\', 'u' };
132
133 while (source < sourceEnd) {
134 UTF32 ch = 0;
135 unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
136 if (source + extraBytesToRead >= sourceEnd) {
137 rb_raise(rb_path2class("JSON::GeneratorError"),
138 "partial character in source, but hit end");
139 }
140 if (!isLegalUTF8(source, extraBytesToRead+1)) {
141 rb_raise(rb_path2class("JSON::GeneratorError"),
142 "source sequence is illegal/malformed utf-8");
143 }
144 /*
145 * The cases all fall through. See "Note A" below.
146 */
147 switch (extraBytesToRead) {
148 case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
149 case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
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++;
154 }
155 ch -= offsetsFromUTF8[extraBytesToRead];
156
157 if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
158 /* UTF-16 surrogate values are illegal in UTF-32 */
159 if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
160 #if UNI_STRICT_CONVERSION
161 source -= (extraBytesToRead+1); /* return to the illegal value itself */
162 rb_raise(rb_path2class("JSON::GeneratorError"),
163 "source sequence is illegal/malformed utf-8");
164 #else
165 unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR);
166 #endif
167 } else {
168 /* normal case */
169 if (ch >= 0x20 && ch <= 0x7f) {
170 switch (ch) {
171 case '\\':
172 fbuffer_append(buffer, "\\\\", 2);
173 break;
174 case '"':
175 fbuffer_append(buffer, "\\\"", 2);
176 break;
177 default:
178 fbuffer_append_char(buffer, (char)ch);
179 break;
180 }
181 } else {
182 switch (ch) {
183 case '\n':
184 fbuffer_append(buffer, "\\n", 2);
185 break;
186 case '\r':
187 fbuffer_append(buffer, "\\r", 2);
188 break;
189 case '\t':
190 fbuffer_append(buffer, "\\t", 2);
191 break;
192 case '\f':
193 fbuffer_append(buffer, "\\f", 2);
194 break;
195 case '\b':
196 fbuffer_append(buffer, "\\b", 2);
197 break;
198 default:
199 unicode_escape_to_buffer(buffer, buf, (UTF16) ch);
200 break;
201 }
202 }
203 }
204 } else if (ch > UNI_MAX_UTF16) {
205 #if UNI_STRICT_CONVERSION
206 source -= (extraBytesToRead+1); /* return to the start */
207 rb_raise(rb_path2class("JSON::GeneratorError"),
208 "source sequence is illegal/malformed utf8");
209 #else
210 unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR);
211 #endif
212 } else {
213 /* target is a character in range 0xFFFF - 0x10FFFF. */
214 ch -= halfBase;
215 unicode_escape_to_buffer(buffer, buf, (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START));
216 unicode_escape_to_buffer(buffer, buf, (UTF16)((ch & halfMask) + UNI_SUR_LOW_START));
217 }
218 }
219 }
220
221 /* Converts string to a JSON string in FBuffer buffer, where only the
222 * characters required by the JSON standard are JSON escaped. The remaining
223 * characters (should be UTF8) are just passed through and appended to the
224 * result. */
225 static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
226 {
227 const char *ptr = RSTRING_PTR(string), *p;
228 unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
229 const char *escape = NULL;
230 int escape_len;
231 unsigned char c;
232 char buf[6] = { '\\', 'u' };
233
234 for (start = 0, end = 0; end < len;) {
235 p = ptr + end;
236 c = (unsigned char) *p;
237 if (c < 0x20) {
238 switch (c) {
239 case '\n':
240 escape = "\\n";
241 escape_len = 2;
242 break;
243 case '\r':
244 escape = "\\r";
245 escape_len = 2;
246 break;
247 case '\t':
248 escape = "\\t";
249 escape_len = 2;
250 break;
251 case '\f':
252 escape = "\\f";
253 escape_len = 2;
254 break;
255 case '\b':
256 escape = "\\b";
257 escape_len = 2;
258 break;
259 default:
260 unicode_escape(buf, (UTF16) *p);
261 escape = buf;
262 escape_len = 6;
263 break;
264 }
265 } else {
266 switch (c) {
267 case '\\':
268 escape = "\\\\";
269 escape_len = 2;
270 break;
271 case '"':
272 escape = "\\\"";
273 escape_len = 2;
274 break;
275 default:
276 {
277 unsigned short clen = trailingBytesForUTF8[c] + 1;
278 if (end + clen > len) {
279 rb_raise(rb_path2class("JSON::GeneratorError"),
280 "partial character in source, but hit end");
281 }
282 if (!isLegalUTF8((UTF8 *) p, clen)) {
283 rb_raise(rb_path2class("JSON::GeneratorError"),
284 "source sequence is illegal/malformed utf-8");
285 }
286 end += clen;
287 }
288 continue;
289 break;
290 }
291 }
292 fbuffer_append(buffer, ptr + start, end - start);
293 fbuffer_append(buffer, escape, escape_len);
294 start = ++end;
295 escape = NULL;
296 }
297 fbuffer_append(buffer, ptr + start, end - start);
298 }
299
300 static char *fstrndup(const char *ptr, unsigned long len) {
301 char *result;
302 if (len <= 0) return NULL;
303 result = ALLOC_N(char, len);
304 memccpy(result, ptr, 0, len);
305 return result;
306 }
307
308 /*
309 * Document-module: JSON::Ext::Generator
310 *
311 * This is the JSON generator implemented as a C extension. It can be
312 * configured to be used by setting
313 *
314 * JSON.generator = JSON::Ext::Generator
315 *
316 * with the method generator= in JSON.
317 *
318 */
319
320 /*
321 * call-seq: to_json(state = nil)
322 *
323 * Returns a JSON string containing a JSON object, that is generated from
324 * this Hash instance.
325 * _state_ is a JSON::State object, that can also be used to configure the
326 * produced JSON string output further.
327 */
328 static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
329 {
330 GENERATE_JSON(object);
331 }
332
333 /*
334 * call-seq: to_json(state = nil)
335 *
336 * Returns a JSON string containing a JSON array, that is generated from
337 * this Array instance.
338 * _state_ is a JSON::State object, that can also be used to configure the
339 * produced JSON string output further.
340 */
341 static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
342 GENERATE_JSON(array);
343 }
344
345 /*
346 * call-seq: to_json(*)
347 *
348 * Returns a JSON string representation for this Integer number.
349 */
350 static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
351 {
352 GENERATE_JSON(fixnum);
353 }
354
355 /*
356 * call-seq: to_json(*)
357 *
358 * Returns a JSON string representation for this Integer number.
359 */
360 static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
361 {
362 GENERATE_JSON(bignum);
363 }
364
365 /*
366 * call-seq: to_json(*)
367 *
368 * Returns a JSON string representation for this Float number.
369 */
370 static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
371 {
372 GENERATE_JSON(float);
373 }
374
375 /*
376 * call-seq: String.included(modul)
377 *
378 * Extends _modul_ with the String::Extend module.
379 */
380 static VALUE mString_included_s(VALUE self, VALUE modul) {
381 VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
382 return result;
383 }
384
385 /*
386 * call-seq: to_json(*)
387 *
388 * This string should be encoded with UTF-8 A call to this method
389 * returns a JSON string encoded with UTF16 big endian characters as
390 * \u????.
391 */
392 static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
393 {
394 GENERATE_JSON(string);
395 }
396
397 /*
398 * call-seq: to_json_raw_object()
399 *
400 * This method creates a raw object hash, that can be nested into
401 * other data structures and will be generated as a raw string. This
402 * method should be used, if you want to convert raw strings to JSON
403 * instead of UTF-8 strings, e. g. binary data.
404 */
405 static VALUE mString_to_json_raw_object(VALUE self)
406 {
407 VALUE ary;
408 VALUE result = rb_hash_new();
409 rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self)));
410 ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*"));
411 rb_hash_aset(result, rb_str_new2("raw"), ary);
412 return result;
413 }
414
415 /*
416 * call-seq: to_json_raw(*args)
417 *
418 * This method creates a JSON text from the result of a call to
419 * to_json_raw_object of this String.
420 */
421 static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
422 {
423 VALUE obj = mString_to_json_raw_object(self);
424 Check_Type(obj, T_HASH);
425 return mHash_to_json(argc, argv, obj);
426 }
427
428 /*
429 * call-seq: json_create(o)
430 *
431 * Raw Strings are JSON Objects (the raw bytes are stored in an array for the
432 * key "raw"). The Ruby String can be created by this module method.
433 */
434 static VALUE mString_Extend_json_create(VALUE self, VALUE o)
435 {
436 VALUE ary;
437 Check_Type(o, T_HASH);
438 ary = rb_hash_aref(o, rb_str_new2("raw"));
439 return rb_funcall(ary, i_pack, 1, rb_str_new2("C*"));
440 }
441
442 /*
443 * call-seq: to_json(*)
444 *
445 * Returns a JSON string for true: 'true'.
446 */
447 static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
448 {
449 GENERATE_JSON(true);
450 }
451
452 /*
453 * call-seq: to_json(*)
454 *
455 * Returns a JSON string for false: 'false'.
456 */
457 static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
458 {
459 GENERATE_JSON(false);
460 }
461
462 /*
463 * call-seq: to_json(*)
464 *
465 * Returns a JSON string for nil: 'null'.
466 */
467 static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
468 {
469 GENERATE_JSON(null);
470 }
471
472 /*
473 * call-seq: to_json(*)
474 *
475 * Converts this object to a string (calling #to_s), converts
476 * it to a JSON string, and returns the result. This is a fallback, if no
477 * special method #to_json was defined for some object.
478 */
479 static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
480 {
481 VALUE state;
482 VALUE string = rb_funcall(self, i_to_s, 0);
483 rb_scan_args(argc, argv, "01", &state);
484 Check_Type(string, T_STRING);
485 state = cState_from_state_s(cState, state);
486 return cState_partial_generate(state, string);
487 }
488
489 static void State_free(JSON_Generator_State *state)
490 {
491 if (state->indent) ruby_xfree(state->indent);
492 if (state->space) ruby_xfree(state->space);
493 if (state->space_before) ruby_xfree(state->space_before);
494 if (state->object_nl) ruby_xfree(state->object_nl);
495 if (state->array_nl) ruby_xfree(state->array_nl);
496 if (state->array_delim) fbuffer_free(state->array_delim);
497 if (state->object_delim) fbuffer_free(state->object_delim);
498 if (state->object_delim2) fbuffer_free(state->object_delim2);
499 ruby_xfree(state);
500 }
501
502 static JSON_Generator_State *State_allocate()
503 {
504 JSON_Generator_State *state = ALLOC(JSON_Generator_State);
505 MEMZERO(state, JSON_Generator_State, 1);
506 return state;
507 }
508
509 static VALUE cState_s_allocate(VALUE klass)
510 {
511 JSON_Generator_State *state = State_allocate();
512 return Data_Wrap_Struct(klass, NULL, State_free, state);
513 }
514
515 /*
516 * call-seq: configure(opts)
517 *
518 * Configure this State instance with the Hash _opts_, and return
519 * itself.
520 */
521 static VALUE cState_configure(VALUE self, VALUE opts)
522 {
523 VALUE tmp;
524 GET_STATE(self);
525 tmp = rb_check_convert_type(opts, T_HASH, "Hash", "to_hash");
526 if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
527 opts = tmp;
528 tmp = rb_hash_aref(opts, ID2SYM(i_indent));
529 if (RTEST(tmp)) {
530 unsigned long len;
531 Check_Type(tmp, T_STRING);
532 len = RSTRING_LEN(tmp);
533 state->indent = fstrndup(RSTRING_PTR(tmp), len + 1);
534 state->indent_len = len;
535 }
536 tmp = rb_hash_aref(opts, ID2SYM(i_space));
537 if (RTEST(tmp)) {
538 unsigned long len;
539 Check_Type(tmp, T_STRING);
540 len = RSTRING_LEN(tmp);
541 state->space = fstrndup(RSTRING_PTR(tmp), len + 1);
542 state->space_len = len;
543 }
544 tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
545 if (RTEST(tmp)) {
546 unsigned long len;
547 Check_Type(tmp, T_STRING);
548 len = RSTRING_LEN(tmp);
549 state->space_before = fstrndup(RSTRING_PTR(tmp), len + 1);
550 state->space_before_len = len;
551 }
552 tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
553 if (RTEST(tmp)) {
554 unsigned long len;
555 Check_Type(tmp, T_STRING);
556 len = RSTRING_LEN(tmp);
557 state->array_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
558 state->array_nl_len = len;
559 }
560 tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
561 if (RTEST(tmp)) {
562 unsigned long len;
563 Check_Type(tmp, T_STRING);
564 len = RSTRING_LEN(tmp);
565 state->object_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
566 state->object_nl_len = len;
567 }
568 tmp = ID2SYM(i_max_nesting);
569 state->max_nesting = 100;
570 if (option_given_p(opts, tmp)) {
571 VALUE max_nesting = rb_hash_aref(opts, tmp);
572 if (RTEST(max_nesting)) {
573 Check_Type(max_nesting, T_FIXNUM);
574 state->max_nesting = FIX2LONG(max_nesting);
575 } else {
576 state->max_nesting = 0;
577 }
578 }
579 tmp = ID2SYM(i_depth);
580 state->depth = 0;
581 if (option_given_p(opts, tmp)) {
582 VALUE depth = rb_hash_aref(opts, tmp);
583 if (RTEST(depth)) {
584 Check_Type(depth, T_FIXNUM);
585 state->depth = FIX2LONG(depth);
586 } else {
587 state->depth = 0;
588 }
589 }
590 tmp = ID2SYM(i_buffer_initial_length);
591 if (option_given_p(opts, tmp)) {
592 VALUE buffer_initial_length = rb_hash_aref(opts, tmp);
593 if (RTEST(buffer_initial_length)) {
594 long initial_length;
595 Check_Type(buffer_initial_length, T_FIXNUM);
596 initial_length = FIX2LONG(buffer_initial_length);
597 if (initial_length > 0) state->buffer_initial_length = initial_length;
598 }
599 }
600 tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
601 state->allow_nan = RTEST(tmp);
602 tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
603 state->ascii_only = RTEST(tmp);
604 tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode));
605 state->quirks_mode = RTEST(tmp);
606 return self;
607 }
608
609 static void set_state_ivars(VALUE hash, VALUE state)
610 {
611 VALUE ivars = rb_obj_instance_variables(state);
612 int i = 0;
613 for (i = 0; i < RARRAY_LEN(ivars); i++) {
614 VALUE key = rb_funcall(rb_ary_entry(ivars, i), i_to_s, 0);
615 long key_len = RSTRING_LEN(key);
616 VALUE value = rb_iv_get(state, StringValueCStr(key));
617 rb_hash_aset(hash, rb_str_intern(rb_str_substr(key, 1, key_len - 1)), value);
618 }
619 }
620
621 /*
622 * call-seq: to_h
623 *
624 * Returns the configuration instance variables as a hash, that can be
625 * passed to the configure method.
626 */
627 static VALUE cState_to_h(VALUE self)
628 {
629 VALUE result = rb_hash_new();
630 GET_STATE(self);
631 set_state_ivars(result, self);
632 rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len));
633 rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len));
634 rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len));
635 rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new(state->object_nl, state->object_nl_len));
636 rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
637 rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
638 rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
639 rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse);
640 rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
641 rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
642 rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
643 return result;
644 }
645
646 /*
647 * call-seq: [](name)
648 *
649 * Return the value returned by method +name+.
650 */
651 static VALUE cState_aref(VALUE self, VALUE name)
652 {
653 name = rb_funcall(name, i_to_s, 0);
654 if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
655 return rb_funcall(self, i_send, 1, name);
656 } else {
657 return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
658 }
659 }
660
661 /*
662 * call-seq: []=(name, value)
663 *
664 * Set the attribute name to value.
665 */
666 static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
667 {
668 VALUE name_writer;
669
670 name = rb_funcall(name, i_to_s, 0);
671 name_writer = rb_str_cat2(rb_str_dup(name), "=");
672 if (RTEST(rb_funcall(self, i_respond_to_p, 1, name_writer))) {
673 return rb_funcall(self, i_send, 2, name_writer, value);
674 } else {
675 rb_ivar_set(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)), value);
676 }
677 return Qnil;
678 }
679
680 static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
681 {
682 char *object_nl = state->object_nl;
683 long object_nl_len = state->object_nl_len;
684 char *indent = state->indent;
685 long indent_len = state->indent_len;
686 long max_nesting = state->max_nesting;
687 char *delim = FBUFFER_PTR(state->object_delim);
688 long delim_len = FBUFFER_LEN(state->object_delim);
689 char *delim2 = FBUFFER_PTR(state->object_delim2);
690 long delim2_len = FBUFFER_LEN(state->object_delim2);
691 long depth = ++state->depth;
692 int i, j;
693 VALUE key, key_to_s, keys;
694 if (max_nesting != 0 && depth > max_nesting) {
695 fbuffer_free(buffer);
696 rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
697 }
698 fbuffer_append_char(buffer, '{');
699 keys = rb_funcall(obj, i_keys, 0);
700 for(i = 0; i < RARRAY_LEN(keys); i++) {
701 if (i > 0) fbuffer_append(buffer, delim, delim_len);
702 if (object_nl) {
703 fbuffer_append(buffer, object_nl, object_nl_len);
704 }
705 if (indent) {
706 for (j = 0; j < depth; j++) {
707 fbuffer_append(buffer, indent, indent_len);
708 }
709 }
710 key = rb_ary_entry(keys, i);
711 key_to_s = rb_funcall(key, i_to_s, 0);
712 Check_Type(key_to_s, T_STRING);
713 generate_json(buffer, Vstate, state, key_to_s);
714 fbuffer_append(buffer, delim2, delim2_len);
715 generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
716 }
717 depth = --state->depth;
718 if (object_nl) {
719 fbuffer_append(buffer, object_nl, object_nl_len);
720 if (indent) {
721 for (j = 0; j < depth; j++) {
722 fbuffer_append(buffer, indent, indent_len);
723 }
724 }
725 }
726 fbuffer_append_char(buffer, '}');
727 }
728
729 static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
730 {
731 char *array_nl = state->array_nl;
732 long array_nl_len = state->array_nl_len;
733 char *indent = state->indent;
734 long indent_len = state->indent_len;
735 long max_nesting = state->max_nesting;
736 char *delim = FBUFFER_PTR(state->array_delim);
737 long delim_len = FBUFFER_LEN(state->array_delim);
738 long depth = ++state->depth;
739 int i, j;
740 if (max_nesting != 0 && depth > max_nesting) {
741 fbuffer_free(buffer);
742 rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
743 }
744 fbuffer_append_char(buffer, '[');
745 if (array_nl) fbuffer_append(buffer, array_nl, array_nl_len);
746 for(i = 0; i < RARRAY_LEN(obj); i++) {
747 if (i > 0) fbuffer_append(buffer, delim, delim_len);
748 if (indent) {
749 for (j = 0; j < depth; j++) {
750 fbuffer_append(buffer, indent, indent_len);
751 }
752 }
753 generate_json(buffer, Vstate, state, rb_ary_entry(obj, i));
754 }
755 state->depth = --depth;
756 if (array_nl) {
757 fbuffer_append(buffer, array_nl, array_nl_len);
758 if (indent) {
759 for (j = 0; j < depth; j++) {
760 fbuffer_append(buffer, indent, indent_len);
761 }
762 }
763 }
764 fbuffer_append_char(buffer, ']');
765 }
766
767 static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
768 {
769 fbuffer_append_char(buffer, '"');
770 #ifdef HAVE_RUBY_ENCODING_H
771 obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
772 #endif
773 if (state->ascii_only) {
774 convert_UTF8_to_JSON_ASCII(buffer, obj);
775 } else {
776 convert_UTF8_to_JSON(buffer, obj);
777 }
778 fbuffer_append_char(buffer, '"');
779 }
780
781 static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
782 {
783 fbuffer_append(buffer, "null", 4);
784 }
785
786 static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
787 {
788 fbuffer_append(buffer, "false", 5);
789 }
790
791 static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
792 {
793 fbuffer_append(buffer, "true", 4);
794 }
795
796 static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
797 {
798 fbuffer_append_long(buffer, FIX2LONG(obj));
799 }
800
801 static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
802 {
803 VALUE tmp = rb_funcall(obj, i_to_s, 0);
804 fbuffer_append_str(buffer, tmp);
805 }
806
807 static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
808 {
809 double value = RFLOAT_VALUE(obj);
810 char allow_nan = state->allow_nan;
811 VALUE tmp = rb_funcall(obj, i_to_s, 0);
812 if (!allow_nan) {
813 if (isinf(value)) {
814 fbuffer_free(buffer);
815 rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
816 } else if (isnan(value)) {
817 fbuffer_free(buffer);
818 rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
819 }
820 }
821 fbuffer_append_str(buffer, tmp);
822 }
823
824 static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
825 {
826 VALUE tmp;
827 VALUE klass = CLASS_OF(obj);
828 if (klass == rb_cHash) {
829 generate_json_object(buffer, Vstate, state, obj);
830 } else if (klass == rb_cArray) {
831 generate_json_array(buffer, Vstate, state, obj);
832 } else if (klass == rb_cString) {
833 generate_json_string(buffer, Vstate, state, obj);
834 } else if (obj == Qnil) {
835 generate_json_null(buffer, Vstate, state, obj);
836 } else if (obj == Qfalse) {
837 generate_json_false(buffer, Vstate, state, obj);
838 } else if (obj == Qtrue) {
839 generate_json_true(buffer, Vstate, state, obj);
840 } else if (klass == rb_cFixnum) {
841 generate_json_fixnum(buffer, Vstate, state, obj);
842 } else if (klass == rb_cBignum) {
843 generate_json_bignum(buffer, Vstate, state, obj);
844 } else if (klass == rb_cFloat) {
845 generate_json_float(buffer, Vstate, state, obj);
846 } else if (rb_respond_to(obj, i_to_json)) {
847 tmp = rb_funcall(obj, i_to_json, 1, Vstate);
848 Check_Type(tmp, T_STRING);
849 fbuffer_append_str(buffer, tmp);
850 } else {
851 tmp = rb_funcall(obj, i_to_s, 0);
852 Check_Type(tmp, T_STRING);
853 generate_json(buffer, Vstate, state, tmp);
854 }
855 }
856
857 static FBuffer *cState_prepare_buffer(VALUE self)
858 {
859 FBuffer *buffer;
860 GET_STATE(self);
861 buffer = fbuffer_alloc(state->buffer_initial_length);
862
863 if (state->object_delim) {
864 fbuffer_clear(state->object_delim);
865 } else {
866 state->object_delim = fbuffer_alloc(16);
867 }
868 fbuffer_append_char(state->object_delim, ',');
869 if (state->object_delim2) {
870 fbuffer_clear(state->object_delim2);
871 } else {
872 state->object_delim2 = fbuffer_alloc(16);
873 }
874 fbuffer_append_char(state->object_delim2, ':');
875 if (state->space) fbuffer_append(state->object_delim2, state->space, state->space_len);
876
877 if (state->array_delim) {
878 fbuffer_clear(state->array_delim);
879 } else {
880 state->array_delim = fbuffer_alloc(16);
881 }
882 fbuffer_append_char(state->array_delim, ',');
883 if (state->array_nl) fbuffer_append(state->array_delim, state->array_nl, state->array_nl_len);
884 return buffer;
885 }
886
887 static VALUE cState_partial_generate(VALUE self, VALUE obj)
888 {
889 FBuffer *buffer = cState_prepare_buffer(self);
890 GET_STATE(self);
891 generate_json(buffer, self, state, obj);
892 return fbuffer_to_s(buffer);
893 }
894
895 /*
896 * This function returns true if string is either a JSON array or JSON object.
897 * It might suffer from false positives, e. g. syntactically incorrect JSON in
898 * the string or certain UTF-8 characters on the right hand side.
899 */
900 static int isArrayOrObject(VALUE string)
901 {
902 long string_len = RSTRING_LEN(string);
903 char *p = RSTRING_PTR(string), *q = p + string_len - 1;
904 if (string_len < 2) return 0;
905 for (; p < q && isspace((unsigned char)*p); p++);
906 for (; q > p && isspace((unsigned char)*q); q--);
907 return (*p == '[' && *q == ']') || (*p == '{' && *q == '}');
908 }
909
910 /*
911 * call-seq: generate(obj)
912 *
913 * Generates a valid JSON document from object +obj+ and returns the
914 * result. If no valid JSON document can be created this method raises a
915 * GeneratorError exception.
916 */
917 static VALUE cState_generate(VALUE self, VALUE obj)
918 {
919 VALUE result = cState_partial_generate(self, obj);
920 GET_STATE(self);
921 if (!state->quirks_mode && !isArrayOrObject(result)) {
922 rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
923 }
924 return result;
925 }
926
927 /*
928 * call-seq: new(opts = {})
929 *
930 * Instantiates a new State object, configured by _opts_.
931 *
932 * _opts_ can have the following keys:
933 *
934 * * *indent*: a string used to indent levels (default: ''),
935 * * *space*: a string that is put after, a : or , delimiter (default: ''),
936 * * *space_before*: a string that is put before a : pair delimiter (default: ''),
937 * * *object_nl*: a string that is put at the end of a JSON object (default: ''),
938 * * *array_nl*: a string that is put at the end of a JSON array (default: ''),
939 * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
940 * generated, otherwise an exception is thrown, if these values are
941 * encountered. This options defaults to false.
942 * * *quirks_mode*: Enables quirks_mode for parser, that is for example
943 * generating single JSON values instead of documents is possible.
944 * * *buffer_initial_length*: sets the initial length of the generator's
945 * internal buffer.
946 */
947 static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
948 {
949 VALUE opts;
950 GET_STATE(self);
951 state->max_nesting = 100;
952 state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
953 rb_scan_args(argc, argv, "01", &opts);
954 if (!NIL_P(opts)) cState_configure(self, opts);
955 return self;
956 }
957
958 /*
959 * call-seq: initialize_copy(orig)
960 *
961 * Initializes this object from orig if it to be duplicated/cloned and returns
962 * it.
963 */
964 static VALUE cState_init_copy(VALUE obj, VALUE orig)
965 {
966 JSON_Generator_State *objState, *origState;
967
968 if (obj == orig) return obj;
969 Data_Get_Struct(obj, JSON_Generator_State, objState);
970 Data_Get_Struct(orig, JSON_Generator_State, origState);
971 if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State");
972
973 MEMCPY(objState, origState, JSON_Generator_State, 1);
974 objState->indent = fstrndup(origState->indent, origState->indent_len);
975 objState->space = fstrndup(origState->space, origState->space_len);
976 objState->space_before = fstrndup(origState->space_before, origState->space_before_len);
977 objState->object_nl = fstrndup(origState->object_nl, origState->object_nl_len);
978 objState->array_nl = fstrndup(origState->array_nl, origState->array_nl_len);
979 if (origState->array_delim) objState->array_delim = fbuffer_dup(origState->array_delim);
980 if (origState->object_delim) objState->object_delim = fbuffer_dup(origState->object_delim);
981 if (origState->object_delim2) objState->object_delim2 = fbuffer_dup(origState->object_delim2);
982 return obj;
983 }
984
985 /*
986 * call-seq: from_state(opts)
987 *
988 * Creates a State object from _opts_, which ought to be Hash to create a
989 * new State instance configured by _opts_, something else to create an
990 * unconfigured instance. If _opts_ is a State object, it is just returned.
991 */
992 static VALUE cState_from_state_s(VALUE self, VALUE opts)
993 {
994 if (rb_obj_is_kind_of(opts, self)) {
995 return opts;
996 } else if (rb_obj_is_kind_of(opts, rb_cHash)) {
997 return rb_funcall(self, i_new, 1, opts);
998 } else {
999 if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
1000 CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
1001 }
1002 return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
1003 }
1004 }
1005
1006 /*
1007 * call-seq: indent()
1008 *
1009 * This string is used to indent levels in the JSON text.
1010 */
1011 static VALUE cState_indent(VALUE self)
1012 {
1013 GET_STATE(self);
1014 return state->indent ? rb_str_new(state->indent, state->indent_len) : rb_str_new2("");
1015 }
1016
1017 /*
1018 * call-seq: indent=(indent)
1019 *
1020 * This string is used to indent levels in the JSON text.
1021 */
1022 static VALUE cState_indent_set(VALUE self, VALUE indent)
1023 {
1024 unsigned long len;
1025 GET_STATE(self);
1026 Check_Type(indent, T_STRING);
1027 len = RSTRING_LEN(indent);
1028 if (len == 0) {
1029 if (state->indent) {
1030 ruby_xfree(state->indent);
1031 state->indent = NULL;
1032 state->indent_len = 0;
1033 }
1034 } else {
1035 if (state->indent) ruby_xfree(state->indent);
1036 state->indent = strdup(RSTRING_PTR(indent));
1037 state->indent_len = len;
1038 }
1039 return Qnil;
1040 }
1041
1042 /*
1043 * call-seq: space()
1044 *
1045 * This string is used to insert a space between the tokens in a JSON
1046 * string.
1047 */
1048 static VALUE cState_space(VALUE self)
1049 {
1050 GET_STATE(self);
1051 return state->space ? rb_str_new(state->space, state->space_len) : rb_str_new2("");
1052 }
1053
1054 /*
1055 * call-seq: space=(space)
1056 *
1057 * This string is used to insert a space between the tokens in a JSON
1058 * string.
1059 */
1060 static VALUE cState_space_set(VALUE self, VALUE space)
1061 {
1062 unsigned long len;
1063 GET_STATE(self);
1064 Check_Type(space, T_STRING);
1065 len = RSTRING_LEN(space);
1066 if (len == 0) {
1067 if (state->space) {
1068 ruby_xfree(state->space);
1069 state->space = NULL;
1070 state->space_len = 0;
1071 }
1072 } else {
1073 if (state->space) ruby_xfree(state->space);
1074 state->space = strdup(RSTRING_PTR(space));
1075 state->space_len = len;
1076 }
1077 return Qnil;
1078 }
1079
1080 /*
1081 * call-seq: space_before()
1082 *
1083 * This string is used to insert a space before the ':' in JSON objects.
1084 */
1085 static VALUE cState_space_before(VALUE self)
1086 {
1087 GET_STATE(self);
1088 return state->space_before ? rb_str_new(state->space_before, state->space_before_len) : rb_str_new2("");
1089 }
1090
1091 /*
1092 * call-seq: space_before=(space_before)
1093 *
1094 * This string is used to insert a space before the ':' in JSON objects.
1095 */
1096 static VALUE cState_space_before_set(VALUE self, VALUE space_before)
1097 {
1098 unsigned long len;
1099 GET_STATE(self);
1100 Check_Type(space_before, T_STRING);
1101 len = RSTRING_LEN(space_before);
1102 if (len == 0) {
1103 if (state->space_before) {
1104 ruby_xfree(state->space_before);
1105 state->space_before = NULL;
1106 state->space_before_len = 0;
1107 }
1108 } else {
1109 if (state->space_before) ruby_xfree(state->space_before);
1110 state->space_before = strdup(RSTRING_PTR(space_before));
1111 state->space_before_len = len;
1112 }
1113 return Qnil;
1114 }
1115
1116 /*
1117 * call-seq: object_nl()
1118 *
1119 * This string is put at the end of a line that holds a JSON object (or
1120 * Hash).
1121 */
1122 static VALUE cState_object_nl(VALUE self)
1123 {
1124 GET_STATE(self);
1125 return state->object_nl ? rb_str_new(state->object_nl, state->object_nl_len) : rb_str_new2("");
1126 }
1127
1128 /*
1129 * call-seq: object_nl=(object_nl)
1130 *
1131 * This string is put at the end of a line that holds a JSON object (or
1132 * Hash).
1133 */
1134 static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1135 {
1136 unsigned long len;
1137 GET_STATE(self);
1138 Check_Type(object_nl, T_STRING);
1139 len = RSTRING_LEN(object_nl);
1140 if (len == 0) {
1141 if (state->object_nl) {
1142 ruby_xfree(state->object_nl);
1143 state->object_nl = NULL;
1144 }
1145 } else {
1146 if (state->object_nl) ruby_xfree(state->object_nl);
1147 state->object_nl = strdup(RSTRING_PTR(object_nl));
1148 state->object_nl_len = len;
1149 }
1150 return Qnil;
1151 }
1152
1153 /*
1154 * call-seq: array_nl()
1155 *
1156 * This string is put at the end of a line that holds a JSON array.
1157 */
1158 static VALUE cState_array_nl(VALUE self)
1159 {
1160 GET_STATE(self);
1161 return state->array_nl ? rb_str_new(state->array_nl, state->array_nl_len) : rb_str_new2("");
1162 }
1163
1164 /*
1165 * call-seq: array_nl=(array_nl)
1166 *
1167 * This string is put at the end of a line that holds a JSON array.
1168 */
1169 static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1170 {
1171 unsigned long len;
1172 GET_STATE(self);
1173 Check_Type(array_nl, T_STRING);
1174 len = RSTRING_LEN(array_nl);
1175 if (len == 0) {
1176 if (state->array_nl) {
1177 ruby_xfree(state->array_nl);
1178 state->array_nl = NULL;
1179 }
1180 } else {
1181 if (state->array_nl) ruby_xfree(state->array_nl);
1182 state->array_nl = strdup(RSTRING_PTR(array_nl));
1183 state->array_nl_len = len;
1184 }
1185 return Qnil;
1186 }
1187
1188
1189 /*
1190 * call-seq: check_circular?
1191 *
1192 * Returns true, if circular data structures should be checked,
1193 * otherwise returns false.
1194 */
1195 static VALUE cState_check_circular_p(VALUE self)
1196 {
1197 GET_STATE(self);
1198 return state->max_nesting ? Qtrue : Qfalse;
1199 }
1200
1201 /*
1202 * call-seq: max_nesting
1203 *
1204 * This integer returns the maximum level of data structure nesting in
1205 * the generated JSON, max_nesting = 0 if no maximum is checked.
1206 */
1207 static VALUE cState_max_nesting(VALUE self)
1208 {
1209 GET_STATE(self);
1210 return LONG2FIX(state->max_nesting);
1211 }
1212
1213 /*
1214 * call-seq: max_nesting=(depth)
1215 *
1216 * This sets the maximum level of data structure nesting in the generated JSON
1217 * to the integer depth, max_nesting = 0 if no maximum should be checked.
1218 */
1219 static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
1220 {
1221 GET_STATE(self);
1222 Check_Type(depth, T_FIXNUM);
1223 return state->max_nesting = FIX2LONG(depth);
1224 }
1225
1226 /*
1227 * call-seq: allow_nan?
1228 *
1229 * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
1230 * returns false.
1231 */
1232 static VALUE cState_allow_nan_p(VALUE self)
1233 {
1234 GET_STATE(self);
1235 return state->allow_nan ? Qtrue : Qfalse;
1236 }
1237
1238 /*
1239 * call-seq: ascii_only?
1240 *
1241 * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
1242 * returns false.
1243 */
1244 static VALUE cState_ascii_only_p(VALUE self)
1245 {
1246 GET_STATE(self);
1247 return state->ascii_only ? Qtrue : Qfalse;
1248 }
1249
1250 /*
1251 * call-seq: quirks_mode?
1252 *
1253 * Returns true, if quirks mode is enabled. Otherwise returns false.
1254 */
1255 static VALUE cState_quirks_mode_p(VALUE self)
1256 {
1257 GET_STATE(self);
1258 return state->quirks_mode ? Qtrue : Qfalse;
1259 }
1260
1261 /*
1262 * call-seq: quirks_mode=(enable)
1263 *
1264 * If set to true, enables the quirks_mode mode.
1265 */
1266 static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
1267 {
1268 GET_STATE(self);
1269 state->quirks_mode = RTEST(enable);
1270 return Qnil;
1271 }
1272
1273 /*
1274 * call-seq: depth
1275 *
1276 * This integer returns the current depth of data structure nesting.
1277 */
1278 static VALUE cState_depth(VALUE self)
1279 {
1280 GET_STATE(self);
1281 return LONG2FIX(state->depth);
1282 }
1283
1284 /*
1285 * call-seq: depth=(depth)
1286 *
1287 * This sets the maximum level of data structure nesting in the generated JSON
1288 * to the integer depth, max_nesting = 0 if no maximum should be checked.
1289 */
1290 static VALUE cState_depth_set(VALUE self, VALUE depth)
1291 {
1292 GET_STATE(self);
1293 Check_Type(depth, T_FIXNUM);
1294 state->depth = FIX2LONG(depth);
1295 return Qnil;
1296 }
1297
1298 /*
1299 * call-seq: buffer_initial_length
1300 *
1301 * This integer returns the current inital length of the buffer.
1302 */
1303 static VALUE cState_buffer_initial_length(VALUE self)
1304 {
1305 GET_STATE(self);
1306 return LONG2FIX(state->buffer_initial_length);
1307 }
1308
1309 /*
1310 * call-seq: buffer_initial_length=(length)
1311 *
1312 * This sets the initial length of the buffer to +length+, if +length+ > 0,
1313 * otherwise its value isn't changed.
1314 */
1315 static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length)
1316 {
1317 long initial_length;
1318 GET_STATE(self);
1319 Check_Type(buffer_initial_length, T_FIXNUM);
1320 initial_length = FIX2LONG(buffer_initial_length);
1321 if (initial_length > 0) {
1322 state->buffer_initial_length = initial_length;
1323 }
1324 return Qnil;
1325 }
1326
1327 /*
1328 *
1329 */
1330 void Init_generator()
1331 {
1332 rb_require("json/common");
1333
1334 mJSON = rb_define_module("JSON");
1335 mExt = rb_define_module_under(mJSON, "Ext");
1336 mGenerator = rb_define_module_under(mExt, "Generator");
1337
1338 eGeneratorError = rb_path2class("JSON::GeneratorError");
1339 eNestingError = rb_path2class("JSON::NestingError");
1340
1341 cState = rb_define_class_under(mGenerator, "State", rb_cObject);
1342 rb_define_alloc_func(cState, cState_s_allocate);
1343 rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1);
1344 rb_define_method(cState, "initialize", cState_initialize, -1);
1345 rb_define_method(cState, "initialize_copy", cState_init_copy, 1);
1346 rb_define_method(cState, "indent", cState_indent, 0);
1347 rb_define_method(cState, "indent=", cState_indent_set, 1);
1348 rb_define_method(cState, "space", cState_space, 0);
1349 rb_define_method(cState, "space=", cState_space_set, 1);
1350 rb_define_method(cState, "space_before", cState_space_before, 0);
1351 rb_define_method(cState, "space_before=", cState_space_before_set, 1);
1352 rb_define_method(cState, "object_nl", cState_object_nl, 0);
1353 rb_define_method(cState, "object_nl=", cState_object_nl_set, 1);
1354 rb_define_method(cState, "array_nl", cState_array_nl, 0);
1355 rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
1356 rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
1357 rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
1358 rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
1359 rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
1360 rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
1361 rb_define_method(cState, "quirks_mode?", cState_quirks_mode_p, 0);
1362 rb_define_method(cState, "quirks_mode", cState_quirks_mode_p, 0);
1363 rb_define_method(cState, "quirks_mode=", cState_quirks_mode_set, 1);
1364 rb_define_method(cState, "depth", cState_depth, 0);
1365 rb_define_method(cState, "depth=", cState_depth_set, 1);
1366 rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0);
1367 rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1);
1368 rb_define_method(cState, "configure", cState_configure, 1);
1369 rb_define_alias(cState, "merge", "configure");
1370 rb_define_method(cState, "to_h", cState_to_h, 0);
1371 rb_define_alias(cState, "to_hash", "to_h");
1372 rb_define_method(cState, "[]", cState_aref, 1);
1373 rb_define_method(cState, "[]=", cState_aset, 2);
1374 rb_define_method(cState, "generate", cState_generate, 1);
1375
1376 mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
1377 mObject = rb_define_module_under(mGeneratorMethods, "Object");
1378 rb_define_method(mObject, "to_json", mObject_to_json, -1);
1379 mHash = rb_define_module_under(mGeneratorMethods, "Hash");
1380 rb_define_method(mHash, "to_json", mHash_to_json, -1);
1381 mArray = rb_define_module_under(mGeneratorMethods, "Array");
1382 rb_define_method(mArray, "to_json", mArray_to_json, -1);
1383 mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
1384 rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
1385 mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
1386 rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
1387 mFloat = rb_define_module_under(mGeneratorMethods, "Float");
1388 rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
1389 mString = rb_define_module_under(mGeneratorMethods, "String");
1390 rb_define_singleton_method(mString, "included", mString_included_s, 1);
1391 rb_define_method(mString, "to_json", mString_to_json, -1);
1392 rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1);
1393 rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0);
1394 mString_Extend = rb_define_module_under(mString, "Extend");
1395 rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1);
1396 mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass");
1397 rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1);
1398 mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass");
1399 rb_define_method(mFalseClass, "to_json", mFalseClass_to_json, -1);
1400 mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
1401 rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
1402
1403 CRegexp_MULTILINE = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
1404 i_to_s = rb_intern("to_s");
1405 i_to_json = rb_intern("to_json");
1406 i_new = rb_intern("new");
1407 i_indent = rb_intern("indent");
1408 i_space = rb_intern("space");
1409 i_space_before = rb_intern("space_before");
1410 i_object_nl = rb_intern("object_nl");
1411 i_array_nl = rb_intern("array_nl");
1412 i_max_nesting = rb_intern("max_nesting");
1413 i_allow_nan = rb_intern("allow_nan");
1414 i_ascii_only = rb_intern("ascii_only");
1415 i_quirks_mode = rb_intern("quirks_mode");
1416 i_depth = rb_intern("depth");
1417 i_buffer_initial_length = rb_intern("buffer_initial_length");
1418 i_pack = rb_intern("pack");
1419 i_unpack = rb_intern("unpack");
1420 i_create_id = rb_intern("create_id");
1421 i_extend = rb_intern("extend");
1422 i_key_p = rb_intern("key?");
1423 i_aref = rb_intern("[]");
1424 i_send = rb_intern("__send__");
1425 i_respond_to_p = rb_intern("respond_to?");
1426 i_match = rb_intern("match");
1427 i_keys = rb_intern("keys");
1428 i_dup = rb_intern("dup");
1429 #ifdef HAVE_RUBY_ENCODING_H
1430 CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1431 i_encoding = rb_intern("encoding");
1432 i_encode = rb_intern("encode");
1433 #endif
1434 i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
1435 CJSON_SAFE_STATE_PROTOTYPE = Qnil;
1436 }
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:1583
i_max_nesting
static ID i_max_nesting
Definition: generator.c:15
generator.h
fbuffer_clear
static void fbuffer_clear(FBuffer *fb)
Definition: fbuffer.h:83
eGeneratorError
static VALUE eGeneratorError
Definition: generator.c:9
State_allocate
static JSON_Generator_State * State_allocate()
Definition: generator.c:502
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1171
rb_cFloat
RUBY_EXTERN VALUE rb_cFloat
Definition: ruby.h:1566
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:878
i_SAFE_STATE_PROTOTYPE
static VALUE i_SAFE_STATE_PROTOTYPE
Definition: generator.c:9
cState_array_nl
static VALUE cState_array_nl(VALUE self)
Definition: generator.c:1158
generate_json_false
static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:786
mGenerator
static VALUE mGenerator
Definition: generator.c:9
CRegexp_MULTILINE
static VALUE CRegexp_MULTILINE
Definition: generator.c:9
mArray_to_json
static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:341
T_FIXNUM
#define T_FIXNUM
Definition: ruby.h:489
unicode_escape_to_buffer
static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character)
Definition: generator.c:118
JSON_Generator_StateStruct::depth
long depth
Definition: generator.h:77
CEncoding_UTF_8
static VALUE CEncoding_UTF_8
Definition: generator.c:5
trailingBytesForUTF8
static const char trailingBytesForUTF8[256]
Definition: generator.c:50
Data_Get_Struct
#define Data_Get_Struct(obj, type, sval)
Definition: ruby.h:1036
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1655
JSON_Generator_StateStruct::object_delim2
FBuffer * object_delim2
Definition: generator.h:72
mFixnum_to_json
static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:350
cState_from_state_s
static VALUE cState_from_state_s(VALUE self, VALUE opts)
Definition: generator.c:992
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:440
mTrueClass
static VALUE mTrueClass
Definition: generator.c:9
i_extend
static ID i_extend
Definition: generator.c:15
Qtrue
#define Qtrue
Definition: ruby.h:426
cState_array_nl_set
static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
Definition: generator.c:1169
JSON_Generator_StateStruct::object_nl_len
long object_nl_len
Definition: generator.h:67
rb_cHash
VALUE rb_cHash
Definition: hash.c:67
isLegalUTF8
static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length)
Definition: generator.c:79
option_given_p
#define option_given_p(opts, key)
Definition: generator.h:24
i_keys
static ID i_keys
Definition: generator.c:15
i_space
static ID i_space
Definition: generator.c:15
generate_json_array
static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:729
mString_Extend_json_create
static VALUE mString_Extend_json_create(VALUE self, VALUE o)
Definition: generator.c:434
i_space_before
static ID i_space_before
Definition: generator.c:15
JSON_Generator_StateStruct::allow_nan
char allow_nan
Definition: generator.h:74
offsetsFromUTF8
static const UTF32 offsetsFromUTF8[6]
Definition: generator.c:66
mFixnum
static VALUE mFixnum
Definition: generator.c:9
JSON_Generator_StateStruct::max_nesting
long max_nesting
Definition: generator.h:73
UTF8
unsigned char UTF8
Definition: generator.h:32
cState_object_nl
static VALUE cState_object_nl(VALUE self)
Definition: generator.c:1122
i_object_nl
static ID i_object_nl
Definition: generator.c:15
cState_check_circular_p
static VALUE cState_check_circular_p(VALUE self)
Definition: generator.c:1195
cState_max_nesting
static VALUE cState_max_nesting(VALUE self)
Definition: generator.c:1207
i_respond_to_p
static ID i_respond_to_p
Definition: generator.c:15
rb_str_concat
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2340
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:775
cState_initialize
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
Definition: generator.c:947
cState_space_before_set
static VALUE cState_space_before_set(VALUE self, VALUE space_before)
Definition: generator.c:1096
halfBase
static const UTF32 halfBase
Definition: generator.h:47
mGeneratorMethods
static VALUE mGeneratorMethods
Definition: generator.c:9
fbuffer_append_char
static void fbuffer_append_char(FBuffer *fb, char newchr)
Definition: fbuffer.h:126
cState_configure
static VALUE cState_configure(VALUE self, VALUE opts)
Definition: generator.c:521
rb_iv_get
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2601
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:676
Check_Type
#define Check_Type(v, t)
Definition: ruby.h:532
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1115
cState_quirks_mode_p
static VALUE cState_quirks_mode_p(VALUE self)
Definition: generator.c:1255
rb_convert_type
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2616
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:652
T_HASH
#define T_HASH
Definition: ruby.h:485
mJSON
static VALUE mJSON
Definition: generator.c:9
cState_max_nesting_set
static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
Definition: generator.c:1219
JSON_Generator_StateStruct::indent_len
long indent_len
Definition: generator.h:61
JSON_Generator_StateStruct::space_len
long space_len
Definition: generator.h:63
mObject
static VALUE mObject
Definition: generator.c:9
mString_to_json_raw
static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
Definition: generator.c:421
JSON_Generator_StateStruct::array_delim
FBuffer * array_delim
Definition: generator.h:70
cState_s_allocate
static VALUE cState_s_allocate(VALUE klass)
Definition: generator.c:509
cState_allow_nan_p
static VALUE cState_allow_nan_p(VALUE self)
Definition: generator.c:1232
mTrueClass_to_json
static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:447
i_depth
static ID i_depth
Definition: generator.c:15
rb_path2class
VALUE rb_path2class(const char *)
Definition: variable.c:379
UTF16
unsigned short UTF16
Definition: generator.h:31
FBUFFER_INITIAL_LENGTH_DEFAULT
#define FBUFFER_INITIAL_LENGTH_DEFAULT
Definition: fbuffer.h:47
mString
static VALUE mString
Definition: generator.c:9
cState
static VALUE cState
Definition: generator.c:9
cState_indent
static VALUE cState_indent(VALUE self)
Definition: generator.c:1011
generate_json
static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:824
generate_json_float
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:807
cState_space_set
static VALUE cState_space_set(VALUE self, VALUE space)
Definition: generator.c:1060
Data_Wrap_Struct
#define Data_Wrap_Struct(klass, mark, free, sval)
Definition: ruby.h:1018
JSON_Generator_StateStruct::space
char * space
Definition: generator.h:62
i_dup
static ID i_dup
Definition: generator.c:15
mNilClass_to_json
static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:467
mString_to_json
static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:392
mExt
static VALUE mExt
Definition: generator.c:9
MEMZERO
#define MEMZERO(p, type, n)
Definition: ruby.h:1351
generate_json_true
static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:791
rb_require
VALUE rb_require(const char *)
Definition: load.c:1034
i_array_nl
static ID i_array_nl
Definition: generator.c:15
generate_json_fixnum
static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:796
i_aref
static ID i_aref
Definition: generator.c:15
i_send
static ID i_send
Definition: generator.c:15
cState_generate
static VALUE cState_generate(VALUE self, VALUE obj)
Definition: generator.c:917
rb_intern_str
#define rb_intern_str(string)
Definition: generator.h:17
rb_class_name
VALUE rb_class_name(VALUE)
Definition: variable.c:391
ALLOC_N
#define ALLOC_N(type, n)
Definition: ruby.h:1333
JSON_Generator_StateStruct::object_delim
FBuffer * object_delim
Definition: generator.h:71
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1393
i_encode
static ID i_encode
Definition: generator.c:6
rb_str_substr
VALUE rb_str_substr(VALUE, long, long)
Definition: string.c:1945
JSON_Generator_StateStruct::array_nl_len
long array_nl_len
Definition: generator.h:69
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1553
cState_aset
static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
Definition: generator.c:666
fbuffer_append
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
Definition: fbuffer.h:105
cState_depth
static VALUE cState_depth(VALUE self)
Definition: generator.c:1278
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:2159
i_indent
static ID i_indent
Definition: generator.c:15
mArray
static VALUE mArray
Definition: generator.c:9
mNilClass
static VALUE mNilClass
Definition: generator.c:9
UTF32
unsigned long UTF32
Definition: generator.h:30
JSON_Generator_StateStruct::indent
char * indent
Definition: generator.h:60
NIL_P
#define NIL_P(v)
Definition: ruby.h:438
i_ascii_only
static ID i_ascii_only
Definition: generator.c:15
cState_indent_set
static VALUE cState_indent_set(VALUE self, VALUE indent)
Definition: generator.c:1022
mFalseClass_to_json
static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:457
mFloat
static VALUE mFloat
Definition: generator.c:9
argc
int argc
Definition: ruby.c:131
convert_UTF8_to_JSON_ASCII
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
Definition: generator.c:127
Qfalse
#define Qfalse
Definition: ruby.h:425
cState_depth_set
static VALUE cState_depth_set(VALUE self, VALUE depth)
Definition: generator.c:1290
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1352
i_to_json
static ID i_to_json
Definition: generator.c:15
isinf
RUBY_EXTERN int isinf(double)
Definition: isinf.c:56
rb_str_new2
#define rb_str_new2
Definition: intern.h:840
i_unpack
static ID i_unpack
Definition: generator.c:15
JSON_Generator_StateStruct
Definition: generator.h:59
isArrayOrObject
static int isArrayOrObject(VALUE string)
Definition: generator.c:900
ALLOC
#define ALLOC(type)
Definition: ruby.h:1334
mHash
static VALUE mHash
Definition: generator.c:9
generate_json_string
static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:767
mBignum
static VALUE mBignum
Definition: generator.c:9
i_new
static ID i_new
Definition: generator.c:15
fbuffer_alloc
static FBuffer * fbuffer_alloc(unsigned long initial_length)
Definition: fbuffer.h:67
rb_const_get
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1880
mString_to_json_raw_object
static VALUE mString_to_json_raw_object(VALUE self)
Definition: generator.c:405
mFloat_to_json
static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:370
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1697
rb_cRegexp
RUBY_EXTERN VALUE rb_cRegexp
Definition: ruby.h:1581
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:841
halfShift
static const int halfShift
Definition: generator.h:45
fstrndup
static char * fstrndup(const char *ptr, unsigned long len)
Definition: generator.c:300
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:298
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:6242
strdup
#define strdup(s)
Definition: util.h:67
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
cState_to_h
static VALUE cState_to_h(VALUE self)
Definition: generator.c:627
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1133
cState_space_before
static VALUE cState_space_before(VALUE self)
Definition: generator.c:1085
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
ID
unsigned long ID
Definition: ruby.h:89
cState_partial_generate
static VALUE cState_partial_generate(VALUE self, VALUE obj)
Definition: generator.c:887
Qnil
#define Qnil
Definition: ruby.h:427
i_allow_nan
static ID i_allow_nan
Definition: generator.c:15
VALUE
unsigned long VALUE
Definition: ruby.h:88
result
static VALUE result
Definition: nkf.c:40
JSON_Generator_StateStruct::object_nl
char * object_nl
Definition: generator.h:66
i_pack
static ID i_pack
Definition: generator.c:15
halfMask
static const UTF32 halfMask
Definition: generator.h:48
cState_ascii_only_p
static VALUE cState_ascii_only_p(VALUE self)
Definition: generator.c:1244
unicode_escape
static void unicode_escape(char *buf, UTF16 character)
Definition: generator.c:106
UNI_SUR_HIGH_START
#define UNI_SUR_HIGH_START
Definition: generator.h:40
isnan
#define isnan(x)
Definition: win32.h:376
mObject_to_json
static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:479
Init_generator
void Init_generator()
Definition: generator.c:1330
i_create_id
static ID i_create_id
Definition: generator.c:15
rb_str_dup
VALUE rb_str_dup(VALUE)
Definition: string.c:1062
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1639
JSON_Generator_StateStruct::ascii_only
char ascii_only
Definition: generator.h:75
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:766
StringValueCStr
#define StringValueCStr(v)
Definition: ruby.h:541
CJSON_SAFE_STATE_PROTOTYPE
static VALUE CJSON_SAFE_STATE_PROTOTYPE
Definition: generator.c:9
JSON_Generator_StateStruct::space_before_len
long space_before_len
Definition: generator.h:65
i_match
static ID i_match
Definition: generator.c:15
i_buffer_initial_length
static ID i_buffer_initial_length
Definition: generator.c:15
generate_json_object
static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:680
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:845
i_to_s
static ID i_to_s
Definition: generator.c:15
cState_prepare_buffer
static FBuffer * cState_prepare_buffer(VALUE self)
Definition: generator.c:857
cState_aref
static VALUE cState_aref(VALUE self, VALUE name)
Definition: generator.c:651
UNI_MAX_BMP
#define UNI_MAX_BMP
Definition: generator.h:35
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
Definition: ruby.h:814
cState_quirks_mode_set
static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
Definition: generator.c:1266
rb_cBignum
VALUE rb_cBignum
Definition: bignum.c:35
rb_check_convert_type
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2631
UNI_SUR_LOW_END
#define UNI_SUR_LOW_END
Definition: generator.h:43
mString_Extend
static VALUE mString_Extend
Definition: generator.c:9
convert_UTF8_to_JSON
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
Definition: generator.c:225
GENERATE_JSON
#define GENERATE_JSON(type)
Definition: generator.h:85
fbuffer_free
static void fbuffer_free(FBuffer *fb)
Definition: fbuffer.h:77
FBUFFER_PTR
#define FBUFFER_PTR(fb)
Definition: fbuffer.h:49
UNI_MAX_UTF16
#define UNI_MAX_UTF16
Definition: generator.h:36
set_state_ivars
static void set_state_ivars(VALUE hash, VALUE state)
Definition: generator.c:609
rb_hash_aref
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:697
cState_object_nl_set
static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
Definition: generator.c:1134
JSON_Generator_StateStruct::array_nl
char * array_nl
Definition: generator.h:68
generate_json_null
static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:781
key
uint8_t key[16]
Definition: random.c:1250
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:232
RTEST
#define RTEST(v)
Definition: ruby.h:437
i_key_p
static ID i_key_p
Definition: generator.c:15
T_STRING
#define T_STRING
Definition: ruby.h:482
mFalseClass
static VALUE mFalseClass
Definition: generator.c:9
UNI_SUR_LOW_START
#define UNI_SUR_LOW_START
Definition: generator.h:42
eNestingError
static VALUE eNestingError
Definition: generator.c:9
UNI_REPLACEMENT_CHAR
#define UNI_REPLACEMENT_CHAR
Definition: generator.h:34
i_quirks_mode
static ID i_quirks_mode
Definition: generator.c:15
rb_cArray
VALUE rb_cArray
Definition: array.c:27
hash
static unsigned int hash(const char *str, unsigned int len)
Definition: lex.c:56
cState_buffer_initial_length_set
static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length)
Definition: generator.c:1315
i_encoding
static ID i_encoding
Definition: generator.c:6
name
const char * name
Definition: nkf.c:208
ID2SYM
#define ID2SYM(x)
Definition: ruby.h:355
FBufferStruct
Definition: fbuffer.h:40
cState_buffer_initial_length
static VALUE cState_buffer_initial_length(VALUE self)
Definition: generator.c:1303
cState_init_copy
static VALUE cState_init_copy(VALUE obj, VALUE orig)
Definition: generator.c:964
cState_space
static VALUE cState_space(VALUE self)
Definition: generator.c:1048
mBignum_to_json
static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:360
rb_str_intern
VALUE rb_str_intern(VALUE)
Definition: string.c:7467
FBUFFER_LEN
#define FBUFFER_LEN(fb)
Definition: fbuffer.h:50
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:746
rb_intern
#define rb_intern(str)
NULL
#define NULL
Definition: _sdbm.c:103
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:345
rb_cFixnum
RUBY_EXTERN VALUE rb_cFixnum
Definition: ruby.h:1565
mHash_to_json
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:328
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
rb_obj_instance_variables
#define rb_obj_instance_variables(object)
Definition: generator.h:21
JSON_Generator_StateStruct::space_before
char * space_before
Definition: generator.h:64
rb_eArgError
VALUE rb_eArgError
Definition: error.c:549
generate_json_bignum
static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:801
GET_STATE
#define GET_STATE(self)
Definition: generator.h:81
argv
char ** argv
Definition: ruby.c:132
mString_included_s
static VALUE mString_included_s(VALUE self, VALUE modul)
Definition: generator.c:380
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:534
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:226
State_free
static void State_free(JSON_Generator_State *state)
Definition: generator.c:489