oj 2.6.1 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oj might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +2 -4
- data/ext/oj/dump.c +85 -44
- data/ext/oj/oj.c +39 -0
- data/ext/oj/oj.h +2 -0
- data/lib/oj/version.rb +1 -1
- data/test/test_writer.rb +45 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 874c4d47513efdd1f1a64da2ddfe403009f683bc
|
4
|
+
data.tar.gz: 16969c09038d314da516230b5ed45787cc05f4cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5192373bff2623463ab580cf32b54a45ba380e66a16d342de37b79655c94d6e4ef61180e9332023d6601bc7243ba3f1a594d3a6ad427f0ceb79e2211d070e7b1
|
7
|
+
data.tar.gz: 6457b838b18ad5b580b096db8f2ed5c474cc7a7841dd6c2fcde90360a2ec861c7ef0b33a63580339c0735a0f6822a75bdc35d88ed1b8cdd99360f5d85d7e645a
|
data/README.md
CHANGED
@@ -26,11 +26,9 @@ Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announceme
|
|
26
26
|
|
27
27
|
[![Build Status](https://secure.travis-ci.org/ohler55/oj.png?branch=master)](http://travis-ci.org/ohler55/oj)
|
28
28
|
|
29
|
-
### Current Release 2.
|
29
|
+
### Current Release 2.7.0
|
30
30
|
|
31
|
-
-
|
32
|
-
instead of a segfault unless a reduced stack is used which could trigger the
|
33
|
-
segfault due to an out of memory condition.
|
31
|
+
- Added the push_key() method to the StringWriter and StreamWriter classes.
|
34
32
|
|
35
33
|
[Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
|
36
34
|
|
data/ext/oj/dump.c
CHANGED
@@ -2049,10 +2049,13 @@ maybe_comma(StrWriter sw) {
|
|
2049
2049
|
}
|
2050
2050
|
|
2051
2051
|
void
|
2052
|
-
|
2052
|
+
oj_str_writer_push_key(StrWriter sw, const char *key) {
|
2053
|
+
DumpType type = sw->types[sw->depth];
|
2053
2054
|
long size;
|
2054
2055
|
|
2055
|
-
|
2056
|
+
if (ObjectNew != type && ObjectType != type) {
|
2057
|
+
rb_raise(rb_eStandardError, "Can only push a key onto an Object.");
|
2058
|
+
}
|
2056
2059
|
size = sw->depth * sw->out.indent + 3;
|
2057
2060
|
if (sw->out.end - sw->out.cur <= (long)size) {
|
2058
2061
|
grow(&sw->out, size);
|
@@ -2061,9 +2064,31 @@ oj_str_writer_push_object(StrWriter sw, const char *key) {
|
|
2061
2064
|
if (0 < sw->depth) {
|
2062
2065
|
fill_indent(&sw->out, sw->depth);
|
2063
2066
|
}
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
+
dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
2068
|
+
*sw->out.cur++ = ':';
|
2069
|
+
sw->keyWritten = 1;
|
2070
|
+
}
|
2071
|
+
|
2072
|
+
void
|
2073
|
+
oj_str_writer_push_object(StrWriter sw, const char *key) {
|
2074
|
+
if (sw->keyWritten) {
|
2075
|
+
sw->keyWritten = 0;
|
2076
|
+
} else {
|
2077
|
+
long size;
|
2078
|
+
|
2079
|
+
key_check(sw, key);
|
2080
|
+
size = sw->depth * sw->out.indent + 3;
|
2081
|
+
if (sw->out.end - sw->out.cur <= (long)size) {
|
2082
|
+
grow(&sw->out, size);
|
2083
|
+
}
|
2084
|
+
maybe_comma(sw);
|
2085
|
+
if (0 < sw->depth) {
|
2086
|
+
fill_indent(&sw->out, sw->depth);
|
2087
|
+
}
|
2088
|
+
if (0 != key) {
|
2089
|
+
dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
2090
|
+
*sw->out.cur++ = ':';
|
2091
|
+
}
|
2067
2092
|
}
|
2068
2093
|
*sw->out.cur++ = '{';
|
2069
2094
|
push_type(sw, ObjectNew);
|
@@ -2071,20 +2096,24 @@ oj_str_writer_push_object(StrWriter sw, const char *key) {
|
|
2071
2096
|
|
2072
2097
|
void
|
2073
2098
|
oj_str_writer_push_array(StrWriter sw, const char *key) {
|
2074
|
-
|
2099
|
+
if (sw->keyWritten) {
|
2100
|
+
sw->keyWritten = 0;
|
2101
|
+
} else {
|
2102
|
+
long size;
|
2075
2103
|
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2104
|
+
key_check(sw, key);
|
2105
|
+
size = sw->depth * sw->out.indent + 3;
|
2106
|
+
if (sw->out.end - sw->out.cur <= size) {
|
2107
|
+
grow(&sw->out, size);
|
2108
|
+
}
|
2109
|
+
maybe_comma(sw);
|
2110
|
+
if (0 < sw->depth) {
|
2111
|
+
fill_indent(&sw->out, sw->depth);
|
2112
|
+
}
|
2113
|
+
if (0 != key) {
|
2114
|
+
dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
2115
|
+
*sw->out.cur++ = ':';
|
2116
|
+
}
|
2088
2117
|
}
|
2089
2118
|
*sw->out.cur++ = '[';
|
2090
2119
|
push_type(sw, ArrayNew);
|
@@ -2092,40 +2121,48 @@ oj_str_writer_push_array(StrWriter sw, const char *key) {
|
|
2092
2121
|
|
2093
2122
|
void
|
2094
2123
|
oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) {
|
2095
|
-
|
2124
|
+
if (sw->keyWritten) {
|
2125
|
+
sw->keyWritten = 0;
|
2126
|
+
} else {
|
2127
|
+
long size;
|
2096
2128
|
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2129
|
+
key_check(sw, key);
|
2130
|
+
size = sw->depth * sw->out.indent + 3;
|
2131
|
+
if (sw->out.end - sw->out.cur <= size) {
|
2132
|
+
grow(&sw->out, size);
|
2133
|
+
}
|
2134
|
+
maybe_comma(sw);
|
2135
|
+
if (0 < sw->depth) {
|
2136
|
+
fill_indent(&sw->out, sw->depth);
|
2137
|
+
}
|
2138
|
+
if (0 != key) {
|
2139
|
+
dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
2140
|
+
*sw->out.cur++ = ':';
|
2141
|
+
}
|
2109
2142
|
}
|
2110
2143
|
dump_val(val, sw->depth, &sw->out);
|
2111
2144
|
}
|
2112
2145
|
|
2113
2146
|
void
|
2114
2147
|
oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
|
2115
|
-
|
2148
|
+
if (sw->keyWritten) {
|
2149
|
+
sw->keyWritten = 0;
|
2150
|
+
} else {
|
2151
|
+
long size;
|
2116
2152
|
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2153
|
+
key_check(sw, key);
|
2154
|
+
size = sw->depth * sw->out.indent + 3;
|
2155
|
+
if (sw->out.end - sw->out.cur <= size) {
|
2156
|
+
grow(&sw->out, size);
|
2157
|
+
}
|
2158
|
+
maybe_comma(sw);
|
2159
|
+
if (0 < sw->depth) {
|
2160
|
+
fill_indent(&sw->out, sw->depth);
|
2161
|
+
}
|
2162
|
+
if (0 != key) {
|
2163
|
+
dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
2164
|
+
*sw->out.cur++ = ':';
|
2165
|
+
}
|
2129
2166
|
}
|
2130
2167
|
dump_raw(json, strlen(json), &sw->out);
|
2131
2168
|
}
|
@@ -2135,6 +2172,10 @@ oj_str_writer_pop(StrWriter sw) {
|
|
2135
2172
|
long size;
|
2136
2173
|
DumpType type = sw->types[sw->depth];
|
2137
2174
|
|
2175
|
+
if (sw->keyWritten) {
|
2176
|
+
sw->keyWritten = 0;
|
2177
|
+
rb_raise(rb_eStandardError, "Can not pop after writing a key but no value.");
|
2178
|
+
}
|
2138
2179
|
sw->depth--;
|
2139
2180
|
if (0 > sw->depth) {
|
2140
2181
|
rb_raise(rb_eStandardError, "Can not pop with no open array or object.");
|
data/ext/oj/oj.c
CHANGED
@@ -864,6 +864,8 @@ str_writer_init(StrWriter sw) {
|
|
864
864
|
sw->types = ALLOC_N(char, 256);
|
865
865
|
sw->types_end = sw->types + 256;
|
866
866
|
*sw->types = '\0';
|
867
|
+
sw->keyWritten = 0;
|
868
|
+
|
867
869
|
sw->out.buf = ALLOC_N(char, 4096);
|
868
870
|
sw->out.end = sw->out.buf + 4086;
|
869
871
|
sw->out.allocated = 1;
|
@@ -894,6 +896,23 @@ str_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
894
896
|
return Data_Wrap_Struct(oj_string_writer_class, 0, str_writer_free, sw);
|
895
897
|
}
|
896
898
|
|
899
|
+
/* call-seq: push_key(key)
|
900
|
+
*
|
901
|
+
* Pushes a key onto the JSON document. The key will be used for the next push
|
902
|
+
* if currently in a JSON object and ignored otherwise. If a key is provided on
|
903
|
+
* the next push then that new key will be ignored.
|
904
|
+
* @param [String] key the key pending for the next push
|
905
|
+
*/
|
906
|
+
static VALUE
|
907
|
+
str_writer_push_key(VALUE self, VALUE key) {
|
908
|
+
StrWriter sw = (StrWriter)DATA_PTR(self);
|
909
|
+
|
910
|
+
rb_check_type(key, T_STRING);
|
911
|
+
oj_str_writer_push_key(sw, StringValuePtr(key));
|
912
|
+
|
913
|
+
return Qnil;
|
914
|
+
}
|
915
|
+
|
897
916
|
/* call-seq: push_object(key=nil)
|
898
917
|
*
|
899
918
|
* Pushes an object onto the JSON document. Future pushes will be to this object
|
@@ -1050,6 +1069,7 @@ str_writer_reset(VALUE self) {
|
|
1050
1069
|
|
1051
1070
|
sw->depth = 0;
|
1052
1071
|
*sw->types = '\0';
|
1072
|
+
sw->keyWritten = 0;
|
1053
1073
|
sw->out.cur = sw->out.buf;
|
1054
1074
|
*sw->out.cur = '\0';
|
1055
1075
|
|
@@ -1155,6 +1175,23 @@ stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
1155
1175
|
return Data_Wrap_Struct(oj_stream_writer_class, 0, stream_writer_free, sw);
|
1156
1176
|
}
|
1157
1177
|
|
1178
|
+
/* call-seq: push_key(key)
|
1179
|
+
*
|
1180
|
+
* Pushes a key onto the JSON document. The key will be used for the next push
|
1181
|
+
* if currently in a JSON object and ignored otherwise. If a key is provided on
|
1182
|
+
* the next push then that new key will be ignored.
|
1183
|
+
* @param [String] key the key pending for the next push
|
1184
|
+
*/
|
1185
|
+
static VALUE
|
1186
|
+
stream_writer_push_key(VALUE self, VALUE key) {
|
1187
|
+
StreamWriter sw = (StreamWriter)DATA_PTR(self);
|
1188
|
+
|
1189
|
+
rb_check_type(key, T_STRING);
|
1190
|
+
oj_str_writer_push_key(&sw->sw, StringValuePtr(key));
|
1191
|
+
stream_writer_write(sw);
|
1192
|
+
return Qnil;
|
1193
|
+
}
|
1194
|
+
|
1158
1195
|
/* call-seq: push_object(key=nil)
|
1159
1196
|
*
|
1160
1197
|
* Pushes an object onto the JSON document. Future pushes will be to this object
|
@@ -1706,6 +1743,7 @@ void Init_oj() {
|
|
1706
1743
|
|
1707
1744
|
oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
|
1708
1745
|
rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
|
1746
|
+
rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
|
1709
1747
|
rb_define_method(oj_string_writer_class, "push_object", str_writer_push_object, -1);
|
1710
1748
|
rb_define_method(oj_string_writer_class, "push_array", str_writer_push_array, -1);
|
1711
1749
|
rb_define_method(oj_string_writer_class, "push_value", str_writer_push_value, -1);
|
@@ -1717,6 +1755,7 @@ void Init_oj() {
|
|
1717
1755
|
|
1718
1756
|
oj_stream_writer_class = rb_define_class_under(Oj, "StreamWriter", rb_cObject);
|
1719
1757
|
rb_define_module_function(oj_stream_writer_class, "new", stream_writer_new, -1);
|
1758
|
+
rb_define_method(oj_stream_writer_class, "push_key", stream_writer_push_key, 1);
|
1720
1759
|
rb_define_method(oj_stream_writer_class, "push_object", stream_writer_push_object, -1);
|
1721
1760
|
rb_define_method(oj_stream_writer_class, "push_array", stream_writer_push_array, -1);
|
1722
1761
|
rb_define_method(oj_stream_writer_class, "push_value", stream_writer_push_value, -1);
|
data/ext/oj/oj.h
CHANGED
@@ -162,6 +162,7 @@ typedef struct _StrWriter {
|
|
162
162
|
int depth;
|
163
163
|
char *types; // DumpType
|
164
164
|
char *types_end;
|
165
|
+
int keyWritten;
|
165
166
|
} *StrWriter;
|
166
167
|
|
167
168
|
typedef struct _StreamWriter {
|
@@ -212,6 +213,7 @@ extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
|
|
212
213
|
extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
|
213
214
|
extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
|
214
215
|
|
216
|
+
extern void oj_str_writer_push_key(StrWriter sw, const char *key);
|
215
217
|
extern void oj_str_writer_push_object(StrWriter sw, const char *key);
|
216
218
|
extern void oj_str_writer_push_array(StrWriter sw, const char *key);
|
217
219
|
extern void oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key);
|
data/lib/oj/version.rb
CHANGED
data/test/test_writer.rb
CHANGED
@@ -61,6 +61,24 @@ class OjWriter < ::Test::Unit::TestCase
|
|
61
61
|
assert_equal('{"a1":{},"a2":{"b":{}},"a3":{}}', w.to_s)
|
62
62
|
end
|
63
63
|
|
64
|
+
def test_string_writer_nested_key_object
|
65
|
+
w = Oj::StringWriter.new(:indent => 0)
|
66
|
+
w.push_object()
|
67
|
+
w.push_key('a1')
|
68
|
+
w.push_object()
|
69
|
+
w.pop()
|
70
|
+
w.push_key('a2')
|
71
|
+
w.push_object('x')
|
72
|
+
w.push_object('b')
|
73
|
+
w.pop()
|
74
|
+
w.pop()
|
75
|
+
w.push_key('a3')
|
76
|
+
w.push_object()
|
77
|
+
w.pop()
|
78
|
+
w.pop()
|
79
|
+
assert_equal('{"a1":{},"a2":{"b":{}},"a3":{}}', w.to_s)
|
80
|
+
end
|
81
|
+
|
64
82
|
def test_string_writer_value_array
|
65
83
|
w = Oj::StringWriter.new(:indent => 2)
|
66
84
|
w.push_array()
|
@@ -117,6 +135,33 @@ class OjWriter < ::Test::Unit::TestCase
|
|
117
135
|
end
|
118
136
|
|
119
137
|
def test_string_writer_pop_excess
|
138
|
+
w = Oj::StringWriter.new(:indent => 0)
|
139
|
+
begin
|
140
|
+
w.push_object() {
|
141
|
+
w.push_key('key')
|
142
|
+
}
|
143
|
+
rescue Exception
|
144
|
+
assert(true)
|
145
|
+
return
|
146
|
+
end
|
147
|
+
assert(false, "*** expected an exception")
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_string_writer_array_key
|
151
|
+
w = Oj::StringWriter.new(:indent => 0)
|
152
|
+
begin
|
153
|
+
w.push_array() {
|
154
|
+
w.push_key('key')
|
155
|
+
w.push_value(7)
|
156
|
+
}
|
157
|
+
rescue Exception
|
158
|
+
assert(true)
|
159
|
+
return
|
160
|
+
end
|
161
|
+
assert(false, "*** expected an exception")
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_string_writer_pop_with_key
|
120
165
|
w = Oj::StringWriter.new(:indent => 0)
|
121
166
|
begin
|
122
167
|
w.pop()
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'The fastest JSON parser and object serializer. '
|
14
14
|
email: peter@ohler.com
|