oj 2.11.5 → 2.12.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 +8 -11
- data/ext/oj/dump.c +55 -14
- data/ext/oj/object.c +188 -3
- data/ext/oj/oj.c +18 -6
- data/ext/oj/oj.h +4 -1
- data/ext/oj/parse.c +4 -1
- data/ext/oj/parse.h +1 -0
- data/ext/oj/sparse.c +3 -1
- data/lib/oj/version.rb +1 -1
- data/test/bug.rb +40 -51
- data/test/bug2.rb +10 -0
- data/test/io.rb +48 -0
- data/test/{test_range.rb → mod.rb} +6 -9
- data/test/struct.rb +29 -0
- data/test/test_compat.rb +62 -0
- data/test/test_file.rb +14 -3
- data/test/test_object.rb +185 -17
- data/test/test_serializer.rb +59 -0
- data/test/test_various.rb +5 -15
- data/test/write_timebars.rb +31 -0
- data/test/zip.rb +34 -0
- metadata +10 -7
- data/test/perf1.rb +0 -64
- data/test/perf2.rb +0 -76
- data/test/perf_obj_old.rb +0 -213
- data/test/test_bigd.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4f6db0371ed698ce4c6002a7d12acfb79982191
|
4
|
+
data.tar.gz: 8255ac3b86ed139ebbb350aacf8a8b25cd4806d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee7a31844af7de0fcf4074146e963f17952cf396de304af36b7b04ad35a9e6904dc3ff93207cd728fbcb5102a5f4d8307942df9124cb4085b82c07ab3f0111c1
|
7
|
+
data.tar.gz: daa03c5114facec630dea16ce5925aa873a398e008383a6fc9323c3a468d6dec173167f1c071c036192564a3e9ec856e0d5b6b23222d21ff90aabf4e2900987b
|
data/README.md
CHANGED
@@ -26,19 +26,16 @@ 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
|
-
## Release 2.
|
29
|
+
## Future Release 2.12.0
|
30
30
|
|
31
|
-
-
|
31
|
+
- String formats for UTC time are now explitly UTC instead of offset of
|
32
|
+
zero. This fixes a problem with pre-2.2.0 Rubies that automatically convert
|
33
|
+
zero offset times to local times.
|
32
34
|
|
33
|
-
- Added
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
- DateTime second encoding is now always a Rational to preserve accuracy.
|
39
|
-
|
40
|
-
- Fixed bug in the Oj.load() callback feature that caused an endless loop when
|
41
|
-
a StringIO was used with a JSON that was a number.
|
35
|
+
- Added :unix_zone time_format option for formating numeric time. This option
|
36
|
+
is the same as the :unix time option but the UTC offset is included as an
|
37
|
+
exponent to the number time value. A value of 86400 is an indication of UTC
|
38
|
+
time.
|
42
39
|
|
43
40
|
[Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
|
44
41
|
|
data/ext/oj/dump.c
CHANGED
@@ -80,7 +80,7 @@ static int hash_cb_strict(VALUE key, VALUE value, Out out);
|
|
80
80
|
static int hash_cb_compat(VALUE key, VALUE value, Out out);
|
81
81
|
static int hash_cb_object(VALUE key, VALUE value, Out out);
|
82
82
|
static void dump_hash(VALUE obj, VALUE clas, int depth, int mode, Out out);
|
83
|
-
static void dump_time(VALUE obj, Out out);
|
83
|
+
static void dump_time(VALUE obj, Out out, int withZone);
|
84
84
|
static void dump_ruby_time(VALUE obj, Out out);
|
85
85
|
static void dump_xml_time(VALUE obj, Out out);
|
86
86
|
static void dump_data_strict(VALUE obj, Out out);
|
@@ -996,11 +996,11 @@ dump_hash(VALUE obj, VALUE clas, int depth, int mode, Out out) {
|
|
996
996
|
}
|
997
997
|
|
998
998
|
static void
|
999
|
-
dump_time(VALUE obj, Out out) {
|
999
|
+
dump_time(VALUE obj, Out out, int withZone) {
|
1000
1000
|
char buf[64];
|
1001
1001
|
char *b = buf + sizeof(buf) - 1;
|
1002
1002
|
long size;
|
1003
|
-
char *dot
|
1003
|
+
char *dot;
|
1004
1004
|
int neg = 0;
|
1005
1005
|
long one = 1000000000;
|
1006
1006
|
#if HAS_RB_TIME_TIMESPEC
|
@@ -1016,6 +1016,31 @@ dump_time(VALUE obj, Out out) {
|
|
1016
1016
|
#endif
|
1017
1017
|
#endif
|
1018
1018
|
|
1019
|
+
*b-- = '\0';
|
1020
|
+
if (withZone) {
|
1021
|
+
long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
|
1022
|
+
int zneg = (0 > tzsecs);
|
1023
|
+
|
1024
|
+
if (0 == tzsecs && Qtrue == rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
1025
|
+
tzsecs = 86400;
|
1026
|
+
} else {
|
1027
|
+
sec += tzsecs;
|
1028
|
+
}
|
1029
|
+
if (zneg) {
|
1030
|
+
tzsecs = -tzsecs;
|
1031
|
+
}
|
1032
|
+
if (0 == tzsecs) {
|
1033
|
+
*b-- = '0';
|
1034
|
+
} else {
|
1035
|
+
for (; 0 < tzsecs; b--, tzsecs /= 10) {
|
1036
|
+
*b = '0' + (tzsecs % 10);
|
1037
|
+
}
|
1038
|
+
if (zneg) {
|
1039
|
+
*b-- = '-';
|
1040
|
+
}
|
1041
|
+
}
|
1042
|
+
*b-- = 'e';
|
1043
|
+
}
|
1019
1044
|
if (0 > sec) {
|
1020
1045
|
neg = 1;
|
1021
1046
|
sec = -sec;
|
@@ -1024,7 +1049,7 @@ dump_time(VALUE obj, Out out) {
|
|
1024
1049
|
sec--;
|
1025
1050
|
}
|
1026
1051
|
}
|
1027
|
-
|
1052
|
+
dot = b - 9;
|
1028
1053
|
if (0 < out->opts->sec_prec) {
|
1029
1054
|
if (9 > out->opts->sec_prec) {
|
1030
1055
|
int i;
|
@@ -1088,7 +1113,7 @@ dump_xml_time(VALUE obj, Out out) {
|
|
1088
1113
|
long nsec = NUM2LONG(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
|
1089
1114
|
#endif
|
1090
1115
|
#endif
|
1091
|
-
long
|
1116
|
+
long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
|
1092
1117
|
int tzhour, tzmin;
|
1093
1118
|
char tzsign = '+';
|
1094
1119
|
|
@@ -1109,16 +1134,16 @@ dump_xml_time(VALUE obj, Out out) {
|
|
1109
1134
|
}
|
1110
1135
|
// 2012-01-05T23:58:07.123456000+09:00
|
1111
1136
|
//tm = localtime(&sec);
|
1112
|
-
sec +=
|
1137
|
+
sec += tzsecs;
|
1113
1138
|
tm = gmtime(&sec);
|
1114
1139
|
#if 1
|
1115
|
-
if (0 >
|
1140
|
+
if (0 > tzsecs) {
|
1116
1141
|
tzsign = '-';
|
1117
|
-
tzhour = (int)(
|
1118
|
-
tzmin = (int)(
|
1142
|
+
tzhour = (int)(tzsecs / -3600);
|
1143
|
+
tzmin = (int)(tzsecs / -60) - (tzhour * 60);
|
1119
1144
|
} else {
|
1120
|
-
tzhour = (int)(
|
1121
|
-
tzmin = (int)(
|
1145
|
+
tzhour = (int)(tzsecs / 3600);
|
1146
|
+
tzmin = (int)(tzsecs / 60) - (tzhour * 60);
|
1122
1147
|
}
|
1123
1148
|
#else
|
1124
1149
|
if (0 > tm->tm_gmtoff) {
|
@@ -1131,7 +1156,7 @@ dump_xml_time(VALUE obj, Out out) {
|
|
1131
1156
|
}
|
1132
1157
|
#endif
|
1133
1158
|
if (0 == nsec || 0 == out->opts->sec_prec) {
|
1134
|
-
if (0 ==
|
1159
|
+
if (0 == tzsecs && Qtrue == rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
1135
1160
|
sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ",
|
1136
1161
|
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
1137
1162
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
@@ -1143,6 +1168,18 @@ dump_xml_time(VALUE obj, Out out) {
|
|
1143
1168
|
tzsign, tzhour, tzmin);
|
1144
1169
|
dump_cstr(buf, 25, 0, 0, out);
|
1145
1170
|
}
|
1171
|
+
} else if (0 == tzsecs && Qtrue == rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
1172
|
+
char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ";
|
1173
|
+
int len = 30;
|
1174
|
+
|
1175
|
+
if (9 > out->opts->sec_prec) {
|
1176
|
+
format[32] = '0' + out->opts->sec_prec;
|
1177
|
+
len -= 9 - out->opts->sec_prec;
|
1178
|
+
}
|
1179
|
+
sprintf(buf, format,
|
1180
|
+
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
1181
|
+
tm->tm_hour, tm->tm_min, tm->tm_sec, nsec);
|
1182
|
+
dump_cstr(buf, len, 0, 0, out);
|
1146
1183
|
} else {
|
1147
1184
|
char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d";
|
1148
1185
|
int len = 35;
|
@@ -1232,8 +1269,9 @@ dump_data_comp(VALUE obj, int depth, Out out) {
|
|
1232
1269
|
switch (out->opts->time_format) {
|
1233
1270
|
case RubyTime: dump_ruby_time(obj, out); break;
|
1234
1271
|
case XmlTime: dump_xml_time(obj, out); break;
|
1272
|
+
case UnixZTime: dump_time(obj, out, 1); break;
|
1235
1273
|
case UnixTime:
|
1236
|
-
default: dump_time(obj, out); break;
|
1274
|
+
default: dump_time(obj, out, 0); break;
|
1237
1275
|
}
|
1238
1276
|
} else if (oj_bigdecimal_class == clas) {
|
1239
1277
|
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
@@ -1266,9 +1304,12 @@ dump_data_obj(VALUE obj, int depth, Out out) {
|
|
1266
1304
|
case XmlTime:
|
1267
1305
|
dump_xml_time(obj, out);
|
1268
1306
|
break;
|
1307
|
+
case UnixZTime:
|
1308
|
+
dump_time(obj, out, 1);
|
1309
|
+
break;
|
1269
1310
|
case UnixTime:
|
1270
1311
|
default:
|
1271
|
-
dump_time(obj, out);
|
1312
|
+
dump_time(obj, out, 0);
|
1272
1313
|
break;
|
1273
1314
|
}
|
1274
1315
|
*out->cur++ = '}';
|
data/ext/oj/object.c
CHANGED
@@ -29,6 +29,7 @@
|
|
29
29
|
*/
|
30
30
|
|
31
31
|
#include <stdio.h>
|
32
|
+
#include <time.h>
|
32
33
|
|
33
34
|
#include "oj.h"
|
34
35
|
#include "err.h"
|
@@ -93,6 +94,146 @@ str_to_value(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
93
94
|
return rstr;
|
94
95
|
}
|
95
96
|
|
97
|
+
#if (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
|
98
|
+
static VALUE
|
99
|
+
parse_xml_time(const char *str, int len) {
|
100
|
+
return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(str, len));
|
101
|
+
}
|
102
|
+
#else
|
103
|
+
// The much faster approach (4x faster)
|
104
|
+
static int
|
105
|
+
parse_num(const char *str, const char *end, int cnt) {
|
106
|
+
int n = 0;
|
107
|
+
char c;
|
108
|
+
int i;
|
109
|
+
|
110
|
+
for (i = cnt; 0 < i; i--, str++) {
|
111
|
+
c = *str;
|
112
|
+
if (end <= str || c < '0' || '9' < c) {
|
113
|
+
return -1;
|
114
|
+
}
|
115
|
+
n = n * 10 + (c - '0');
|
116
|
+
}
|
117
|
+
return n;
|
118
|
+
}
|
119
|
+
|
120
|
+
static VALUE
|
121
|
+
parse_xml_time(const char *str, int len) {
|
122
|
+
VALUE args[8];
|
123
|
+
const char *end = str + len;
|
124
|
+
int n;
|
125
|
+
|
126
|
+
// year
|
127
|
+
if (0 > (n = parse_num(str, end, 4))) {
|
128
|
+
return Qnil;
|
129
|
+
}
|
130
|
+
str += 4;
|
131
|
+
args[0] = LONG2NUM(n);
|
132
|
+
if ('-' != *str++) {
|
133
|
+
return Qnil;
|
134
|
+
}
|
135
|
+
// month
|
136
|
+
if (0 > (n = parse_num(str, end, 2))) {
|
137
|
+
return Qnil;
|
138
|
+
}
|
139
|
+
str += 2;
|
140
|
+
args[1] = LONG2NUM(n);
|
141
|
+
if ('-' != *str++) {
|
142
|
+
return Qnil;
|
143
|
+
}
|
144
|
+
// day
|
145
|
+
if (0 > (n = parse_num(str, end, 2))) {
|
146
|
+
return Qnil;
|
147
|
+
}
|
148
|
+
str += 2;
|
149
|
+
args[2] = LONG2NUM(n);
|
150
|
+
if ('T' != *str++) {
|
151
|
+
return Qnil;
|
152
|
+
}
|
153
|
+
// hour
|
154
|
+
if (0 > (n = parse_num(str, end, 2))) {
|
155
|
+
return Qnil;
|
156
|
+
}
|
157
|
+
str += 2;
|
158
|
+
args[3] = LONG2NUM(n);
|
159
|
+
if (':' != *str++) {
|
160
|
+
return Qnil;
|
161
|
+
}
|
162
|
+
// minute
|
163
|
+
if (0 > (n = parse_num(str, end, 2))) {
|
164
|
+
return Qnil;
|
165
|
+
}
|
166
|
+
str += 2;
|
167
|
+
args[4] = LONG2NUM(n);
|
168
|
+
if (':' != *str++) {
|
169
|
+
return Qnil;
|
170
|
+
}
|
171
|
+
// second
|
172
|
+
if (0 > (n = parse_num(str, end, 2))) {
|
173
|
+
return Qnil;
|
174
|
+
}
|
175
|
+
str += 2;
|
176
|
+
if (str == end) {
|
177
|
+
args[5] = LONG2NUM(n);
|
178
|
+
args[6] = LONG2NUM(0);
|
179
|
+
} else {
|
180
|
+
char c = *str++;
|
181
|
+
|
182
|
+
if ('.' == c) {
|
183
|
+
long nsec = 0;
|
184
|
+
|
185
|
+
for (; str < end; str++) {
|
186
|
+
c = *str;
|
187
|
+
if (c < '0' || '9' < c) {
|
188
|
+
str++;
|
189
|
+
break;
|
190
|
+
}
|
191
|
+
nsec = nsec * 10 + (c - '0');
|
192
|
+
}
|
193
|
+
args[5] = rb_float_new((double)n + ((double)nsec + 0.5) / 1000000000.0);
|
194
|
+
} else {
|
195
|
+
args[5] = LONG2NUM(n);
|
196
|
+
}
|
197
|
+
if (end < str) {
|
198
|
+
args[6] = LONG2NUM(0);
|
199
|
+
} else {
|
200
|
+
if ('Z' == c) {
|
201
|
+
return rb_funcall2(rb_cTime, oj_utc_id, 6, args);
|
202
|
+
} else if ('+' == c) {
|
203
|
+
int hr = parse_num(str, end, 2);
|
204
|
+
int min;
|
205
|
+
|
206
|
+
str += 2;
|
207
|
+
if (0 > hr || ':' != *str++) {
|
208
|
+
return Qnil;
|
209
|
+
}
|
210
|
+
min = parse_num(str, end, 2);
|
211
|
+
if (0 > min) {
|
212
|
+
return Qnil;
|
213
|
+
}
|
214
|
+
args[6] = LONG2NUM(hr * 3600 + min * 60);
|
215
|
+
} else if ('-' == c) {
|
216
|
+
int hr = parse_num(str, end, 2);
|
217
|
+
int min;
|
218
|
+
|
219
|
+
str += 2;
|
220
|
+
if (0 > hr || ':' != *str++) {
|
221
|
+
return Qnil;
|
222
|
+
}
|
223
|
+
min = parse_num(str, end, 2);
|
224
|
+
if (0 > min) {
|
225
|
+
return Qnil;
|
226
|
+
}
|
227
|
+
args[6] = LONG2NUM(-(hr * 3600 + min * 60));
|
228
|
+
} else {
|
229
|
+
args[6] = LONG2NUM(0);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
return rb_funcall2(rb_cTime, oj_new_id, 7, args);
|
234
|
+
}
|
235
|
+
#endif
|
236
|
+
|
96
237
|
static int
|
97
238
|
hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t len) {
|
98
239
|
const char *key = kval->key;
|
@@ -133,7 +274,7 @@ hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t len) {
|
|
133
274
|
parent->val = oj_name2class(pi, str, len, Yes == pi->options.auto_define);
|
134
275
|
break;
|
135
276
|
case 't': // time
|
136
|
-
parent->val =
|
277
|
+
parent->val = parse_xml_time(str, len);
|
137
278
|
break;
|
138
279
|
default:
|
139
280
|
return 0;
|
@@ -159,11 +300,55 @@ hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
|
|
159
300
|
nsec = 1000000000LL - nsec;
|
160
301
|
}
|
161
302
|
}
|
303
|
+
if (86400 == ni->exp) { // UTC time
|
304
|
+
#if HAS_NANO_TIME
|
305
|
+
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
306
|
+
#else
|
307
|
+
parent->val = rb_time_new(ni->i, (long)(nsec / 1000));
|
308
|
+
#endif
|
309
|
+
// Since the ruby C routines alway create local time, the
|
310
|
+
// offset and then a convertion to UTC keeps makes the time
|
311
|
+
// match the expected value.
|
312
|
+
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
313
|
+
} else if (ni->hasExp) {
|
314
|
+
time_t t = (time_t)ni->i;
|
315
|
+
struct tm *st = gmtime(&t);
|
316
|
+
#if RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8
|
317
|
+
// The only methods that allow the UTC offset to be set in
|
318
|
+
// 1.8.7 is the parse() and xmlschema() methods. The
|
319
|
+
// xmlschema() method always returns a Time instance that is
|
320
|
+
// UTC time. (true on some platforms anyway) Time.parse()
|
321
|
+
// fails on other Ruby versions until 2.2.0.
|
322
|
+
char buf[64];
|
323
|
+
int z = (0 > ni->exp ? -ni->exp : ni->exp) / 60;
|
324
|
+
int tzhour = z / 60;
|
325
|
+
int tzmin = z - tzhour * 60;
|
326
|
+
int cnt;
|
327
|
+
|
328
|
+
cnt = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d",
|
329
|
+
1900 + st->tm_year, 1 + st->tm_mon, st->tm_mday,
|
330
|
+
st->tm_hour, st->tm_min, st->tm_sec, (long)nsec,
|
331
|
+
(0 > ni->exp ? '-' : '+'), tzhour, tzmin);
|
332
|
+
parent->val = rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(buf, cnt));
|
333
|
+
#else
|
334
|
+
VALUE args[8];
|
335
|
+
|
336
|
+
args[0] = LONG2NUM(1900 + st->tm_year);
|
337
|
+
args[1] = LONG2NUM(1 + st->tm_mon);
|
338
|
+
args[2] = LONG2NUM(st->tm_mday);
|
339
|
+
args[3] = LONG2NUM(st->tm_hour);
|
340
|
+
args[4] = LONG2NUM(st->tm_min);
|
341
|
+
args[5] = rb_float_new((double)st->tm_sec + ((double)nsec + 0.5) / 1000000000.0);
|
342
|
+
args[6] = LONG2NUM(ni->exp);
|
343
|
+
parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
|
344
|
+
#endif
|
345
|
+
} else {
|
162
346
|
#if HAS_NANO_TIME
|
163
|
-
|
347
|
+
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
164
348
|
#else
|
165
|
-
|
349
|
+
parent->val = rb_time_new(ni->i, (long)(nsec / 1000));
|
166
350
|
#endif
|
351
|
+
}
|
167
352
|
}
|
168
353
|
break;
|
169
354
|
case 'i': // circular index
|
data/ext/oj/oj.c
CHANGED
@@ -70,6 +70,7 @@ ID oj_instance_variables_id;
|
|
70
70
|
ID oj_json_create_id;
|
71
71
|
ID oj_length_id;
|
72
72
|
ID oj_new_id;
|
73
|
+
ID oj_parse_id;
|
73
74
|
ID oj_pos_id;
|
74
75
|
ID oj_read_id;
|
75
76
|
ID oj_readpartial_id;
|
@@ -84,7 +85,9 @@ ID oj_to_time_id;
|
|
84
85
|
ID oj_tv_nsec_id;
|
85
86
|
ID oj_tv_sec_id;
|
86
87
|
ID oj_tv_usec_id;
|
88
|
+
ID oj_utc_id;
|
87
89
|
ID oj_utc_offset_id;
|
90
|
+
ID oj_utcq_id;
|
88
91
|
ID oj_write_id;
|
89
92
|
|
90
93
|
VALUE oj_bag_class;
|
@@ -97,7 +100,6 @@ VALUE oj_stream_writer_class;
|
|
97
100
|
VALUE oj_string_writer_class;
|
98
101
|
VALUE oj_stringio_class;
|
99
102
|
VALUE oj_struct_class;
|
100
|
-
VALUE oj_time_class;
|
101
103
|
|
102
104
|
VALUE oj_slash_string;
|
103
105
|
|
@@ -130,6 +132,7 @@ static VALUE strict_sym;
|
|
130
132
|
static VALUE symbol_keys_sym;
|
131
133
|
static VALUE time_format_sym;
|
132
134
|
static VALUE unix_sym;
|
135
|
+
static VALUE unix_zone_sym;
|
133
136
|
static VALUE use_to_json_sym;
|
134
137
|
static VALUE xmlschema_sym;
|
135
138
|
static VALUE xss_safe_sym;
|
@@ -164,7 +167,7 @@ struct _Options oj_default_options = {
|
|
164
167
|
JSONEsc, // escape_mode
|
165
168
|
ObjectMode, // mode
|
166
169
|
Yes, // class_cache
|
167
|
-
|
170
|
+
UnixZTime, // time_format
|
168
171
|
Yes, // bigdec_as_num
|
169
172
|
AutoDec, // bigdec_load
|
170
173
|
Yes, // to_json
|
@@ -191,7 +194,7 @@ static VALUE define_mimic_json(int argc, VALUE *argv, VALUE self);
|
|
191
194
|
* - escape_mode: [:newline|:json|:xss_safe|:ascii|nil] determines the characters to escape
|
192
195
|
* - class_cache: [true|false|nil] cache classes for faster parsing (if dynamically modifying classes or reloading classes then don't use this)
|
193
196
|
* - mode: [:object|:strict|:compat|:null] load and dump modes to use for JSON
|
194
|
-
* - time_format: [:unix|:xmlschema|:ruby] time format when dumping in :compat mode
|
197
|
+
* - time_format: [:unix|:unix_zone|:xmlschema|:ruby] time format when dumping in :compat and :object mode
|
195
198
|
* - bigdecimal_as_decimal: [true|false|nil] dump BigDecimal as a decimal number or as a String
|
196
199
|
* - bigdecimal_load: [:bigdecimal|:float|:auto] load decimals as BigDecimal instead of as a Float. :auto pick the most precise for the number of digits.
|
197
200
|
* - create_id: [String|nil] create id for json compatible object encoding, default is 'json_create'
|
@@ -236,6 +239,7 @@ get_def_opts(VALUE self) {
|
|
236
239
|
switch (oj_default_options.time_format) {
|
237
240
|
case XmlTime: rb_hash_aset(opts, time_format_sym, xmlschema_sym); break;
|
238
241
|
case RubyTime: rb_hash_aset(opts, time_format_sym, ruby_sym); break;
|
242
|
+
case UnixZTime: rb_hash_aset(opts, time_format_sym, unix_zone_sym); break;
|
239
243
|
case UnixTime:
|
240
244
|
default: rb_hash_aset(opts, time_format_sym, unix_sym); break;
|
241
245
|
}
|
@@ -275,6 +279,7 @@ get_def_opts(VALUE self) {
|
|
275
279
|
* replaces them with a null.
|
276
280
|
* @param [:unix|:xmlschema|:ruby] time format when dumping in :compat mode
|
277
281
|
* :unix decimal number denoting the number of seconds since 1/1/1970,
|
282
|
+
* :unix_zone decimal number denoting the number of seconds since 1/1/1970 plus the utc_offset in the exponent ,
|
278
283
|
* :xmlschema date-time format taken from XML Schema as a String,
|
279
284
|
* :ruby Time.to_s formatted String
|
280
285
|
* @param [String|nil] :create_id create id for json compatible object encoding
|
@@ -360,12 +365,14 @@ set_def_opts(VALUE self, VALUE opts) {
|
|
360
365
|
// ignore
|
361
366
|
} else if (unix_sym == v) {
|
362
367
|
oj_default_options.time_format = UnixTime;
|
368
|
+
} else if (unix_zone_sym == v) {
|
369
|
+
oj_default_options.time_format = UnixZTime;
|
363
370
|
} else if (xmlschema_sym == v) {
|
364
371
|
oj_default_options.time_format = XmlTime;
|
365
372
|
} else if (ruby_sym == v) {
|
366
373
|
oj_default_options.time_format = RubyTime;
|
367
374
|
} else {
|
368
|
-
rb_raise(rb_eArgError, ":time_format must be :unix, :xmlschema, or :ruby.");
|
375
|
+
rb_raise(rb_eArgError, ":time_format must be :unix, :unix_zone, :xmlschema, or :ruby.");
|
369
376
|
}
|
370
377
|
|
371
378
|
v = rb_hash_lookup(opts, escape_mode_sym);
|
@@ -512,12 +519,14 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
512
519
|
if (Qnil != (v = rb_hash_lookup(ropts, time_format_sym))) {
|
513
520
|
if (unix_sym == v) {
|
514
521
|
copts->time_format = UnixTime;
|
522
|
+
} else if (unix_zone_sym == v) {
|
523
|
+
copts->time_format = UnixZTime;
|
515
524
|
} else if (xmlschema_sym == v) {
|
516
525
|
copts->time_format = XmlTime;
|
517
526
|
} else if (ruby_sym == v) {
|
518
527
|
copts->time_format = RubyTime;
|
519
528
|
} else {
|
520
|
-
rb_raise(rb_eArgError, ":time_format must be :unix, :xmlschema, or :ruby.");
|
529
|
+
rb_raise(rb_eArgError, ":time_format must be :unix, :unix_zone, :xmlschema, or :ruby.");
|
521
530
|
}
|
522
531
|
}
|
523
532
|
|
@@ -2042,6 +2051,7 @@ void Init_oj() {
|
|
2042
2051
|
oj_json_create_id = rb_intern("json_create");
|
2043
2052
|
oj_length_id = rb_intern("length");
|
2044
2053
|
oj_new_id = rb_intern("new");
|
2054
|
+
oj_parse_id = rb_intern("parse");
|
2045
2055
|
oj_pos_id = rb_intern("pos");
|
2046
2056
|
oj_read_id = rb_intern("read");
|
2047
2057
|
oj_readpartial_id = rb_intern("readpartial");
|
@@ -2056,7 +2066,9 @@ void Init_oj() {
|
|
2056
2066
|
oj_tv_nsec_id = rb_intern("tv_nsec");
|
2057
2067
|
oj_tv_sec_id = rb_intern("tv_sec");
|
2058
2068
|
oj_tv_usec_id = rb_intern("tv_usec");
|
2069
|
+
oj_utc_id = rb_intern("utc");
|
2059
2070
|
oj_utc_offset_id = rb_intern("utc_offset");
|
2071
|
+
oj_utcq_id = rb_intern("utc?");
|
2060
2072
|
oj_write_id = rb_intern("write");
|
2061
2073
|
|
2062
2074
|
rb_require("oj/bag");
|
@@ -2072,7 +2084,6 @@ void Init_oj() {
|
|
2072
2084
|
oj_parse_error_class = rb_const_get_at(Oj, rb_intern("ParseError"));
|
2073
2085
|
oj_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO"));
|
2074
2086
|
oj_struct_class = rb_const_get(rb_cObject, rb_intern("Struct"));
|
2075
|
-
oj_time_class = rb_const_get(rb_cObject, rb_intern("Time"));
|
2076
2087
|
|
2077
2088
|
allow_gc_sym = ID2SYM(rb_intern("allow_gc")); rb_gc_register_address(&allow_gc_sym);
|
2078
2089
|
ascii_only_sym = ID2SYM(rb_intern("ascii_only")); rb_gc_register_address(&ascii_only_sym);
|
@@ -2103,6 +2114,7 @@ void Init_oj() {
|
|
2103
2114
|
symbol_keys_sym = ID2SYM(rb_intern("symbol_keys")); rb_gc_register_address(&symbol_keys_sym);
|
2104
2115
|
time_format_sym = ID2SYM(rb_intern("time_format")); rb_gc_register_address(&time_format_sym);
|
2105
2116
|
unix_sym = ID2SYM(rb_intern("unix")); rb_gc_register_address(&unix_sym);
|
2117
|
+
unix_zone_sym = ID2SYM(rb_intern("unix_zone")); rb_gc_register_address(&unix_zone_sym);
|
2106
2118
|
use_to_json_sym = ID2SYM(rb_intern("use_to_json")); rb_gc_register_address(&use_to_json_sym);
|
2107
2119
|
xmlschema_sym = ID2SYM(rb_intern("xmlschema")); rb_gc_register_address(&xmlschema_sym);
|
2108
2120
|
xss_safe_sym = ID2SYM(rb_intern("xss_safe")); rb_gc_register_address(&xss_safe_sym);
|