yajl-ruby 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of yajl-ruby might be problematic. Click here for more details.

@@ -5,9 +5,24 @@
5
5
  #define READ_BUFSIZE 8092
6
6
  #define WRITE_BUFSIZE 8092
7
7
 
8
+ // Older versions of Ruby (< 1.8.6) need these
9
+ #ifndef RSTRING_PTR
10
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
11
+ #endif
12
+ #ifndef RSTRING_LEN
13
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
14
+ #endif
15
+ #ifndef RARRAY_PTR
16
+ #define RARRAY_PTR(s) (RARRAY(s)->ptr)
17
+ #endif
18
+ #ifndef RARRAY_LEN
19
+ #define RARRAY_LEN(s) (RARRAY(s)->len)
20
+ #endif
21
+
8
22
  static VALUE cParseError, cEncodeError, mYajl, cParser, cEncoder;
9
- static ID intern_io_read, intern_eof, intern_call, intern_keys, intern_to_s, intern_to_json, intern_has_key,
10
- sym_allow_comments, sym_check_utf8, sym_pretty, sym_indent, sym_terminator, sym_symbolize_keys;
23
+ static ID intern_io_read, intern_eof, intern_call, intern_keys, intern_to_s,
24
+ intern_to_json, intern_has_key, intern_to_sym;
25
+ static ID sym_allow_comments, sym_check_utf8, sym_pretty, sym_indent, sym_terminator, sym_symbolize_keys;
11
26
 
12
27
  #define GetParser(obj, sval) (sval = (struct yajl_parser_wrapper*)DATA_PTR(obj));
13
28
  #define GetEncoder(obj, sval) (sval = (struct yajl_encoder_wrapper*)DATA_PTR(obj));
@@ -80,4 +95,6 @@ static VALUE rb_yajl_json_ext_string_to_json(int argc, VALUE * argv, VALUE self)
80
95
  static VALUE rb_yajl_json_ext_true_to_json(int argc, VALUE * argv, VALUE self);
81
96
  static VALUE rb_yajl_json_ext_false_to_json(int argc, VALUE * argv, VALUE self);
82
97
  static VALUE rb_yajl_json_ext_nil_to_json(int argc, VALUE * argv, VALUE self);
83
- static VALUE rb_yajl_encoder_enable_json_gem_ext(VALUE klass);
98
+ static VALUE rb_yajl_encoder_enable_json_gem_ext(VALUE klass);
99
+
100
+ void Init_yajl_ext();
@@ -37,6 +37,7 @@
37
37
  #include <stdlib.h>
38
38
  #include <string.h>
39
39
  #include <stdio.h>
40
+ #include <math.h>
40
41
 
41
42
  typedef enum {
42
43
  yajl_gen_start,
@@ -166,11 +167,19 @@ yajl_gen_integer(yajl_gen g, long int number)
166
167
  return yajl_gen_status_ok;
167
168
  }
168
169
 
170
+ #ifdef WIN32
171
+ #include <float.h>
172
+ #define isnan _isnan
173
+ #define isinf _finite
174
+ #endif
175
+
169
176
  yajl_gen_status
170
177
  yajl_gen_double(yajl_gen g, double number)
171
178
  {
172
179
  char i[32];
173
- ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
180
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY;
181
+ if (isnan(number) || isinf(number)) return yajl_gen_invalid_number;
182
+ INSERT_SEP; INSERT_WHITESPACE;
174
183
  sprintf(i, "%g", number);
175
184
  yajl_buf_append(g->buf, i, strlen(i));
176
185
  APPENDED_ATOM;
@@ -307,8 +307,8 @@ yajl_do_parse(yajl_handle hand, unsigned int * offset,
307
307
  {
308
308
  yajl_state s = yajl_bs_current(hand->stateStack);
309
309
  if (s == yajl_state_start) {
310
- // HACK: is this even safe to do?
311
- // yajl_bs_set(hand->stateStack, yajl_state_parse_complete);
310
+ /* HACK: is this even safe to do?
311
+ yajl_bs_set(hand->stateStack, yajl_state_parse_complete); */
312
312
  yajl_reset_parser(hand);
313
313
  } else if (s == yajl_state_map_need_val) {
314
314
  yajl_bs_set(hand->stateStack, yajl_state_map_got_val);
@@ -13,7 +13,17 @@ require 'yajl_ext'
13
13
  #
14
14
  # Ruby bindings to the excellent Yajl (Yet Another JSON Parser) ANSI C library.
15
15
  module Yajl
16
- VERSION = "0.6.3"
16
+ VERSION = "0.6.4"
17
+
18
+ # For compatibility, has the same signature of Yajl::Parser.parse
19
+ def self.load(str_or_io, options={}, read_bufsize=nil, &block)
20
+ Parser.parse(str_or_io, options, read_bufsize, &block)
21
+ end
22
+
23
+ # For compatibility, has the same signature of Yajl::Encoder.encode
24
+ def self.dump(obj, *args, &block)
25
+ Encoder.encode(obj, args, &block)
26
+ end
17
27
 
18
28
  class Parser
19
29
  # A helper method for parse-and-forget use-cases
@@ -25,8 +35,8 @@ module Yajl
25
35
  # :allow_comments accepts a boolean will enable/disable checks for in-line comments in the JSON stream
26
36
  #
27
37
  # :check_utf8 accepts a boolean will enable/disable UTF8 validation for the JSON stream
28
- def self.parse(io, options={}, read_bufsize=nil, &block)
29
- new(options).parse(io, read_bufsize, &block)
38
+ def self.parse(str_or_io, options={}, read_bufsize=nil, &block)
39
+ new(options).parse(str_or_io, read_bufsize, &block)
30
40
  end
31
41
  end
32
42
 
@@ -52,6 +62,7 @@ module Yajl
52
62
  # If a block is passed, it will be used as (and work the same as) the +on_progress+ callback
53
63
  def self.encode(obj, *args, &block)
54
64
  # TODO: this code smells, any ideas?
65
+ args.flatten!
55
66
  options = {}
56
67
  io = nil
57
68
  args.each do |arg|
@@ -68,15 +79,15 @@ module Yajl
68
79
  # DEPRECATED - See Yajl::Parser and Yajl::Encoder
69
80
  module Stream
70
81
  # DEPRECATED - See Yajl::Parser
71
- def self.parse(io)
72
- STDERR.puts "WARNING: Yajl::Stream has be deprecated and will most likely be gone in the next release. Use the Yajl::Parser class instead."
73
- Parser.new.parse(io)
82
+ def self.parse(str_or_io)
83
+ warn "WARNING: Yajl::Stream has be deprecated and will most likely be gone in the next release. Use the Yajl::Parser class instead."
84
+ Parser.new.parse(str_or_io)
74
85
  end
75
86
 
76
87
  # DEPRECATED - See Yajl::Encoder
77
- def self.encode(obj, io)
78
- STDERR.puts "WARNING: Yajl::Stream has be deprecated and will most likely be gone in the next release. Use the Yajl::Encoder class instead."
79
- Encoder.new.encode(obj, io)
88
+ def self.encode(obj, str_or_io=nil)
89
+ warn "WARNING: Yajl::Stream has be deprecated and will most likely be gone in the next release. Use the Yajl::Encoder class instead."
90
+ Encoder.new.encode(obj, str_or_io)
80
91
  end
81
92
  end
82
93
  end
@@ -13,6 +13,9 @@ class Object
13
13
  end
14
14
 
15
15
  module JSON
16
+ class JSONError < StandardError; end unless defined?(JSON::JSONError)
17
+ class GeneratorError < JSONError; end unless defined?(JSON::GeneratorError)
18
+
16
19
  def self.generate(obj, opts={})
17
20
  begin
18
21
  options_map = {}
@@ -21,8 +24,8 @@ module JSON
21
24
  options_map[:indent] = opts[:indent]
22
25
  end
23
26
  Yajl::Encoder.encode(obj, options_map)
24
- rescue Yajl::ParseError => e
25
- raise JSON::ParserError, e.message
27
+ rescue Yajl::EncodeError => e
28
+ raise JSON::GeneratorError, e.message
26
29
  end
27
30
  end
28
31
 
@@ -32,16 +35,16 @@ module JSON
32
35
  options_map[:pretty] = true
33
36
  options_map[:indent] = opts[:indent] if opts.has_key?(:indent)
34
37
  Yajl::Encoder.encode(obj, options_map)
35
- rescue Yajl::ParseError => e
36
- raise JSON::ParserError, e.message
38
+ rescue Yajl::EncodeError => e
39
+ raise JSON::GeneratorError, e.message
37
40
  end
38
41
  end
39
42
 
40
43
  def self.dump(obj, io=nil, *args)
41
44
  begin
42
45
  Yajl::Encoder.encode(obj, io)
43
- rescue Yajl::ParseError => e
44
- raise JSON::ParserError, e.message
46
+ rescue Yajl::EncodeError => e
47
+ raise JSON::GeneratorError, e.message
45
48
  end
46
49
  end
47
50
  end
@@ -2,7 +2,8 @@
2
2
  require 'yajl' unless defined?(Yajl::Parser)
3
3
 
4
4
  module JSON
5
- class ParserError < Yajl::ParseError; end
5
+ class JSONError < StandardError; end unless defined?(JSON::JSONError)
6
+ class ParserError < JSONError; end unless defined?(JSON::ParserError)
6
7
 
7
8
  def self.default_options
8
9
  @default_options ||= {:symbolize_keys => false}
@@ -11,62 +11,59 @@ describe "Yajl JSON encoder" do
11
11
  FILES = Dir[File.dirname(__FILE__)+'/../../benchmark/subjects/*.json']
12
12
 
13
13
  FILES.each do |file|
14
- it "should encode #{File.basename(file)} to an IO" do
15
- # we don't care about testing the stream subject as it has multiple JSON strings in it
16
- if File.basename(file) != 'twitter_stream.json'
17
- input = File.new(File.expand_path(file), 'r')
18
- io = StringIO.new
19
- encoder = Yajl::Encoder.new
20
- hash = Yajl::Parser.parse(input)
21
- encoder.encode(hash, io)
22
- io.rewind
23
- hash2 = Yajl::Parser.parse(io)
24
- io.close
25
- input.close
26
- hash.should == hash2
27
- end
28
- end
29
- end
30
-
31
- FILES.each do |file|
32
- it "should encode #{File.basename(file)} and return a String" do
33
- # we don't care about testing the stream subject as it has multiple JSON strings in it
34
- if File.basename(file) != 'twitter_stream.json'
35
- input = File.new(File.expand_path(file), 'r')
36
- encoder = Yajl::Encoder.new
37
- hash = Yajl::Parser.parse(input)
38
- output = encoder.encode(hash)
39
- hash2 = Yajl::Parser.parse(output)
40
- input.close
41
- hash.should == hash2
42
- end
43
- end
44
- end
45
-
46
- FILES.each do |file|
47
- it "should encode #{File.basename(file)} call the passed block, passing it a String" do
48
- # we don't care about testing the stream subject as it has multiple JSON strings in it
49
- if File.basename(file) != 'twitter_stream.json'
50
- input = File.new(File.expand_path(file), 'r')
51
- encoder = Yajl::Encoder.new
52
- hash = Yajl::Parser.parse(input)
53
- output = ''
54
- encoder.encode(hash) do |json_str|
55
- output << json_str
56
- end
57
- hash2 = Yajl::Parser.parse(output)
58
- input.close
59
- hash.should == hash2
60
- end
61
- end
62
- end
14
+ it "should encode #{File.basename(file)} to an IO" do
15
+ # we don't care about testing the stream subject as it has multiple JSON strings in it
16
+ if File.basename(file) != 'twitter_stream.json'
17
+ input = File.new(File.expand_path(file), 'r')
18
+ io = StringIO.new
19
+ encoder = Yajl::Encoder.new
20
+ hash = Yajl::Parser.parse(input)
21
+ encoder.encode(hash, io)
22
+ io.rewind
23
+ hash2 = Yajl::Parser.parse(io)
24
+ io.close
25
+ input.close
26
+ hash.should == hash2
27
+ end
28
+ end
29
+ end
30
+
31
+ FILES.each do |file|
32
+ it "should encode #{File.basename(file)} and return a String" do
33
+ # we don't care about testing the stream subject as it has multiple JSON strings in it
34
+ if File.basename(file) != 'twitter_stream.json'
35
+ input = File.new(File.expand_path(file), 'r')
36
+ encoder = Yajl::Encoder.new
37
+ hash = Yajl::Parser.parse(input)
38
+ output = encoder.encode(hash)
39
+ hash2 = Yajl::Parser.parse(output)
40
+ input.close
41
+ hash.should == hash2
42
+ end
43
+ end
44
+ end
45
+
46
+ FILES.each do |file|
47
+ it "should encode #{File.basename(file)} call the passed block, passing it a String" do
48
+ # we don't care about testing the stream subject as it has multiple JSON strings in it
49
+ if File.basename(file) != 'twitter_stream.json'
50
+ input = File.new(File.expand_path(file), 'r')
51
+ encoder = Yajl::Encoder.new
52
+ hash = Yajl::Parser.parse(input)
53
+ output = ''
54
+ encoder.encode(hash) do |json_str|
55
+ output << json_str
56
+ end
57
+ hash2 = Yajl::Parser.parse(output)
58
+ input.close
59
+ hash.should == hash2
60
+ end
61
+ end
62
+ end
63
63
 
64
64
  it "should encode with :pretty turned on and a single space indent, to an IO" do
65
- output = "{\n \"foo\": {\n \"name\": \"bar\",\n \"id\": 1234\n }\n}"
66
- if RUBY_VERSION.include?('1.9') # FIXME
67
- output = "{\n \"foo\": {\n \"id\": 1234,\n \"name\": \"bar\"\n }\n}"
68
- end
69
- obj = {:foo => {:id => 1234, :name => "bar"}}
65
+ output = "{\n \"foo\": 1234\n}"
66
+ obj = {:foo => 1234}
70
67
  io = StringIO.new
71
68
  encoder = Yajl::Encoder.new(:pretty => true, :indent => ' ')
72
69
  encoder.encode(obj, io)
@@ -75,22 +72,16 @@ describe "Yajl JSON encoder" do
75
72
  end
76
73
 
77
74
  it "should encode with :pretty turned on and a single space indent, and return a String" do
78
- output = "{\n \"foo\": {\n \"name\": \"bar\",\n \"id\": 1234\n }\n}"
79
- if RUBY_VERSION.include?('1.9') # FIXME
80
- output = "{\n \"foo\": {\n \"id\": 1234,\n \"name\": \"bar\"\n }\n}"
81
- end
82
- obj = {:foo => {:id => 1234, :name => "bar"}}
75
+ output = "{\n \"foo\": 1234\n}"
76
+ obj = {:foo => 1234}
83
77
  encoder = Yajl::Encoder.new(:pretty => true, :indent => ' ')
84
78
  output = encoder.encode(obj)
85
79
  output.should == output
86
80
  end
87
81
 
88
82
  it "should encode with :pretty turned on and a tab character indent, to an IO" do
89
- output = "{\n\t\"foo\": {\n\t\t\"name\": \"bar\",\n\t\t\"id\": 1234\n\t}\n}"
90
- if RUBY_VERSION.include?('1.9') # FIXME
91
- output = "{\n\t\"foo\": {\n\t\t\"id\": 1234,\n\t\t\"name\": \"bar\"\n\t}\n}"
92
- end
93
- obj = {:foo => {:id => 1234, :name => "bar"}}
83
+ output = "{\n\t\"foo\": 1234\n}"
84
+ obj = {:foo => 1234}
94
85
  io = StringIO.new
95
86
  encoder = Yajl::Encoder.new(:pretty => true, :indent => "\t")
96
87
  encoder.encode(obj, io)
@@ -99,22 +90,16 @@ describe "Yajl JSON encoder" do
99
90
  end
100
91
 
101
92
  it "should encode with :pretty turned on and a tab character indent, and return a String" do
102
- output = "{\n\t\"foo\": {\n\t\t\"name\": \"bar\",\n\t\t\"id\": 1234\n\t}\n}"
103
- if RUBY_VERSION.include?('1.9') # FIXME
104
- output = "{\n\t\"foo\": {\n\t\t\"id\": 1234,\n\t\t\"name\": \"bar\"\n\t}\n}"
105
- end
106
- obj = {:foo => {:id => 1234, :name => "bar"}}
93
+ output = "{\n\t\"foo\": 1234\n}"
94
+ obj = {:foo => 1234}
107
95
  encoder = Yajl::Encoder.new(:pretty => true, :indent => "\t")
108
96
  output = encoder.encode(obj)
109
97
  output.should == output
110
98
  end
111
99
 
112
100
  it "should encode with it's class method with :pretty and a tab character indent options set, to an IO" do
113
- output = "{\n\t\"foo\": {\n\t\t\"name\": \"bar\",\n\t\t\"id\": 1234\n\t}\n}"
114
- if RUBY_VERSION.include?('1.9') # FIXME
115
- output = "{\n\t\"foo\": {\n\t\t\"id\": 1234,\n\t\t\"name\": \"bar\"\n\t}\n}"
116
- end
117
- obj = {:foo => {:id => 1234, :name => "bar"}}
101
+ output = "{\n\t\"foo\": 1234\n}"
102
+ obj = {:foo => 1234}
118
103
  io = StringIO.new
119
104
  Yajl::Encoder.encode(obj, io, :pretty => true, :indent => "\t")
120
105
  io.rewind
@@ -122,21 +107,15 @@ describe "Yajl JSON encoder" do
122
107
  end
123
108
 
124
109
  it "should encode with it's class method with :pretty and a tab character indent options set, and return a String" do
125
- output = "{\n\t\"foo\": {\n\t\t\"name\": \"bar\",\n\t\t\"id\": 1234\n\t}\n}"
126
- if RUBY_VERSION.include?('1.9') # FIXME
127
- output = "{\n\t\"foo\": {\n\t\t\"id\": 1234,\n\t\t\"name\": \"bar\"\n\t}\n}"
128
- end
129
- obj = {:foo => {:id => 1234, :name => "bar"}}
110
+ output = "{\n\t\"foo\": 1234\n}"
111
+ obj = {:foo => 1234}
130
112
  output = Yajl::Encoder.encode(obj, :pretty => true, :indent => "\t")
131
113
  output.should == output
132
114
  end
133
115
 
134
116
  it "should encode with it's class method with :pretty and a tab character indent options set, to a block" do
135
- output = "{\n\t\"foo\": {\n\t\t\"name\": \"bar\",\n\t\t\"id\": 1234\n\t}\n}"
136
- if RUBY_VERSION.include?('1.9') # FIXME
137
- output = "{\n\t\"foo\": {\n\t\t\"id\": 1234,\n\t\t\"name\": \"bar\"\n\t}\n}"
138
- end
139
- obj = {:foo => {:id => 1234, :name => "bar"}}
117
+ output = "{\n\t\"foo\": 1234\n}"
118
+ obj = {:foo => 1234}
140
119
  output = ''
141
120
  Yajl::Encoder.encode(obj, :pretty => true, :indent => "\t") do |json_str|
142
121
  output = json_str
@@ -145,33 +124,25 @@ describe "Yajl JSON encoder" do
145
124
  end
146
125
 
147
126
  it "should encode multiple objects into a single stream, to an IO" do
148
- pending "Find a better way to compare order of hash keys in resulting string"
149
127
  io = StringIO.new
150
- obj = {:foo => "bar", :baz => 1234}
128
+ obj = {:foo => 1234}
151
129
  encoder = Yajl::Encoder.new
152
130
  5.times do
153
131
  encoder.encode(obj, io)
154
132
  end
155
133
  io.rewind
156
- output = "{\"baz\":1234,\"foo\":\"bar\"}{\"baz\":1234,\"foo\":\"bar\"}{\"baz\":1234,\"foo\":\"bar\"}{\"baz\":1234,\"foo\":\"bar\"}{\"baz\":1234,\"foo\":\"bar\"}"
157
- if RUBY_VERSION.include?('1.9') # FIXME
158
- output = "{\"foo\":\"bar\",\"baz\":1234}{\"foo\":\"bar\",\"baz\":1234}{\"foo\":\"bar\",\"baz\":1234}{\"foo\":\"bar\",\"baz\":1234}{\"foo\":\"bar\",\"baz\":1234}"
159
- end
134
+ output = "{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}"
160
135
  io.read.should == output
161
136
  end
162
137
 
163
138
  it "should encode multiple objects into a single stream, and return a String" do
164
- pending "Find a better way to compare order of hash keys in resulting string"
165
- obj = {:foo => "bar", :baz => 1234}
139
+ obj = {:foo => 1234}
166
140
  encoder = Yajl::Encoder.new
167
141
  json_output = ''
168
142
  5.times do
169
143
  json_output << encoder.encode(obj)
170
144
  end
171
- output = "{\"baz\":1234,\"foo\":\"bar\"}\n{\"baz\":1234,\"foo\":\"bar\"}\n{\"baz\":1234,\"foo\":\"bar\"}\n{\"baz\":1234,\"foo\":\"bar\"}\n{\"baz\":1234,\"foo\":\"bar\"}\n"
172
- if RUBY_VERSION.include?('1.9') # FIXME
173
- output = "{\"foo\":\"bar\",\"baz\":1234}\n{\"foo\":\"bar\",\"baz\":1234}\n{\"foo\":\"bar\",\"baz\":1234}\n{\"foo\":\"bar\",\"baz\":1234}\n{\"foo\":\"bar\",\"baz\":1234}\n"
174
- end
145
+ output = "{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}{\"foo\":1234}"
175
146
  json_output.should == output
176
147
  end
177
148
 
@@ -223,4 +194,19 @@ describe "Yajl JSON encoder" do
223
194
  s.rewind
224
195
  s.read.should eql("{\"foo\":\"bar\"}")
225
196
  end
197
+
198
+ it "should not encode NaN" do
199
+ lambda {
200
+ Yajl::Encoder.encode(0.0/0.0)
201
+ }.should raise_error(Yajl::EncodeError)
202
+ end
203
+
204
+ it "should not encode Infinity or -Infinity" do
205
+ lambda {
206
+ Yajl::Encoder.encode(1.0/0.0)
207
+ }.should raise_error(Yajl::EncodeError)
208
+ lambda {
209
+ Yajl::Encoder.encode(-1.0/0.0)
210
+ }.should raise_error(Yajl::EncodeError)
211
+ end
226
212
  end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
3
+
4
+ describe "Yajl" do
5
+ context "dump" do
6
+ it "should exist as a class-method" do
7
+ Yajl.should respond_to(:dump)
8
+ end
9
+
10
+ it "should be able to encode to a string" do
11
+ Yajl.dump({:a => 1234}).should eql('{"a":1234}')
12
+ end
13
+
14
+ it "should be able to encode to an IO" do
15
+ io = StringIO.new
16
+ Yajl.dump({:a => 1234}, io)
17
+ io.rewind
18
+ io.read.should eql('{"a":1234}')
19
+ end
20
+
21
+ it "should be able to encode with a block supplied" do
22
+ Yajl.dump({:a => 1234}) do |chunk|
23
+ chunk.should eql('{"a":1234}')
24
+ end
25
+ end
26
+ end
27
+
28
+ context "load" do
29
+ it "should exist as a class-method" do
30
+ Yajl.should respond_to(:load)
31
+ end
32
+
33
+ it "should be able to parse from a string" do
34
+ Yajl.load('{"a":1234}').should eql({"a" => 1234})
35
+ end
36
+
37
+ it "should be able to parse from an IO" do
38
+ io = StringIO.new('{"a":1234}')
39
+ Yajl.load(io).should eql({"a" => 1234})
40
+ end
41
+
42
+ it "should be able to parse from a string with a block supplied" do
43
+ Yajl.load('{"a":1234}') do |h|
44
+ h.should eql({"a" => 1234})
45
+ end
46
+ end
47
+
48
+ it "should be able to parse from an IO with a block supplied" do
49
+ io = StringIO.new('{"a":1234}')
50
+ Yajl.load(io) do |h|
51
+ h.should eql({"a" => 1234})
52
+ end
53
+ end
54
+ end
55
+ end