json_pure 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/CHANGES +25 -0
  2. data/GPL +340 -0
  3. data/README +77 -0
  4. data/Rakefile +250 -0
  5. data/TODO +1 -0
  6. data/VERSION +1 -0
  7. data/benchmarks/benchmark.txt +133 -0
  8. data/benchmarks/benchmark_generator.rb +44 -0
  9. data/benchmarks/benchmark_parser.rb +22 -0
  10. data/benchmarks/benchmark_rails.rb +26 -0
  11. data/bin/edit_json.rb +11 -0
  12. data/data/example.json +1 -0
  13. data/data/index.html +37 -0
  14. data/data/prototype.js +2515 -0
  15. data/ext/json/ext/generator/Makefile +149 -0
  16. data/ext/json/ext/generator/extconf.rb +9 -0
  17. data/ext/json/ext/generator/generator.c +729 -0
  18. data/ext/json/ext/generator/unicode.c +184 -0
  19. data/ext/json/ext/generator/unicode.h +40 -0
  20. data/ext/json/ext/parser/Makefile +149 -0
  21. data/ext/json/ext/parser/extconf.rb +9 -0
  22. data/ext/json/ext/parser/parser.c +1551 -0
  23. data/ext/json/ext/parser/parser.rl +515 -0
  24. data/ext/json/ext/parser/unicode.c +156 -0
  25. data/ext/json/ext/parser/unicode.h +44 -0
  26. data/install.rb +26 -0
  27. data/lib/json.rb +205 -0
  28. data/lib/json/Array.xpm +21 -0
  29. data/lib/json/FalseClass.xpm +21 -0
  30. data/lib/json/Hash.xpm +21 -0
  31. data/lib/json/Key.xpm +73 -0
  32. data/lib/json/NilClass.xpm +21 -0
  33. data/lib/json/Numeric.xpm +28 -0
  34. data/lib/json/String.xpm +96 -0
  35. data/lib/json/TrueClass.xpm +21 -0
  36. data/lib/json/common.rb +184 -0
  37. data/lib/json/editor.rb +1207 -0
  38. data/lib/json/ext.rb +13 -0
  39. data/lib/json/json.xpm +1499 -0
  40. data/lib/json/pure.rb +75 -0
  41. data/lib/json/pure/generator.rb +321 -0
  42. data/lib/json/pure/parser.rb +210 -0
  43. data/lib/json/version.rb +8 -0
  44. data/tests/fixtures/fail1.json +1 -0
  45. data/tests/fixtures/fail10.json +1 -0
  46. data/tests/fixtures/fail11.json +1 -0
  47. data/tests/fixtures/fail12.json +1 -0
  48. data/tests/fixtures/fail13.json +1 -0
  49. data/tests/fixtures/fail14.json +1 -0
  50. data/tests/fixtures/fail15.json +1 -0
  51. data/tests/fixtures/fail16.json +1 -0
  52. data/tests/fixtures/fail17.json +1 -0
  53. data/tests/fixtures/fail19.json +1 -0
  54. data/tests/fixtures/fail2.json +1 -0
  55. data/tests/fixtures/fail20.json +1 -0
  56. data/tests/fixtures/fail21.json +1 -0
  57. data/tests/fixtures/fail22.json +1 -0
  58. data/tests/fixtures/fail23.json +1 -0
  59. data/tests/fixtures/fail24.json +1 -0
  60. data/tests/fixtures/fail25.json +1 -0
  61. data/tests/fixtures/fail26.json +1 -0
  62. data/tests/fixtures/fail27.json +2 -0
  63. data/tests/fixtures/fail28.json +2 -0
  64. data/tests/fixtures/fail3.json +1 -0
  65. data/tests/fixtures/fail4.json +1 -0
  66. data/tests/fixtures/fail5.json +1 -0
  67. data/tests/fixtures/fail6.json +1 -0
  68. data/tests/fixtures/fail7.json +1 -0
  69. data/tests/fixtures/fail8.json +1 -0
  70. data/tests/fixtures/fail9.json +1 -0
  71. data/tests/fixtures/pass1.json +56 -0
  72. data/tests/fixtures/pass18.json +1 -0
  73. data/tests/fixtures/pass2.json +1 -0
  74. data/tests/fixtures/pass3.json +6 -0
  75. data/tests/runner.rb +24 -0
  76. data/tests/test_json.rb +235 -0
  77. data/tests/test_json_addition.rb +94 -0
  78. data/tests/test_json_fixtures.rb +30 -0
  79. data/tests/test_json_generate.rb +81 -0
  80. data/tests/test_json_unicode.rb +55 -0
  81. data/tools/fuzz.rb +133 -0
  82. data/tools/server.rb +62 -0
  83. metadata +146 -0
@@ -0,0 +1,156 @@
1
+ /* vim: set cin et sw=4 ts=4: */
2
+
3
+ #include "unicode.h"
4
+
5
+ /*
6
+ * Copyright 2001-2004 Unicode, Inc.
7
+ *
8
+ * Disclaimer
9
+ *
10
+ * This source code is provided as is by Unicode, Inc. No claims are
11
+ * made as to fitness for any particular purpose. No warranties of any
12
+ * kind are expressed or implied. The recipient agrees to determine
13
+ * applicability of information provided. If this file has been
14
+ * purchased on magnetic or optical media from Unicode, Inc., the
15
+ * sole remedy for any claim will be exchange of defective media
16
+ * within 90 days of receipt.
17
+ *
18
+ * Limitations on Rights to Redistribute This Code
19
+ *
20
+ * Unicode, Inc. hereby grants the right to freely use the information
21
+ * supplied in this file in the creation of products supporting the
22
+ * Unicode Standard, and to make copies of this file in any form
23
+ * for internal or external distribution as long as this notice
24
+ * remains attached.
25
+ */
26
+
27
+ /*
28
+ * Index into the table below with the first byte of a UTF-8 sequence to
29
+ * get the number of trailing bytes that are supposed to follow it.
30
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
31
+ * left as-is for anyone who may want to do such conversion, which was
32
+ * allowed in earlier algorithms.
33
+ */
34
+ static const char trailingBytesForUTF8[256] = {
35
+ 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,
36
+ 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,
37
+ 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,
38
+ 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,
39
+ 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,
40
+ 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,
41
+ 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,
42
+ 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
43
+ };
44
+
45
+ /*
46
+ * Magic values subtracted from a buffer value during UTF8 conversion.
47
+ * This table contains as many values as there might be trailing bytes
48
+ * in a UTF-8 sequence.
49
+ */
50
+ static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
51
+ 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
52
+
53
+ /*
54
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
55
+ * into the first byte, depending on how many bytes follow. There are
56
+ * as many entries in this table as there are UTF-8 sequence types.
57
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
58
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
59
+ */
60
+ static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
61
+
62
+ inline char *JSON_convert_UTF16_to_UTF8 (
63
+ VALUE buffer,
64
+ char *source,
65
+ char *sourceEnd,
66
+ ConversionFlags flags)
67
+ {
68
+ UTF16 *tmp, *tmpPtr, *tmpEnd;
69
+ char buf[5];
70
+ long n = 0, i;
71
+ char *p = source - 1;
72
+
73
+ while (p < sourceEnd && p[0] == '\\' && p[1] == 'u') {
74
+ p += 6;
75
+ n++;
76
+ }
77
+ p = source + 1;
78
+ buf[4] = 0;
79
+ tmpPtr = tmp = ALLOC_N(UTF16, n);
80
+ tmpEnd = tmp + n;
81
+ for (i = 0; i < n; i++) {
82
+ buf[0] = *p++;
83
+ buf[1] = *p++;
84
+ buf[2] = *p++;
85
+ buf[3] = *p++;
86
+ tmpPtr[i] = strtol(buf, NULL, 16);
87
+ p += 2;
88
+ }
89
+
90
+ while (tmpPtr < tmpEnd) {
91
+ UTF32 ch;
92
+ unsigned short bytesToWrite = 0;
93
+ const UTF32 byteMask = 0xBF;
94
+ const UTF32 byteMark = 0x80;
95
+ ch = *tmpPtr++;
96
+ /* If we have a surrogate pair, convert to UTF32 first. */
97
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
98
+ /* If the 16 bits following the high surrogate are in the source
99
+ * buffer... */
100
+ if (tmpPtr < tmpEnd) {
101
+ UTF32 ch2 = *tmpPtr;
102
+ /* If it's a low surrogate, convert to UTF32. */
103
+ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
104
+ ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
105
+ + (ch2 - UNI_SUR_LOW_START) + halfBase;
106
+ ++tmpPtr;
107
+ } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
108
+ free(tmp);
109
+ rb_raise(rb_path2class("JSON::ParserError"),
110
+ "source sequence is illegal/malformed near %s", source);
111
+ }
112
+ } else { /* We don't have the 16 bits following the high surrogate. */
113
+ free(tmp);
114
+ rb_raise(rb_path2class("JSON::ParserError"),
115
+ "partial character in source, but hit end near %s", source);
116
+ break;
117
+ }
118
+ } else if (flags == strictConversion) {
119
+ /* UTF-16 surrogate values are illegal in UTF-32 */
120
+ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
121
+ free(tmp);
122
+ rb_raise(rb_path2class("JSON::ParserError"),
123
+ "source sequence is illegal/malformed near %s", source);
124
+ }
125
+ }
126
+ /* Figure out how many bytes the result will require */
127
+ if (ch < (UTF32) 0x80) {
128
+ bytesToWrite = 1;
129
+ } else if (ch < (UTF32) 0x800) {
130
+ bytesToWrite = 2;
131
+ } else if (ch < (UTF32) 0x10000) {
132
+ bytesToWrite = 3;
133
+ } else if (ch < (UTF32) 0x110000) {
134
+ bytesToWrite = 4;
135
+ } else {
136
+ bytesToWrite = 3;
137
+ ch = UNI_REPLACEMENT_CHAR;
138
+ }
139
+
140
+ buf[0] = 0;
141
+ buf[1] = 0;
142
+ buf[2] = 0;
143
+ buf[3] = 0;
144
+ p = buf + bytesToWrite;
145
+ switch (bytesToWrite) { /* note: everything falls through. */
146
+ case 4: *--p = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6;
147
+ case 3: *--p = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6;
148
+ case 2: *--p = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6;
149
+ case 1: *--p = (UTF8) (ch | firstByteMark[bytesToWrite]);
150
+ }
151
+ rb_str_buf_cat(buffer, p, bytesToWrite);
152
+ }
153
+ free(tmp);
154
+ source += 5 + (n - 1) * 6;
155
+ return source;
156
+ }
@@ -0,0 +1,44 @@
1
+
2
+ #ifndef _PARSER_UNICODE_H_
3
+ #define _PARSER_UNICODE_H_
4
+
5
+ #include "ruby.h"
6
+
7
+ typedef unsigned long UTF32; /* at least 32 bits */
8
+ typedef unsigned short UTF16; /* at least 16 bits */
9
+ typedef unsigned char UTF8; /* typically 8 bits */
10
+
11
+ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
12
+ #define UNI_MAX_BMP (UTF32)0x0000FFFF
13
+ #define UNI_MAX_UTF16 (UTF32)0x0010FFFF
14
+ #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
15
+ #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
16
+
17
+ #define UNI_SUR_HIGH_START (UTF32)0xD800
18
+ #define UNI_SUR_HIGH_END (UTF32)0xDBFF
19
+ #define UNI_SUR_LOW_START (UTF32)0xDC00
20
+ #define UNI_SUR_LOW_END (UTF32)0xDFFF
21
+
22
+ static const int halfShift = 10; /* used for shifting by 10 bits */
23
+
24
+ static const UTF32 halfBase = 0x0010000UL;
25
+ static const UTF32 halfMask = 0x3FFUL;
26
+
27
+ typedef enum {
28
+ conversionOK = 0, /* conversion successful */
29
+ sourceExhausted, /* partial character in source, but hit end */
30
+ targetExhausted, /* insuff. room in target for conversion */
31
+ sourceIllegal /* source sequence is illegal/malformed */
32
+ } ConversionResult;
33
+
34
+ typedef enum {
35
+ strictConversion = 0,
36
+ lenientConversion
37
+ } ConversionFlags;
38
+
39
+ char *JSON_convert_UTF16_to_UTF8 (
40
+ VALUE buffer,
41
+ char *source,
42
+ char *sourceEnd,
43
+ ConversionFlags flags);
44
+ #endif
data/install.rb ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rbconfig'
4
+ require 'fileutils'
5
+ include FileUtils::Verbose
6
+
7
+ include Config
8
+
9
+ bindir = CONFIG["bindir"]
10
+ cd 'bin' do
11
+ filename = 'edit_json.rb'
12
+ #install(filename, bindir)
13
+ end
14
+ sitelibdir = CONFIG["sitelibdir"]
15
+ cd 'lib' do
16
+ install('json.rb', sitelibdir)
17
+ mkdir_p File.join(sitelibdir, 'json')
18
+ for file in Dir['json/**/*.{rb,xpm}']
19
+ d = File.join(sitelibdir, file)
20
+ mkdir_p File.dirname(d)
21
+ install(file, d)
22
+ end
23
+ install(File.join('json', 'editor.rb'), File.join(sitelibdir,'json'))
24
+ install(File.join('json', 'json.xpm'), File.join(sitelibdir,'json'))
25
+ end
26
+ warn " *** Installed PURE ruby library."
data/lib/json.rb ADDED
@@ -0,0 +1,205 @@
1
+ require 'json/common'
2
+ # = json - JSON for Ruby
3
+ #
4
+ # == Description
5
+ #
6
+ # This is a implementation of the JSON specification according to RFC 4627
7
+ # (http://www.ietf.org/rfc/rfc4627.txt). Starting from version 1.0.0 on there
8
+ # will be two variants available:
9
+ #
10
+ # * A pure ruby variant, that relies on the iconv and the stringscan
11
+ # extensions, which are both part of the ruby standard library.
12
+ # * The quite a bit faster C extension variant, which is in parts implemented
13
+ # in C and comes with its own unicode conversion functions and a parser
14
+ # generated by the ragel state machine compiler
15
+ # (http://www.cs.queensu.ca/~thurston/ragel).
16
+ #
17
+ # Both variants of the JSON generator escape all non-ASCII an control
18
+ # characters with \uXXXX escape sequences, and support UTF-16 surrogate pairs
19
+ # in order to be able to generate the whole range of unicode code points. This
20
+ # means that generated JSON text is encoded as UTF-8 (because ASCII is a subset
21
+ # of UTF-8) and at the same time avoids decoding problems for receiving
22
+ # endpoints, that don't expect UTF-8 encoded texts. On the negative side this
23
+ # may lead to a bit longer strings than necessarry.
24
+ #
25
+ # All strings, that are to be encoded as JSON strings, should be UTF-8 byte
26
+ # sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8
27
+ # encoded, please use the to_json_raw_object method of String (which produces
28
+ # an object, that contains a byte array) and decode the result on the receiving
29
+ # endpoint.
30
+ #
31
+ # == Author
32
+ #
33
+ # Florian Frank <mailto:flori@ping.de>
34
+ #
35
+ # == License
36
+ #
37
+ # This is free software; you can redistribute it and/or modify it under the
38
+ # terms of the GNU General Public License Version 2 as published by the Free
39
+ # Software Foundation: www.gnu.org/copyleft/gpl.html
40
+ #
41
+ # == Download
42
+ #
43
+ # The latest version of this library can be downloaded at
44
+ #
45
+ # * http://rubyforge.org/frs?group_id=953
46
+ #
47
+ # Online Documentation should be located at
48
+ #
49
+ # * http://json.rubyforge.org
50
+ #
51
+ # == Speed Comparisons
52
+ #
53
+ # I have created some benchmark results (see the benchmarks subdir of the
54
+ # package) for the JSON-Parser to estimate the speed up in the C extension:
55
+ #
56
+ # JSON::Pure::Parser:: 28.90 calls/second
57
+ # JSON::Ext::Parser:: 505.50 calls/second
58
+ #
59
+ # This is ca. <b>17.5</b> times the speed of the pure Ruby implementation.
60
+ #
61
+ # I have benchmarked the JSON-Generator as well. This generates a few more
62
+ # values, because there are different modes, that also influence the achieved
63
+ # speed:
64
+ #
65
+ # * JSON::Pure::Generator:
66
+ # generate:: 35.06 calls/second
67
+ # pretty_generate:: 34.00 calls/second
68
+ # fast_generate:: 41.06 calls/second
69
+ #
70
+ # * JSON::Ext::Generator:
71
+ # generate:: 492.11 calls/second
72
+ # pretty_generate:: 348.85 calls/second
73
+ # fast_generate:: 541.60 calls/second
74
+ #
75
+ # * Speedup Ext/Pure:
76
+ # generate safe:: 14.0 times
77
+ # generate pretty:: 10.3 times
78
+ # generate fast:: 13.2 times
79
+ #
80
+ # The rails framework includes a generator as well, also it seems to be rather
81
+ # slow: I measured only 23.87 calls/second which is slower than any of my pure
82
+ # generator results. Here a comparison of the different speedups with the Rails
83
+ # measurement as the divisor:
84
+ #
85
+ # * Speedup Pure/Rails:
86
+ # generate safe:: 1.5 times
87
+ # generate pretty:: 1.4 times
88
+ # generate fast:: 1.7 times
89
+ #
90
+ # * Speedup Ext/Rails:
91
+ # generate safe:: 20.6 times
92
+ # generate pretty:: 14.6 times
93
+ # generate fast:: 22.7 times
94
+ #
95
+ # To achieve the fastest JSON text output, you can use the
96
+ # fast_generate/fast_unparse methods. Beware, that this will disable the
97
+ # checking for circular Ruby data structures, which may cause JSON to go into
98
+ # an infinite loop.
99
+ #
100
+ # == Examples
101
+ #
102
+ # To create a JSON text from a ruby data structure, you
103
+ # can call JSON.generate (or JSON.unparse) like that:
104
+ #
105
+ # json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
106
+ # # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
107
+ #
108
+ # It's also possible to call the #to_json method directly.
109
+ #
110
+ # json = [1, 2, {"a"=>3.141}, false, true, nil, 4..10].to_json
111
+ # # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
112
+ #
113
+ # To create a valid JSON text you have to make sure, that the output is
114
+ # embedded in either a JSON array [] or a JSON object {}. The easiest way to do
115
+ # this, is by putting your values in a Ruby Array or Hash instance.
116
+ #
117
+ # To get back a ruby data structure from a JSON text, you have to call
118
+ # JSON.parse on it:
119
+ #
120
+ # JSON.parse json
121
+ # # => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
122
+ #
123
+ # Note, that the range from the original data structure is a simple
124
+ # string now. The reason for this is, that JSON doesn't support ranges
125
+ # or arbitrary classes. In this case the json library falls back to call
126
+ # Object#to_json, which is the same as #to_s.to_json.
127
+ #
128
+ # It's possible to extend JSON to support serialization of arbitrary classes by
129
+ # simply implementing a more specialized version of the #to_json method, that
130
+ # should return a JSON object (a hash converted to JSON with #to_json)
131
+ # like this (don't forget the *a for all the arguments):
132
+ #
133
+ # class Range
134
+ # def to_json(*a)
135
+ # {
136
+ # 'json_class' => self.class.name, # = 'Range'
137
+ # 'data' => [ first, last, exclude_end? ]
138
+ # }.to_json(*a)
139
+ # end
140
+ # end
141
+ #
142
+ # The hash key 'json_class' is the class, that will be asked to deserialize the
143
+ # JSON representation later. In this case it's 'Range', but any namespace of
144
+ # the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be
145
+ # used to store the necessary data to configure the object to be deserialized.
146
+ #
147
+ # If a the key 'json_class' is found in a JSON object, the JSON parser checks
148
+ # if the given class responds to the json_create class method. If so, it is
149
+ # called with the JSON object converted to a Ruby hash. So a range can
150
+ # be deserialized by implementing Range.json_create like this:
151
+ #
152
+ # class Range
153
+ # def self.json_create(o)
154
+ # new(*o['data'])
155
+ # end
156
+ # end
157
+ #
158
+ # Now it possible to serialize/deserialize ranges as well:
159
+ #
160
+ # json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
161
+ # # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
162
+ # JSON.parse json
163
+ # # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
164
+ #
165
+ # JSON.generate always creates the shortest possible string representation of a
166
+ # ruby data structure in one line. This good for data storage or network
167
+ # protocols, but not so good for humans to read. Fortunately there's also
168
+ # JSON.pretty_generate (or JSON.pretty_generate) that creates a more
169
+ # readable output:
170
+ #
171
+ # puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
172
+ # [
173
+ # 1,
174
+ # 2,
175
+ # {
176
+ # "a": 3.141
177
+ # },
178
+ # false,
179
+ # true,
180
+ # null,
181
+ # {
182
+ # "json_class": "Range",
183
+ # "data": [
184
+ # 4,
185
+ # 10,
186
+ # false
187
+ # ]
188
+ # }
189
+ # ]
190
+ #
191
+ # There are also the methods Kernel#j for unparse, and Kernel#jj for
192
+ # pretty_unparse output to the console, that work analogous to Core Ruby's p
193
+ # and the pp library's pp methods.
194
+ #
195
+ # The script tools/server.rb contains a small example if you want to test, how
196
+ # receiving a JSON object from a webrick server in your browser with the
197
+ # javasript prototype library (http://www.prototypejs.org) works.
198
+ #
199
+ module JSON
200
+ begin
201
+ require 'json/ext'
202
+ rescue LoadError
203
+ require 'json/pure'
204
+ end
205
+ end
@@ -0,0 +1,21 @@
1
+ /* XPM */
2
+ static char * Array_xpm[] = {
3
+ "16 16 2 1",
4
+ " c None",
5
+ ". c #000000",
6
+ " ",
7
+ " ",
8
+ " ",
9
+ " .......... ",
10
+ " . . ",
11
+ " . . ",
12
+ " . . ",
13
+ " . . ",
14
+ " . . ",
15
+ " . . ",
16
+ " . . ",
17
+ " . . ",
18
+ " .......... ",
19
+ " ",
20
+ " ",
21
+ " "};