Ruby 2.0.0p353(2013-11-22revision43784)

- 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 end++;
277 continue;
278 break;
279 }
280 }
281 fbuffer_append(buffer, ptr + start, end - start);
282 fbuffer_append(buffer, escape, escape_len);
283 start = ++end;
284 escape = NULL;
285 }
286 fbuffer_append(buffer, ptr + start, end - start);
287 }
288
289 static char *fstrndup(const char *ptr, unsigned long len) {
290 char *result;
291 if (len <= 0) return NULL;
292 result = ALLOC_N(char, len);
293 memccpy(result, ptr, 0, len);
294 return result;
295 }
296
297 /*
298 * Document-module: JSON::Ext::Generator
299 *
300 * This is the JSON generator implemented as a C extension. It can be
301 * configured to be used by setting
302 *
303 * JSON.generator = JSON::Ext::Generator
304 *
305 * with the method generator= in JSON.
306 *
307 */
308
309 /*
310 * call-seq: to_json(state = nil)
311 *
312 * Returns a JSON string containing a JSON object, that is generated from
313 * this Hash instance.
314 * _state_ is a JSON::State object, that can also be used to configure the
315 * produced JSON string output further.
316 */
317 static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
318 {
319 GENERATE_JSON(object);
320 }
321
322 /*
323 * call-seq: to_json(state = nil)
324 *
325 * Returns a JSON string containing a JSON array, that is generated from
326 * this Array instance.
327 * _state_ is a JSON::State object, that can also be used to configure the
328 * produced JSON string output further.
329 */
330 static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
331 GENERATE_JSON(array);
332 }
333
334 /*
335 * call-seq: to_json(*)
336 *
337 * Returns a JSON string representation for this Integer number.
338 */
339 static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
340 {
341 GENERATE_JSON(fixnum);
342 }
343
344 /*
345 * call-seq: to_json(*)
346 *
347 * Returns a JSON string representation for this Integer number.
348 */
349 static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
350 {
351 GENERATE_JSON(bignum);
352 }
353
354 /*
355 * call-seq: to_json(*)
356 *
357 * Returns a JSON string representation for this Float number.
358 */
359 static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
360 {
361 GENERATE_JSON(float);
362 }
363
364 /*
365 * call-seq: String.included(modul)
366 *
367 * Extends _modul_ with the String::Extend module.
368 */
369 static VALUE mString_included_s(VALUE self, VALUE modul) {
370 VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
371 return result;
372 }
373
374 /*
375 * call-seq: to_json(*)
376 *
377 * This string should be encoded with UTF-8 A call to this method
378 * returns a JSON string encoded with UTF16 big endian characters as
379 * \u????.
380 */
381 static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
382 {
383 GENERATE_JSON(string);
384 }
385
386 /*
387 * call-seq: to_json_raw_object()
388 *
389 * This method creates a raw object hash, that can be nested into
390 * other data structures and will be generated as a raw string. This
391 * method should be used, if you want to convert raw strings to JSON
392 * instead of UTF-8 strings, e. g. binary data.
393 */
394 static VALUE mString_to_json_raw_object(VALUE self)
395 {
396 VALUE ary;
397 VALUE result = rb_hash_new();
398 rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self)));
399 ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*"));
400 rb_hash_aset(result, rb_str_new2("raw"), ary);
401 return result;
402 }
403
404 /*
405 * call-seq: to_json_raw(*args)
406 *
407 * This method creates a JSON text from the result of a call to
408 * to_json_raw_object of this String.
409 */
410 static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
411 {
412 VALUE obj = mString_to_json_raw_object(self);
413 Check_Type(obj, T_HASH);
414 return mHash_to_json(argc, argv, obj);
415 }
416
417 /*
418 * call-seq: json_create(o)
419 *
420 * Raw Strings are JSON Objects (the raw bytes are stored in an array for the
421 * key "raw"). The Ruby String can be created by this module method.
422 */
423 static VALUE mString_Extend_json_create(VALUE self, VALUE o)
424 {
425 VALUE ary;
426 Check_Type(o, T_HASH);
427 ary = rb_hash_aref(o, rb_str_new2("raw"));
428 return rb_funcall(ary, i_pack, 1, rb_str_new2("C*"));
429 }
430
431 /*
432 * call-seq: to_json(*)
433 *
434 * Returns a JSON string for true: 'true'.
435 */
436 static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
437 {
438 GENERATE_JSON(true);
439 }
440
441 /*
442 * call-seq: to_json(*)
443 *
444 * Returns a JSON string for false: 'false'.
445 */
446 static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
447 {
448 GENERATE_JSON(false);
449 }
450
451 /*
452 * call-seq: to_json(*)
453 *
454 * Returns a JSON string for nil: 'null'.
455 */
456 static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
457 {
458 GENERATE_JSON(null);
459 }
460
461 /*
462 * call-seq: to_json(*)
463 *
464 * Converts this object to a string (calling #to_s), converts
465 * it to a JSON string, and returns the result. This is a fallback, if no
466 * special method #to_json was defined for some object.
467 */
468 static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
469 {
470 VALUE state;
471 VALUE string = rb_funcall(self, i_to_s, 0);
472 rb_scan_args(argc, argv, "01", &state);
473 Check_Type(string, T_STRING);
474 state = cState_from_state_s(cState, state);
475 return cState_partial_generate(state, string);
476 }
477
478 static void State_free(JSON_Generator_State *state)
479 {
480 if (state->indent) ruby_xfree(state->indent);
481 if (state->space) ruby_xfree(state->space);
482 if (state->space_before) ruby_xfree(state->space_before);
483 if (state->object_nl) ruby_xfree(state->object_nl);
484 if (state->array_nl) ruby_xfree(state->array_nl);
485 if (state->array_delim) fbuffer_free(state->array_delim);
486 if (state->object_delim) fbuffer_free(state->object_delim);
487 if (state->object_delim2) fbuffer_free(state->object_delim2);
488 ruby_xfree(state);
489 }
490
491 static JSON_Generator_State *State_allocate()
492 {
493 JSON_Generator_State *state = ALLOC(JSON_Generator_State);
494 MEMZERO(state, JSON_Generator_State, 1);
495 return state;
496 }
497
498 static VALUE cState_s_allocate(VALUE klass)
499 {
500 JSON_Generator_State *state = State_allocate();
501 return Data_Wrap_Struct(klass, NULL, State_free, state);
502 }
503
504 /*
505 * call-seq: configure(opts)
506 *
507 * Configure this State instance with the Hash _opts_, and return
508 * itself.
509 */
510 static VALUE cState_configure(VALUE self, VALUE opts)
511 {
512 VALUE tmp;
513 GET_STATE(self);
514 tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
515 if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
516 if (NIL_P(tmp)) {
517 rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash");
518 }
519 opts = tmp;
520 tmp = rb_hash_aref(opts, ID2SYM(i_indent));
521 if (RTEST(tmp)) {
522 unsigned long len;
523 Check_Type(tmp, T_STRING);
524 len = RSTRING_LEN(tmp);
525 state->indent = fstrndup(RSTRING_PTR(tmp), len + 1);
526 state->indent_len = len;
527 }
528 tmp = rb_hash_aref(opts, ID2SYM(i_space));
529 if (RTEST(tmp)) {
530 unsigned long len;
531 Check_Type(tmp, T_STRING);
532 len = RSTRING_LEN(tmp);
533 state->space = fstrndup(RSTRING_PTR(tmp), len + 1);
534 state->space_len = len;
535 }
536 tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
537 if (RTEST(tmp)) {
538 unsigned long len;
539 Check_Type(tmp, T_STRING);
540 len = RSTRING_LEN(tmp);
541 state->space_before = fstrndup(RSTRING_PTR(tmp), len + 1);
542 state->space_before_len = len;
543 }
544 tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
545 if (RTEST(tmp)) {
546 unsigned long len;
547 Check_Type(tmp, T_STRING);
548 len = RSTRING_LEN(tmp);
549 state->array_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
550 state->array_nl_len = len;
551 }
552 tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
553 if (RTEST(tmp)) {
554 unsigned long len;
555 Check_Type(tmp, T_STRING);
556 len = RSTRING_LEN(tmp);
557 state->object_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
558 state->object_nl_len = len;
559 }
560 tmp = ID2SYM(i_max_nesting);
561 state->max_nesting = 100;
562 if (option_given_p(opts, tmp)) {
563 VALUE max_nesting = rb_hash_aref(opts, tmp);
564 if (RTEST(max_nesting)) {
565 Check_Type(max_nesting, T_FIXNUM);
566 state->max_nesting = FIX2LONG(max_nesting);
567 } else {
568 state->max_nesting = 0;
569 }
570 }
571 tmp = ID2SYM(i_depth);
572 state->depth = 0;
573 if (option_given_p(opts, tmp)) {
574 VALUE depth = rb_hash_aref(opts, tmp);
575 if (RTEST(depth)) {
576 Check_Type(depth, T_FIXNUM);
577 state->depth = FIX2LONG(depth);
578 } else {
579 state->depth = 0;
580 }
581 }
582 tmp = ID2SYM(i_buffer_initial_length);
583 if (option_given_p(opts, tmp)) {
584 VALUE buffer_initial_length = rb_hash_aref(opts, tmp);
585 if (RTEST(buffer_initial_length)) {
586 long initial_length;
587 Check_Type(buffer_initial_length, T_FIXNUM);
588 initial_length = FIX2LONG(buffer_initial_length);
589 if (initial_length > 0) state->buffer_initial_length = initial_length;
590 }
591 }
592 tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
593 state->allow_nan = RTEST(tmp);
594 tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
595 state->ascii_only = RTEST(tmp);
596 tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode));
597 state->quirks_mode = RTEST(tmp);
598 return self;
599 }
600
601 static void set_state_ivars(VALUE hash, VALUE state)
602 {
603 VALUE ivars = rb_obj_instance_variables(state);
604 int i = 0;
605 for (i = 0; i < RARRAY_LEN(ivars); i++) {
606 VALUE key = rb_funcall(rb_ary_entry(ivars, i), i_to_s, 0);
607 long key_len = RSTRING_LEN(key);
608 VALUE value = rb_iv_get(state, StringValueCStr(key));
609 rb_hash_aset(hash, rb_str_intern(rb_str_substr(key, 1, key_len - 1)), value);
610 }
611 }
612
613 /*
614 * call-seq: to_h
615 *
616 * Returns the configuration instance variables as a hash, that can be
617 * passed to the configure method.
618 */
619 static VALUE cState_to_h(VALUE self)
620 {
621 VALUE result = rb_hash_new();
622 GET_STATE(self);
623 set_state_ivars(result, self);
624 rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len));
625 rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len));
626 rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len));
627 rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new(state->object_nl, state->object_nl_len));
628 rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
629 rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
630 rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
631 rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse);
632 rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
633 rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
634 rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
635 return result;
636 }
637
638 /*
639 * call-seq: [](name)
640 *
641 * Return the value returned by method +name+.
642 */
643 static VALUE cState_aref(VALUE self, VALUE name)
644 {
645 name = rb_funcall(name, i_to_s, 0);
646 if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
647 return rb_funcall(self, i_send, 1, name);
648 } else {
649 return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
650 }
651 }
652
653 /*
654 * call-seq: []=(name, value)
655 *
656 * Set the attribute name to value.
657 */
658 static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
659 {
660 VALUE name_writer;
661
662 name = rb_funcall(name, i_to_s, 0);
663 name_writer = rb_str_cat2(rb_str_dup(name), "=");
664 if (RTEST(rb_funcall(self, i_respond_to_p, 1, name_writer))) {
665 return rb_funcall(self, i_send, 2, name_writer, value);
666 } else {
667 rb_ivar_set(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)), value);
668 }
669 return Qnil;
670 }
671
672 static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
673 {
674 char *object_nl = state->object_nl;
675 long object_nl_len = state->object_nl_len;
676 char *indent = state->indent;
677 long indent_len = state->indent_len;
678 long max_nesting = state->max_nesting;
679 char *delim = FBUFFER_PTR(state->object_delim);
680 long delim_len = FBUFFER_LEN(state->object_delim);
681 char *delim2 = FBUFFER_PTR(state->object_delim2);
682 long delim2_len = FBUFFER_LEN(state->object_delim2);
683 long depth = ++state->depth;
684 int i, j;
685 VALUE key, key_to_s, keys;
686 if (max_nesting != 0 && depth > max_nesting) {
687 fbuffer_free(buffer);
688 rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
689 }
690 fbuffer_append_char(buffer, '{');
691 keys = rb_funcall(obj, i_keys, 0);
692 for(i = 0; i < RARRAY_LEN(keys); i++) {
693 if (i > 0) fbuffer_append(buffer, delim, delim_len);
694 if (object_nl) {
695 fbuffer_append(buffer, object_nl, object_nl_len);
696 }
697 if (indent) {
698 for (j = 0; j < depth; j++) {
699 fbuffer_append(buffer, indent, indent_len);
700 }
701 }
702 key = rb_ary_entry(keys, i);
703 key_to_s = rb_funcall(key, i_to_s, 0);
704 Check_Type(key_to_s, T_STRING);
705 generate_json(buffer, Vstate, state, key_to_s);
706 fbuffer_append(buffer, delim2, delim2_len);
707 generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
708 }
709 depth = --state->depth;
710 if (object_nl) {
711 fbuffer_append(buffer, object_nl, object_nl_len);
712 if (indent) {
713 for (j = 0; j < depth; j++) {
714 fbuffer_append(buffer, indent, indent_len);
715 }
716 }
717 }
718 fbuffer_append_char(buffer, '}');
719 }
720
721 static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
722 {
723 char *array_nl = state->array_nl;
724 long array_nl_len = state->array_nl_len;
725 char *indent = state->indent;
726 long indent_len = state->indent_len;
727 long max_nesting = state->max_nesting;
728 char *delim = FBUFFER_PTR(state->array_delim);
729 long delim_len = FBUFFER_LEN(state->array_delim);
730 long depth = ++state->depth;
731 int i, j;
732 if (max_nesting != 0 && depth > max_nesting) {
733 fbuffer_free(buffer);
734 rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
735 }
736 fbuffer_append_char(buffer, '[');
737 if (array_nl) fbuffer_append(buffer, array_nl, array_nl_len);
738 for(i = 0; i < RARRAY_LEN(obj); i++) {
739 if (i > 0) fbuffer_append(buffer, delim, delim_len);
740 if (indent) {
741 for (j = 0; j < depth; j++) {
742 fbuffer_append(buffer, indent, indent_len);
743 }
744 }
745 generate_json(buffer, Vstate, state, rb_ary_entry(obj, i));
746 }
747 state->depth = --depth;
748 if (array_nl) {
749 fbuffer_append(buffer, array_nl, array_nl_len);
750 if (indent) {
751 for (j = 0; j < depth; j++) {
752 fbuffer_append(buffer, indent, indent_len);
753 }
754 }
755 }
756 fbuffer_append_char(buffer, ']');
757 }
758
759 static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
760 {
761 fbuffer_append_char(buffer, '"');
762 #ifdef HAVE_RUBY_ENCODING_H
763 obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
764 #endif
765 if (state->ascii_only) {
766 convert_UTF8_to_JSON_ASCII(buffer, obj);
767 } else {
768 convert_UTF8_to_JSON(buffer, obj);
769 }
770 fbuffer_append_char(buffer, '"');
771 }
772
773 static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
774 {
775 fbuffer_append(buffer, "null", 4);
776 }
777
778 static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
779 {
780 fbuffer_append(buffer, "false", 5);
781 }
782
783 static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
784 {
785 fbuffer_append(buffer, "true", 4);
786 }
787
788 static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
789 {
790 fbuffer_append_long(buffer, FIX2LONG(obj));
791 }
792
793 static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
794 {
795 VALUE tmp = rb_funcall(obj, i_to_s, 0);
796 fbuffer_append_str(buffer, tmp);
797 }
798
799 static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
800 {
801 double value = RFLOAT_VALUE(obj);
802 char allow_nan = state->allow_nan;
803 VALUE tmp = rb_funcall(obj, i_to_s, 0);
804 if (!allow_nan) {
805 if (isinf(value)) {
806 fbuffer_free(buffer);
807 rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
808 } else if (isnan(value)) {
809 fbuffer_free(buffer);
810 rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
811 }
812 }
813 fbuffer_append_str(buffer, tmp);
814 }
815
816 static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
817 {
818 VALUE tmp;
819 VALUE klass = CLASS_OF(obj);
820 if (klass == rb_cHash) {
821 generate_json_object(buffer, Vstate, state, obj);
822 } else if (klass == rb_cArray) {
823 generate_json_array(buffer, Vstate, state, obj);
824 } else if (klass == rb_cString) {
825 generate_json_string(buffer, Vstate, state, obj);
826 } else if (obj == Qnil) {
827 generate_json_null(buffer, Vstate, state, obj);
828 } else if (obj == Qfalse) {
829 generate_json_false(buffer, Vstate, state, obj);
830 } else if (obj == Qtrue) {
831 generate_json_true(buffer, Vstate, state, obj);
832 } else if (klass == rb_cFixnum) {
833 generate_json_fixnum(buffer, Vstate, state, obj);
834 } else if (klass == rb_cBignum) {
835 generate_json_bignum(buffer, Vstate, state, obj);
836 } else if (klass == rb_cFloat) {
837 generate_json_float(buffer, Vstate, state, obj);
838 } else if (rb_respond_to(obj, i_to_json)) {
839 tmp = rb_funcall(obj, i_to_json, 1, Vstate);
840 Check_Type(tmp, T_STRING);
841 fbuffer_append_str(buffer, tmp);
842 } else {
843 tmp = rb_funcall(obj, i_to_s, 0);
844 Check_Type(tmp, T_STRING);
845 generate_json(buffer, Vstate, state, tmp);
846 }
847 }
848
849 static FBuffer *cState_prepare_buffer(VALUE self)
850 {
851 FBuffer *buffer;
852 GET_STATE(self);
853 buffer = fbuffer_alloc(state->buffer_initial_length);
854
855 if (state->object_delim) {
856 fbuffer_clear(state->object_delim);
857 } else {
858 state->object_delim = fbuffer_alloc(16);
859 }
860 fbuffer_append_char(state->object_delim, ',');
861 if (state->object_delim2) {
862 fbuffer_clear(state->object_delim2);
863 } else {
864 state->object_delim2 = fbuffer_alloc(16);
865 }
866 fbuffer_append_char(state->object_delim2, ':');
867 if (state->space) fbuffer_append(state->object_delim2, state->space, state->space_len);
868
869 if (state->array_delim) {
870 fbuffer_clear(state->array_delim);
871 } else {
872 state->array_delim = fbuffer_alloc(16);
873 }
874 fbuffer_append_char(state->array_delim, ',');
875 if (state->array_nl) fbuffer_append(state->array_delim, state->array_nl, state->array_nl_len);
876 return buffer;
877 }
878
879 static VALUE cState_partial_generate(VALUE self, VALUE obj)
880 {
881 FBuffer *buffer = cState_prepare_buffer(self);
882 GET_STATE(self);
883 generate_json(buffer, self, state, obj);
884 return fbuffer_to_s(buffer);
885 }
886
887 /*
888 * This function returns true if string is either a JSON array or JSON object.
889 * It might suffer from false positives, e. g. syntactically incorrect JSON in
890 * the string or certain UTF-8 characters on the right hand side.
891 */
892 static int isArrayOrObject(VALUE string)
893 {
894 long string_len = RSTRING_LEN(string);
895 char *p = RSTRING_PTR(string), *q = p + string_len - 1;
896 if (string_len < 2) return 0;
897 for (; p < q && isspace(*p); p++);
898 for (; q > p && isspace(*q); q--);
899 return (*p == '[' && *q == ']') || (*p == '{' && *q == '}');
900 }
901
902 /*
903 * call-seq: generate(obj)
904 *
905 * Generates a valid JSON document from object +obj+ and returns the
906 * result. If no valid JSON document can be created this method raises a
907 * GeneratorError exception.
908 */
909 static VALUE cState_generate(VALUE self, VALUE obj)
910 {
911 VALUE result = cState_partial_generate(self, obj);
912 GET_STATE(self);
913 if (!state->quirks_mode && !isArrayOrObject(result)) {
914 rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
915 }
916 return result;
917 }
918
919 /*
920 * call-seq: new(opts = {})
921 *
922 * Instantiates a new State object, configured by _opts_.
923 *
924 * _opts_ can have the following keys:
925 *
926 * * *indent*: a string used to indent levels (default: ''),
927 * * *space*: a string that is put after, a : or , delimiter (default: ''),
928 * * *space_before*: a string that is put before a : pair delimiter (default: ''),
929 * * *object_nl*: a string that is put at the end of a JSON object (default: ''),
930 * * *array_nl*: a string that is put at the end of a JSON array (default: ''),
931 * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
932 * generated, otherwise an exception is thrown, if these values are
933 * encountered. This options defaults to false.
934 * * *quirks_mode*: Enables quirks_mode for parser, that is for example
935 * generating single JSON values instead of documents is possible.
936 * * *buffer_initial_length*: sets the initial length of the generator's
937 * internal buffer.
938 */
939 static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
940 {
941 VALUE opts;
942 GET_STATE(self);
943 state->max_nesting = 100;
944 state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
945 rb_scan_args(argc, argv, "01", &opts);
946 if (!NIL_P(opts)) cState_configure(self, opts);
947 return self;
948 }
949
950 /*
951 * call-seq: initialize_copy(orig)
952 *
953 * Initializes this object from orig if it to be duplicated/cloned and returns
954 * it.
955 */
956 static VALUE cState_init_copy(VALUE obj, VALUE orig)
957 {
958 JSON_Generator_State *objState, *origState;
959
960 Data_Get_Struct(obj, JSON_Generator_State, objState);
961 Data_Get_Struct(orig, JSON_Generator_State, origState);
962 if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State");
963
964 MEMCPY(objState, origState, JSON_Generator_State, 1);
965 objState->indent = fstrndup(origState->indent, origState->indent_len);
966 objState->space = fstrndup(origState->space, origState->space_len);
967 objState->space_before = fstrndup(origState->space_before, origState->space_before_len);
968 objState->object_nl = fstrndup(origState->object_nl, origState->object_nl_len);
969 objState->array_nl = fstrndup(origState->array_nl, origState->array_nl_len);
970 if (origState->array_delim) objState->array_delim = fbuffer_dup(origState->array_delim);
971 if (origState->object_delim) objState->object_delim = fbuffer_dup(origState->object_delim);
972 if (origState->object_delim2) objState->object_delim2 = fbuffer_dup(origState->object_delim2);
973 return obj;
974 }
975
976 /*
977 * call-seq: from_state(opts)
978 *
979 * Creates a State object from _opts_, which ought to be Hash to create a
980 * new State instance configured by _opts_, something else to create an
981 * unconfigured instance. If _opts_ is a State object, it is just returned.
982 */
983 static VALUE cState_from_state_s(VALUE self, VALUE opts)
984 {
985 if (rb_obj_is_kind_of(opts, self)) {
986 return opts;
987 } else if (rb_obj_is_kind_of(opts, rb_cHash)) {
988 return rb_funcall(self, i_new, 1, opts);
989 } else {
990 if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
991 CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
992 }
993 return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
994 }
995 }
996
997 /*
998 * call-seq: indent()
999 *
1000 * This string is used to indent levels in the JSON text.
1001 */
1002 static VALUE cState_indent(VALUE self)
1003 {
1004 GET_STATE(self);
1005 return state->indent ? rb_str_new(state->indent, state->indent_len) : rb_str_new2("");
1006 }
1007
1008 /*
1009 * call-seq: indent=(indent)
1010 *
1011 * This string is used to indent levels in the JSON text.
1012 */
1013 static VALUE cState_indent_set(VALUE self, VALUE indent)
1014 {
1015 unsigned long len;
1016 GET_STATE(self);
1017 Check_Type(indent, T_STRING);
1018 len = RSTRING_LEN(indent);
1019 if (len == 0) {
1020 if (state->indent) {
1021 ruby_xfree(state->indent);
1022 state->indent = NULL;
1023 state->indent_len = 0;
1024 }
1025 } else {
1026 if (state->indent) ruby_xfree(state->indent);
1027 state->indent = strdup(RSTRING_PTR(indent));
1028 state->indent_len = len;
1029 }
1030 return Qnil;
1031 }
1032
1033 /*
1034 * call-seq: space()
1035 *
1036 * This string is used to insert a space between the tokens in a JSON
1037 * string.
1038 */
1039 static VALUE cState_space(VALUE self)
1040 {
1041 GET_STATE(self);
1042 return state->space ? rb_str_new(state->space, state->space_len) : rb_str_new2("");
1043 }
1044
1045 /*
1046 * call-seq: space=(space)
1047 *
1048 * This string is used to insert a space between the tokens in a JSON
1049 * string.
1050 */
1051 static VALUE cState_space_set(VALUE self, VALUE space)
1052 {
1053 unsigned long len;
1054 GET_STATE(self);
1055 Check_Type(space, T_STRING);
1056 len = RSTRING_LEN(space);
1057 if (len == 0) {
1058 if (state->space) {
1059 ruby_xfree(state->space);
1060 state->space = NULL;
1061 state->space_len = 0;
1062 }
1063 } else {
1064 if (state->space) ruby_xfree(state->space);
1065 state->space = strdup(RSTRING_PTR(space));
1066 state->space_len = len;
1067 }
1068 return Qnil;
1069 }
1070
1071 /*
1072 * call-seq: space_before()
1073 *
1074 * This string is used to insert a space before the ':' in JSON objects.
1075 */
1076 static VALUE cState_space_before(VALUE self)
1077 {
1078 GET_STATE(self);
1079 return state->space_before ? rb_str_new(state->space_before, state->space_before_len) : rb_str_new2("");
1080 }
1081
1082 /*
1083 * call-seq: space_before=(space_before)
1084 *
1085 * This string is used to insert a space before the ':' in JSON objects.
1086 */
1087 static VALUE cState_space_before_set(VALUE self, VALUE space_before)
1088 {
1089 unsigned long len;
1090 GET_STATE(self);
1091 Check_Type(space_before, T_STRING);
1092 len = RSTRING_LEN(space_before);
1093 if (len == 0) {
1094 if (state->space_before) {
1095 ruby_xfree(state->space_before);
1096 state->space_before = NULL;
1097 state->space_before_len = 0;
1098 }
1099 } else {
1100 if (state->space_before) ruby_xfree(state->space_before);
1101 state->space_before = strdup(RSTRING_PTR(space_before));
1102 state->space_before_len = len;
1103 }
1104 return Qnil;
1105 }
1106
1107 /*
1108 * call-seq: object_nl()
1109 *
1110 * This string is put at the end of a line that holds a JSON object (or
1111 * Hash).
1112 */
1113 static VALUE cState_object_nl(VALUE self)
1114 {
1115 GET_STATE(self);
1116 return state->object_nl ? rb_str_new(state->object_nl, state->object_nl_len) : rb_str_new2("");
1117 }
1118
1119 /*
1120 * call-seq: object_nl=(object_nl)
1121 *
1122 * This string is put at the end of a line that holds a JSON object (or
1123 * Hash).
1124 */
1125 static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1126 {
1127 unsigned long len;
1128 GET_STATE(self);
1129 Check_Type(object_nl, T_STRING);
1130 len = RSTRING_LEN(object_nl);
1131 if (len == 0) {
1132 if (state->object_nl) {
1133 ruby_xfree(state->object_nl);
1134 state->object_nl = NULL;
1135 }
1136 } else {
1137 if (state->object_nl) ruby_xfree(state->object_nl);
1138 state->object_nl = strdup(RSTRING_PTR(object_nl));
1139 state->object_nl_len = len;
1140 }
1141 return Qnil;
1142 }
1143
1144 /*
1145 * call-seq: array_nl()
1146 *
1147 * This string is put at the end of a line that holds a JSON array.
1148 */
1149 static VALUE cState_array_nl(VALUE self)
1150 {
1151 GET_STATE(self);
1152 return state->array_nl ? rb_str_new(state->array_nl, state->array_nl_len) : rb_str_new2("");
1153 }
1154
1155 /*
1156 * call-seq: array_nl=(array_nl)
1157 *
1158 * This string is put at the end of a line that holds a JSON array.
1159 */
1160 static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1161 {
1162 unsigned long len;
1163 GET_STATE(self);
1164 Check_Type(array_nl, T_STRING);
1165 len = RSTRING_LEN(array_nl);
1166 if (len == 0) {
1167 if (state->array_nl) {
1168 ruby_xfree(state->array_nl);
1169 state->array_nl = NULL;
1170 }
1171 } else {
1172 if (state->array_nl) ruby_xfree(state->array_nl);
1173 state->array_nl = strdup(RSTRING_PTR(array_nl));
1174 state->array_nl_len = len;
1175 }
1176 return Qnil;
1177 }
1178
1179
1180 /*
1181 * call-seq: check_circular?
1182 *
1183 * Returns true, if circular data structures should be checked,
1184 * otherwise returns false.
1185 */
1186 static VALUE cState_check_circular_p(VALUE self)
1187 {
1188 GET_STATE(self);
1189 return state->max_nesting ? Qtrue : Qfalse;
1190 }
1191
1192 /*
1193 * call-seq: max_nesting
1194 *
1195 * This integer returns the maximum level of data structure nesting in
1196 * the generated JSON, max_nesting = 0 if no maximum is checked.
1197 */
1198 static VALUE cState_max_nesting(VALUE self)
1199 {
1200 GET_STATE(self);
1201 return LONG2FIX(state->max_nesting);
1202 }
1203
1204 /*
1205 * call-seq: max_nesting=(depth)
1206 *
1207 * This sets the maximum level of data structure nesting in the generated JSON
1208 * to the integer depth, max_nesting = 0 if no maximum should be checked.
1209 */
1210 static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
1211 {
1212 GET_STATE(self);
1213 Check_Type(depth, T_FIXNUM);
1214 return state->max_nesting = FIX2LONG(depth);
1215 }
1216
1217 /*
1218 * call-seq: allow_nan?
1219 *
1220 * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
1221 * returns false.
1222 */
1223 static VALUE cState_allow_nan_p(VALUE self)
1224 {
1225 GET_STATE(self);
1226 return state->allow_nan ? Qtrue : Qfalse;
1227 }
1228
1229 /*
1230 * call-seq: ascii_only?
1231 *
1232 * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
1233 * returns false.
1234 */
1235 static VALUE cState_ascii_only_p(VALUE self)
1236 {
1237 GET_STATE(self);
1238 return state->ascii_only ? Qtrue : Qfalse;
1239 }
1240
1241 /*
1242 * call-seq: quirks_mode?
1243 *
1244 * Returns true, if quirks mode is enabled. Otherwise returns false.
1245 */
1246 static VALUE cState_quirks_mode_p(VALUE self)
1247 {
1248 GET_STATE(self);
1249 return state->quirks_mode ? Qtrue : Qfalse;
1250 }
1251
1252 /*
1253 * call-seq: quirks_mode=(enable)
1254 *
1255 * If set to true, enables the quirks_mode mode.
1256 */
1257 static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
1258 {
1259 GET_STATE(self);
1260 state->quirks_mode = RTEST(enable);
1261 return Qnil;
1262 }
1263
1264 /*
1265 * call-seq: depth
1266 *
1267 * This integer returns the current depth of data structure nesting.
1268 */
1269 static VALUE cState_depth(VALUE self)
1270 {
1271 GET_STATE(self);
1272 return LONG2FIX(state->depth);
1273 }
1274
1275 /*
1276 * call-seq: depth=(depth)
1277 *
1278 * This sets the maximum level of data structure nesting in the generated JSON
1279 * to the integer depth, max_nesting = 0 if no maximum should be checked.
1280 */
1281 static VALUE cState_depth_set(VALUE self, VALUE depth)
1282 {
1283 GET_STATE(self);
1284 Check_Type(depth, T_FIXNUM);
1285 state->depth = FIX2LONG(depth);
1286 return Qnil;
1287 }
1288
1289 /*
1290 * call-seq: buffer_initial_length
1291 *
1292 * This integer returns the current inital length of the buffer.
1293 */
1294 static VALUE cState_buffer_initial_length(VALUE self)
1295 {
1296 GET_STATE(self);
1297 return LONG2FIX(state->buffer_initial_length);
1298 }
1299
1300 /*
1301 * call-seq: buffer_initial_length=(length)
1302 *
1303 * This sets the initial length of the buffer to +length+, if +length+ > 0,
1304 * otherwise its value isn't changed.
1305 */
1306 static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length)
1307 {
1308 long initial_length;
1309 GET_STATE(self);
1310 Check_Type(buffer_initial_length, T_FIXNUM);
1311 initial_length = FIX2LONG(buffer_initial_length);
1312 if (initial_length > 0) {
1313 state->buffer_initial_length = initial_length;
1314 }
1315 return Qnil;
1316 }
1317
1318 /*
1319 *
1320 */
1321 void Init_generator()
1322 {
1323 rb_require("json/common");
1324
1325 mJSON = rb_define_module("JSON");
1326 mExt = rb_define_module_under(mJSON, "Ext");
1327 mGenerator = rb_define_module_under(mExt, "Generator");
1328
1329 eGeneratorError = rb_path2class("JSON::GeneratorError");
1330 eNestingError = rb_path2class("JSON::NestingError");
1331
1332 cState = rb_define_class_under(mGenerator, "State", rb_cObject);
1333 rb_define_alloc_func(cState, cState_s_allocate);
1334 rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1);
1335 rb_define_method(cState, "initialize", cState_initialize, -1);
1336 rb_define_method(cState, "initialize_copy", cState_init_copy, 1);
1337 rb_define_method(cState, "indent", cState_indent, 0);
1338 rb_define_method(cState, "indent=", cState_indent_set, 1);
1339 rb_define_method(cState, "space", cState_space, 0);
1340 rb_define_method(cState, "space=", cState_space_set, 1);
1341 rb_define_method(cState, "space_before", cState_space_before, 0);
1342 rb_define_method(cState, "space_before=", cState_space_before_set, 1);
1343 rb_define_method(cState, "object_nl", cState_object_nl, 0);
1344 rb_define_method(cState, "object_nl=", cState_object_nl_set, 1);
1345 rb_define_method(cState, "array_nl", cState_array_nl, 0);
1346 rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
1347 rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
1348 rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
1349 rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
1350 rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
1351 rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
1352 rb_define_method(cState, "quirks_mode?", cState_quirks_mode_p, 0);
1353 rb_define_method(cState, "quirks_mode", cState_quirks_mode_p, 0);
1354 rb_define_method(cState, "quirks_mode=", cState_quirks_mode_set, 1);
1355 rb_define_method(cState, "depth", cState_depth, 0);
1356 rb_define_method(cState, "depth=", cState_depth_set, 1);
1357 rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0);
1358 rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1);
1359 rb_define_method(cState, "configure", cState_configure, 1);
1360 rb_define_alias(cState, "merge", "configure");
1361 rb_define_method(cState, "to_h", cState_to_h, 0);
1362 rb_define_alias(cState, "to_hash", "to_h");
1363 rb_define_method(cState, "[]", cState_aref, 1);
1364 rb_define_method(cState, "[]=", cState_aset, 2);
1365 rb_define_method(cState, "generate", cState_generate, 1);
1366
1367 mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
1368 mObject = rb_define_module_under(mGeneratorMethods, "Object");
1369 rb_define_method(mObject, "to_json", mObject_to_json, -1);
1370 mHash = rb_define_module_under(mGeneratorMethods, "Hash");
1371 rb_define_method(mHash, "to_json", mHash_to_json, -1);
1372 mArray = rb_define_module_under(mGeneratorMethods, "Array");
1373 rb_define_method(mArray, "to_json", mArray_to_json, -1);
1374 mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
1375 rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
1376 mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
1377 rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
1378 mFloat = rb_define_module_under(mGeneratorMethods, "Float");
1379 rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
1380 mString = rb_define_module_under(mGeneratorMethods, "String");
1381 rb_define_singleton_method(mString, "included", mString_included_s, 1);
1382 rb_define_method(mString, "to_json", mString_to_json, -1);
1383 rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1);
1384 rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0);
1385 mString_Extend = rb_define_module_under(mString, "Extend");
1386 rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1);
1387 mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass");
1388 rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1);
1389 mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass");
1390 rb_define_method(mFalseClass, "to_json", mFalseClass_to_json, -1);
1391 mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
1392 rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
1393
1394 CRegexp_MULTILINE = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
1395 i_to_s = rb_intern("to_s");
1396 i_to_json = rb_intern("to_json");
1397 i_new = rb_intern("new");
1398 i_indent = rb_intern("indent");
1399 i_space = rb_intern("space");
1400 i_space_before = rb_intern("space_before");
1401 i_object_nl = rb_intern("object_nl");
1402 i_array_nl = rb_intern("array_nl");
1403 i_max_nesting = rb_intern("max_nesting");
1404 i_allow_nan = rb_intern("allow_nan");
1405 i_ascii_only = rb_intern("ascii_only");
1406 i_quirks_mode = rb_intern("quirks_mode");
1407 i_depth = rb_intern("depth");
1408 i_buffer_initial_length = rb_intern("buffer_initial_length");
1409 i_pack = rb_intern("pack");
1410 i_unpack = rb_intern("unpack");
1411 i_create_id = rb_intern("create_id");
1412 i_extend = rb_intern("extend");
1413 i_key_p = rb_intern("key?");
1414 i_aref = rb_intern("[]");
1415 i_send = rb_intern("__send__");
1416 i_respond_to_p = rb_intern("respond_to?");
1417 i_match = rb_intern("match");
1418 i_keys = rb_intern("keys");
1419 i_dup = rb_intern("dup");
1420 #ifdef HAVE_RUBY_ENCODING_H
1421 CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1422 i_encoding = rb_intern("encoding");
1423 i_encode = rb_intern("encode");
1424 #endif
1425 i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
1426 CJSON_SAFE_STATE_PROTOTYPE = Qnil;
1427 }
i_max_nesting
static ID i_max_nesting
Definition: generator.c:15
generator.h
ALLOC
#define ALLOC(type)
tmp
volatile VALUE tmp
Definition: tcltklib.c:10209
fbuffer_clear
static void fbuffer_clear(FBuffer *fb)
Definition: fbuffer.h:83
eGeneratorError
static VALUE eGeneratorError
Definition: generator.c:9
ary
volatile VALUE ary
Definition: tcltklib.c:9713
State_allocate
static JSON_Generator_State * State_allocate()
Definition: generator.c:491
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1101
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:1149
generate_json_false
static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:778
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:330
unicode_escape_to_buffer
static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character)
Definition: generator.c:118
p
Win32OLEIDispatch * p
Definition: win32ole.c:786
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
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:1497
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:339
cState_from_state_s
static VALUE cState_from_state_s(VALUE self, VALUE opts)
Definition: generator.c:983
mTrueClass
static VALUE mTrueClass
Definition: generator.c:9
i_extend
static ID i_extend
Definition: generator.c:15
cState_array_nl_set
static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
Definition: generator.c:1160
rb_const_get
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1876
JSON_Generator_StateStruct::object_nl_len
long object_nl_len
Definition: generator.h:67
isLegalUTF8
static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length)
Definition: generator.c:79
i
ssize_t i
Definition: bigdecimal.c:5655
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:721
mString_Extend_json_create
static VALUE mString_Extend_json_create(VALUE self, VALUE o)
Definition: generator.c:423
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
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
mFixnum
static VALUE mFixnum
Definition: generator.c:9
JSON_Generator_StateStruct::max_nesting
long max_nesting
Definition: generator.h:73
rb_iv_get
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2583
a
Real * a
Definition: bigdecimal.c:1182
UTF8
unsigned char UTF8
Definition: generator.h:32
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
cState_object_nl
static VALUE cState_object_nl(VALUE self)
Definition: generator.c:1113
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:1186
cState_max_nesting
static VALUE cState_max_nesting(VALUE self)
Definition: generator.c:1198
i_respond_to_p
static ID i_respond_to_p
Definition: generator.c:15
rb_require
VALUE rb_require(const char *)
Definition: load.c:1024
RSTRING_PTR
#define RSTRING_PTR(str)
CLASS_OF
#define CLASS_OF(v)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
cState_initialize
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
Definition: generator.c:939
cState_space_before_set
static VALUE cState_space_before_set(VALUE self, VALUE space_before)
Definition: generator.c:1087
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:510
rb_cFloat
RUBY_EXTERN VALUE rb_cFloat
Definition: ripper.y:1439
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
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:545
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
T_HASH
#define T_HASH
Qtrue
return Qtrue
Definition: tcltklib.c:9610
cState_quirks_mode_p
static VALUE cState_quirks_mode_p(VALUE self)
Definition: generator.c:1246
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:194
rb_class_name
VALUE rb_class_name(VALUE)
Definition: variable.c:383
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:1210
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:410
JSON_Generator_StateStruct::array_delim
FBuffer * array_delim
Definition: generator.h:70
rb_str_new2
#define rb_str_new2
cState_s_allocate
static VALUE cState_s_allocate(VALUE klass)
Definition: generator.c:498
cState_allow_nan_p
static VALUE cState_allow_nan_p(VALUE self)
Definition: generator.c:1223
state
int state
Definition: tcltklib.c:1462
mTrueClass_to_json
static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:436
rb_str_substr
VALUE rb_str_substr(VALUE, long, long)
Definition: string.c:1774
i_depth
static ID i_depth
Definition: generator.c:15
rb_path2class
VALUE rb_path2class(const char *)
Definition: variable.c:371
ID2SYM
#define ID2SYM(x)
UTF16
unsigned short UTF16
Definition: generator.h:31
FBUFFER_INITIAL_LENGTH_DEFAULT
#define FBUFFER_INITIAL_LENGTH_DEFAULT
Definition: fbuffer.h:47
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1116
rb_str_concat
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2162
mString
static VALUE mString
Definition: generator.c:9
rb_cRegexp
RUBY_EXTERN VALUE rb_cRegexp
Definition: ripper.y:1454
cState
static VALUE cState
Definition: generator.c:9
keys
VALUE keys
Definition: tkutil.c:276
cState_indent
static VALUE cState_indent(VALUE self)
Definition: generator.c:1002
generate_json
static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:816
generate_json_float
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:799
cState_space_set
static VALUE cState_space_set(VALUE self, VALUE space)
Definition: generator.c:1051
JSON_Generator_StateStruct::space
char * space
Definition: generator.h:62
MEMZERO
#define MEMZERO(p, type, n)
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:456
mString_to_json
static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:381
hash
VALUE hash
Definition: tkutil.c:267
mExt
static VALUE mExt
Definition: generator.c:9
generate_json_true
static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:783
Data_Wrap_Struct
return Data_Wrap_Struct(CLASS_OF(interp), 0, ip_free, slave)
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:788
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:909
Qfalse
return Qfalse
Definition: tcltklib.c:6779
rb_intern_str
#define rb_intern_str(string)
Definition: generator.h:17
JSON_Generator_StateStruct::object_delim
FBuffer * object_delim
Definition: generator.h:71
i_encode
static ID i_encode
Definition: generator.c:6
RARRAY_LEN
#define RARRAY_LEN(a)
Qnil
#define Qnil
Definition: tcltklib.c:1896
JSON_Generator_StateStruct::array_nl_len
long array_nl_len
Definition: generator.h:69
depth
int depth
Definition: tcltklib.c:2198
cState_aset
static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
Definition: generator.c:658
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:1269
rb_cHash
RUBY_EXTERN VALUE rb_cHash
Definition: ripper.y:1440
Check_Type
#define Check_Type(v, t)
StringValueCStr
#define StringValueCStr(v)
i_indent
static ID i_indent
Definition: generator.c:15
ID
unsigned long ID
Definition: ripper.y:105
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
i_ascii_only
static ID i_ascii_only
Definition: generator.c:15
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1982
cState_indent_set
static VALUE cState_indent_set(VALUE self, VALUE indent)
Definition: generator.c:1013
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
RSTRING_LEN
#define RSTRING_LEN(str)
mFalseClass_to_json
static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:446
FIX2LONG
#define FIX2LONG(x)
T_STRING
#define T_STRING
mFloat
static VALUE mFloat
Definition: generator.c:9
convert_UTF8_to_JSON_ASCII
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
Definition: generator.c:127
cState_depth_set
static VALUE cState_depth_set(VALUE self, VALUE depth)
Definition: generator.c:1281
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
i_to_json
static ID i_to_json
Definition: generator.c:15
i_unpack
static ID i_unpack
Definition: generator.c:15
JSON_Generator_StateStruct
Definition: generator.h:59
key
static int VALUE key
Definition: tkutil.c:265
isArrayOrObject
static int isArrayOrObject(VALUE string)
Definition: generator.c:892
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:759
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_str_dup
VALUE rb_str_dup(VALUE)
Definition: string.c:946
mString_to_json_raw_object
static VALUE mString_to_json_raw_object(VALUE self)
Definition: generator.c:394
argv
VALUE * argv
Definition: tcltklib.c:1971
rb_hash_aset
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
mFloat_to_json
static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:359
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1539
RTEST
#define RTEST(v)
halfShift
static const int halfShift
Definition: generator.h:45
result
q result
Definition: tcltklib.c:7070
fstrndup
static char * fstrndup(const char *ptr, unsigned long len)
Definition: generator.c:289
value
volatile VALUE value
Definition: tcltklib.c:9442
rb_cFixnum
RUBY_EXTERN VALUE rb_cFixnum
Definition: ripper.y:1438
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:3651
strdup
#define strdup(s)
Definition: util.h:69
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
cState_to_h
static VALUE cState_to_h(VALUE self)
Definition: generator.c:619
cState_space_before
static VALUE cState_space_before(VALUE self)
Definition: generator.c:1076
length
size_t length
Definition: tcltklib.c:4559
cState_partial_generate
static VALUE cState_partial_generate(VALUE self, VALUE obj)
Definition: generator.c:879
i_allow_nan
static ID i_allow_nan
Definition: generator.c:15
T_FIXNUM
#define T_FIXNUM
argc
int argc
Definition: tcltklib.c:1970
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:1235
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
isinf
RUBY_EXTERN int isinf(double)
Definition: isinf.c:56
isnan
#define isnan(x)
Definition: win32.h:327
mObject_to_json
static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:468
Init_generator
void Init_generator()
Definition: generator.c:1321
i_create_id
static ID i_create_id
Definition: generator.c:15
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ripper.y:1456
ptr
return ptr
Definition: tcltklib.c:784
c
VpDivd * c
Definition: bigdecimal.c:1205
MEMCPY
#define MEMCPY(p1, p2, type, n)
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:637
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
end
gz end
Definition: zlib.c:2272
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:672
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1128
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:849
cState_aref
static VALUE cState_aref(VALUE self, VALUE name)
Definition: generator.c:643
UNI_MAX_BMP
#define UNI_MAX_BMP
Definition: generator.h:35
cState_quirks_mode_set
static VALUE cState_quirks_mode_set(VALUE self, VALUE enable)
Definition: generator.c:1257
rb_cBignum
VALUE rb_cBignum
Definition: bignum.c:28
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
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:601
cState_object_nl_set
static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
Definition: generator.c:1125
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:773
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
ALLOC_N
#define ALLOC_N(type, n)
LONG2FIX
#define LONG2FIX(i)
i_key_p
static ID i_key_p
Definition: generator.c:15
klass
klass
Definition: tcltklib.c:3504
Data_Get_Struct
#define Data_Get_Struct(obj, type, sval)
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1564
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:29
cState_buffer_initial_length_set
static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length)
Definition: generator.c:1306
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:425
i_encoding
static ID i_encoding
Definition: generator.c:6
FBufferStruct
Definition: fbuffer.h:40
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:234
rb_str_intern
VALUE rb_str_intern(VALUE)
Definition: string.c:7211
cState_buffer_initial_length
static VALUE cState_buffer_initial_length(VALUE self)
Definition: generator.c:1294
cState_init_copy
static VALUE cState_init_copy(VALUE obj, VALUE orig)
Definition: generator.c:956
cState_space
static VALUE cState_space(VALUE self)
Definition: generator.c:1039
rb_hash_aref
VALUE rb_hash_aref(VALUE, VALUE)
Definition: hash.c:560
opts
VALUE opts
Definition: tcltklib.c:6146
VALUE
unsigned long VALUE
Definition: ripper.y:104
mBignum_to_json
static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:349
FBUFFER_LEN
#define FBUFFER_LEN(fb)
Definition: fbuffer.h:50
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:617
rb_intern
#define rb_intern(str)
NULL
#define NULL
Definition: _sdbm.c:103
q
q
Definition: tcltklib.c:2968
name
const char * name
Definition: nkf.c:208
mHash_to_json
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
Definition: generator.c:317
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
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:512
rb_convert_type
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2368
generate_json_bignum
static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
Definition: generator.c:793
GET_STATE
#define GET_STATE(self)
Definition: generator.h:81
mString_included_s
static VALUE mString_included_s(VALUE self, VALUE modul)
Definition: generator.c:369
State_free
static void State_free(JSON_Generator_State *state)
Definition: generator.c:478
len
size_t len
Definition: tcltklib.c:3568