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