engineyard-serverside 2.0.5 → 2.0.6

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