oj 3.7.4 → 3.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -4
- data/ext/oj/buf.h +6 -34
- data/ext/oj/cache8.c +3 -3
- data/ext/oj/cache8.h +5 -33
- data/ext/oj/circarray.c +5 -9
- data/ext/oj/circarray.h +5 -8
- data/ext/oj/code.c +3 -6
- data/ext/oj/code.h +7 -10
- data/ext/oj/compat.c +11 -14
- data/ext/oj/custom.c +108 -75
- data/ext/oj/dump.c +132 -92
- data/ext/oj/dump.h +6 -7
- data/ext/oj/dump_compat.c +37 -34
- data/ext/oj/dump_leaf.c +3 -6
- data/ext/oj/dump_object.c +23 -17
- data/ext/oj/dump_strict.c +7 -9
- data/ext/oj/encode.h +6 -32
- data/ext/oj/err.c +2 -5
- data/ext/oj/err.h +6 -34
- data/ext/oj/extconf.rb +6 -0
- data/ext/oj/fast.c +39 -56
- data/ext/oj/hash.c +11 -39
- data/ext/oj/hash.h +5 -33
- data/ext/oj/hash_test.c +3 -31
- data/ext/oj/mimic_json.c +65 -44
- data/ext/oj/object.c +38 -69
- data/ext/oj/odd.c +18 -17
- data/ext/oj/odd.h +6 -9
- data/ext/oj/oj.c +139 -93
- data/ext/oj/oj.h +43 -35
- data/ext/oj/parse.c +164 -60
- data/ext/oj/parse.h +30 -31
- data/ext/oj/rails.c +119 -83
- data/ext/oj/rails.h +4 -7
- data/ext/oj/reader.c +5 -8
- data/ext/oj/reader.h +7 -10
- data/ext/oj/resolve.c +4 -7
- data/ext/oj/resolve.h +4 -7
- data/ext/oj/rxclass.c +8 -11
- data/ext/oj/rxclass.h +8 -11
- data/ext/oj/saj.c +9 -12
- data/ext/oj/scp.c +4 -7
- data/ext/oj/sparse.c +67 -33
- data/ext/oj/stream_writer.c +16 -15
- data/ext/oj/strict.c +9 -12
- data/ext/oj/string_writer.c +27 -8
- data/ext/oj/trace.c +5 -8
- data/ext/oj/trace.h +9 -12
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +19 -0
- data/ext/oj/val_stack.c +28 -36
- data/ext/oj/val_stack.h +19 -50
- data/ext/oj/wab.c +29 -29
- data/lib/oj.rb +0 -8
- data/lib/oj/json.rb +1 -1
- data/lib/oj/mimic.rb +46 -2
- data/lib/oj/version.rb +2 -2
- data/pages/Modes.md +47 -45
- data/pages/Options.md +43 -10
- data/pages/Rails.md +60 -21
- data/pages/Security.md +1 -1
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/bar.rb +24 -6
- data/test/baz.rb +16 -0
- data/test/foo.rb +26 -57
- data/test/helper.rb +10 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +21 -10
- data/test/test_custom.rb +135 -8
- data/test/test_integer_range.rb +1 -2
- data/test/test_object.rb +35 -2
- data/test/test_rails.rb +35 -0
- data/test/test_strict.rb +24 -1
- data/test/test_various.rb +52 -63
- data/test/test_writer.rb +19 -2
- data/test/tests.rb +1 -0
- data/test/zoo.rb +13 -0
- metadata +100 -75
data/ext/oj/stream_writer.c
CHANGED
@@ -1,13 +1,10 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, 2017, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <errno.h>
|
7
4
|
|
8
5
|
#include <ruby.h>
|
9
6
|
|
10
|
-
#include "
|
7
|
+
#include "encode.h"
|
11
8
|
|
12
9
|
extern VALUE Oj;
|
13
10
|
|
@@ -36,11 +33,17 @@ stream_writer_write(StreamWriter sw) {
|
|
36
33
|
|
37
34
|
switch (sw->type) {
|
38
35
|
case STRING_IO:
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
case STREAM_IO: {
|
37
|
+
volatile VALUE rs = rb_str_new(sw->sw.out.buf, size);
|
38
|
+
|
39
|
+
// Oddly enough, when pushing ASCII characters with UTF-8 encoding or
|
40
|
+
// even ASCII-8BIT does not change the output encoding. Pushing any
|
41
|
+
// non-ASCII no matter what the encoding changes the output encoding
|
42
|
+
// to ASCII-8BIT if it the string is not forced to UTF-8 here.
|
43
|
+
rs = oj_encode(rs);
|
44
|
+
rb_funcall(sw->stream, oj_write_id, 1, rs);
|
43
45
|
break;
|
46
|
+
}
|
44
47
|
case FILE_IO:
|
45
48
|
if (size != write(sw->fd, sw->sw.out.buf, size)) {
|
46
49
|
rb_raise(rb_eIOError, "Write failed. [_%d_:%s]\n", errno, strerror(errno));
|
@@ -80,7 +83,7 @@ stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
80
83
|
#if !IS_WINDOWS
|
81
84
|
VALUE s;
|
82
85
|
#endif
|
83
|
-
|
86
|
+
|
84
87
|
if (oj_stringio_class == clas) {
|
85
88
|
type = STRING_IO;
|
86
89
|
#if !IS_WINDOWS
|
@@ -94,14 +97,14 @@ stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
94
97
|
} else {
|
95
98
|
rb_raise(rb_eArgError, "expected an IO Object.");
|
96
99
|
}
|
97
|
-
sw = ALLOC(struct
|
100
|
+
sw = ALLOC(struct _streamWriter);
|
98
101
|
if (2 == argc && T_HASH == rb_type(argv[1])) {
|
99
102
|
volatile VALUE v;
|
100
103
|
int buf_size = 0;
|
101
104
|
|
102
105
|
if (Qundef == buffer_size_sym) {
|
103
106
|
buffer_size_sym = ID2SYM(rb_intern("buffer_size")); rb_gc_register_address(&buffer_size_sym);
|
104
|
-
|
107
|
+
|
105
108
|
}
|
106
109
|
if (Qnil != (v = rb_hash_lookup(argv[1], buffer_size_sym))) {
|
107
110
|
#ifdef RUBY_INTEGER_UNIFICATION
|
@@ -334,7 +337,7 @@ stream_writer_flush(VALUE self) {
|
|
334
337
|
}
|
335
338
|
|
336
339
|
/* Document-class: Oj::StreamWriter
|
337
|
-
*
|
340
|
+
*
|
338
341
|
* Supports building a JSON document one element at a time. Build the IO stream
|
339
342
|
* document by pushing values into the document. Pushing an array or an object
|
340
343
|
* will create that element in the JSON document and subsequent pushes will add
|
@@ -353,5 +356,3 @@ oj_stream_writer_init() {
|
|
353
356
|
rb_define_method(oj_stream_writer_class, "pop_all", stream_writer_pop_all, 0);
|
354
357
|
rb_define_method(oj_stream_writer_class, "flush", stream_writer_flush, 0);
|
355
358
|
}
|
356
|
-
|
357
|
-
|
data/ext/oj/strict.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <stdlib.h>
|
7
4
|
#include <stdio.h>
|
@@ -15,21 +12,21 @@
|
|
15
12
|
#include "trace.h"
|
16
13
|
|
17
14
|
static void
|
18
|
-
hash_end(
|
15
|
+
hash_end(ParseInfo pi) {
|
19
16
|
if (Yes == pi->options.trace) {
|
20
17
|
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
21
18
|
}
|
22
19
|
}
|
23
20
|
|
24
21
|
static void
|
25
|
-
array_end(
|
22
|
+
array_end(ParseInfo pi) {
|
26
23
|
if (Yes == pi->options.trace) {
|
27
24
|
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
28
25
|
}
|
29
26
|
}
|
30
27
|
|
31
28
|
static VALUE
|
32
|
-
noop_hash_key(
|
29
|
+
noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
33
30
|
return Qundef;
|
34
31
|
}
|
35
32
|
|
@@ -100,9 +97,9 @@ hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char
|
|
100
97
|
}
|
101
98
|
|
102
99
|
static void
|
103
|
-
hash_set_num(
|
100
|
+
hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
104
101
|
volatile VALUE v;
|
105
|
-
|
102
|
+
|
106
103
|
if (ni->infinity || ni->nan) {
|
107
104
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
108
105
|
}
|
@@ -143,7 +140,7 @@ array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
143
140
|
static void
|
144
141
|
array_append_num(ParseInfo pi, NumInfo ni) {
|
145
142
|
volatile VALUE v;
|
146
|
-
|
143
|
+
|
147
144
|
if (ni->infinity || ni->nan) {
|
148
145
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
149
146
|
}
|
@@ -183,7 +180,7 @@ oj_set_strict_callbacks(ParseInfo pi) {
|
|
183
180
|
|
184
181
|
VALUE
|
185
182
|
oj_strict_parse(int argc, VALUE *argv, VALUE self) {
|
186
|
-
struct
|
183
|
+
struct _parseInfo pi;
|
187
184
|
|
188
185
|
parse_info_init(&pi);
|
189
186
|
pi.options = oj_default_options;
|
@@ -200,7 +197,7 @@ oj_strict_parse(int argc, VALUE *argv, VALUE self) {
|
|
200
197
|
|
201
198
|
VALUE
|
202
199
|
oj_strict_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
|
203
|
-
struct
|
200
|
+
struct _parseInfo pi;
|
204
201
|
|
205
202
|
parse_info_init(&pi);
|
206
203
|
pi.options = oj_default_options;
|
data/ext/oj/string_writer.c
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, 2017, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include "dump.h"
|
7
4
|
#include "encode.h"
|
8
5
|
|
9
6
|
extern VALUE Oj;
|
10
7
|
|
8
|
+
bool string_writer_optimized = false;
|
9
|
+
|
11
10
|
static void
|
12
11
|
key_check(StrWriter sw, const char *key) {
|
13
12
|
DumpType type = sw->types[sw->depth];
|
@@ -152,7 +151,7 @@ oj_str_writer_push_array(StrWriter sw, const char *key) {
|
|
152
151
|
void
|
153
152
|
oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) {
|
154
153
|
Out out = &sw->out;
|
155
|
-
|
154
|
+
|
156
155
|
if (sw->keyWritten) {
|
157
156
|
sw->keyWritten = 0;
|
158
157
|
} else {
|
@@ -272,8 +271,8 @@ str_writer_free(void *ptr) {
|
|
272
271
|
*/
|
273
272
|
static VALUE
|
274
273
|
str_writer_new(int argc, VALUE *argv, VALUE self) {
|
275
|
-
StrWriter sw = ALLOC(struct
|
276
|
-
|
274
|
+
StrWriter sw = ALLOC(struct _strWriter);
|
275
|
+
|
277
276
|
oj_str_writer_init(sw, 0);
|
278
277
|
if (1 == argc) {
|
279
278
|
oj_parse_options(argv[0], &sw->opts);
|
@@ -487,8 +486,26 @@ str_writer_to_s(VALUE self) {
|
|
487
486
|
return oj_encode(rstr);
|
488
487
|
}
|
489
488
|
|
489
|
+
/* Document-method: as_json
|
490
|
+
* call-seq: as_json()
|
491
|
+
*
|
492
|
+
* Returns the contents of the writer as a JSON element. If called from inside
|
493
|
+
* an array or hash by Oj the raw buffer will be used othersize a more
|
494
|
+
* inefficient parse of the contents and a return of the result is
|
495
|
+
* completed. The parse uses the trict mode.
|
496
|
+
*
|
497
|
+
* *return* [_Hash_|_Array_|_String_|_Integer_|_Float_|_True_|_False_|_nil|)
|
498
|
+
*/
|
499
|
+
static VALUE
|
500
|
+
str_writer_as_json(VALUE self) {
|
501
|
+
if (string_writer_optimized) {
|
502
|
+
return self;
|
503
|
+
}
|
504
|
+
return rb_hash_new();
|
505
|
+
}
|
506
|
+
|
490
507
|
/* Document-class: Oj::StringWriter
|
491
|
-
*
|
508
|
+
*
|
492
509
|
* Supports building a JSON document one element at a time. Build the document
|
493
510
|
* by pushing values into the document. Pushing an array or an object will
|
494
511
|
* create that element in the JSON document and subsequent pushes will add the
|
@@ -509,4 +526,6 @@ oj_string_writer_init() {
|
|
509
526
|
rb_define_method(oj_string_writer_class, "pop_all", str_writer_pop_all, 0);
|
510
527
|
rb_define_method(oj_string_writer_class, "reset", str_writer_reset, 0);
|
511
528
|
rb_define_method(oj_string_writer_class, "to_s", str_writer_to_s, 0);
|
529
|
+
rb_define_method(oj_string_writer_class, "raw_json", str_writer_to_s, 0);
|
530
|
+
rb_define_method(oj_string_writer_class, "as_json", str_writer_as_json, 0);
|
512
531
|
}
|
data/ext/oj/trace.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2018, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2018 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include "parse.h"
|
7
4
|
#include "trace.h"
|
@@ -37,7 +34,7 @@ oj_trace_parse_call(const char *func, ParseInfo pi, const char *file, int line,
|
|
37
34
|
char fmt[64];
|
38
35
|
char indent[MAX_INDENT];
|
39
36
|
int depth = (int)(stack_size(&pi->stack) * 2);
|
40
|
-
|
37
|
+
|
41
38
|
fill_indent(indent, depth);
|
42
39
|
sprintf(fmt, "#0:%%13s:%%3d:Oj:-:%%%ds %%s %%s\n", depth);
|
43
40
|
printf(fmt, file, line, indent, func, rb_obj_classname(obj));
|
@@ -48,7 +45,7 @@ oj_trace_parse_in(const char *func, ParseInfo pi, const char *file, int line) {
|
|
48
45
|
char fmt[64];
|
49
46
|
char indent[MAX_INDENT];
|
50
47
|
int depth = (int)(stack_size(&pi->stack) * 2);
|
51
|
-
|
48
|
+
|
52
49
|
fill_indent(indent, depth);
|
53
50
|
sprintf(fmt, "#0:%%13s:%%3d:Oj:}:%%%ds %%s\n", depth);
|
54
51
|
printf(fmt, file, line, indent, func);
|
@@ -61,7 +58,7 @@ oj_trace_parse_hash_end(ParseInfo pi, const char *file, int line) {
|
|
61
58
|
int depth = (int)(stack_size(&pi->stack) * 2 - 2);
|
62
59
|
Val v = stack_peek(&pi->stack);
|
63
60
|
VALUE obj = v->val;
|
64
|
-
|
61
|
+
|
65
62
|
fill_indent(indent, depth);
|
66
63
|
sprintf(fmt, "#0:%%13s:%%3d:Oj:{:%%%ds hash_end %%s\n", depth);
|
67
64
|
printf(fmt, file, line, indent, rb_obj_classname(obj));
|
@@ -72,7 +69,7 @@ oj_trace_parse_array_end(ParseInfo pi, const char *file, int line) {
|
|
72
69
|
char fmt[64];
|
73
70
|
char indent[MAX_INDENT];
|
74
71
|
int depth = (int)(stack_size(&pi->stack) * 2);
|
75
|
-
|
72
|
+
|
76
73
|
fill_indent(indent, depth);
|
77
74
|
sprintf(fmt, "#0:%%13s:%%3d:Oj:{:%%%ds array_ned\n", depth);
|
78
75
|
printf(fmt, file, line, indent);
|
data/ext/oj/trace.h
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2018, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2018 Peter Ohler. All rights reserved.
|
5
2
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
3
|
+
#ifndef OJ_TRACE_H
|
4
|
+
#define OJ_TRACE_H
|
8
5
|
|
9
6
|
#include <stdbool.h>
|
10
7
|
#include <ruby.h>
|
@@ -17,12 +14,12 @@ typedef enum {
|
|
17
14
|
TraceRubyOut = '<',
|
18
15
|
} TraceWhere;
|
19
16
|
|
20
|
-
struct
|
17
|
+
struct _parseInfo;
|
21
18
|
|
22
19
|
extern void oj_trace(const char *func, VALUE obj, const char *file, int line, int depth, TraceWhere where);
|
23
|
-
extern void oj_trace_parse_in(const char *func, struct
|
24
|
-
extern void oj_trace_parse_call(const char *func, struct
|
25
|
-
extern void oj_trace_parse_hash_end(struct
|
26
|
-
extern void oj_trace_parse_array_end(struct
|
20
|
+
extern void oj_trace_parse_in(const char *func, struct _parseInfo *pi, const char *file, int line);
|
21
|
+
extern void oj_trace_parse_call(const char *func, struct _parseInfo *pi, const char *file, int line, VALUE obj);
|
22
|
+
extern void oj_trace_parse_hash_end(struct _parseInfo *pi, const char *file, int line);
|
23
|
+
extern void oj_trace_parse_array_end(struct _parseInfo *pi, const char *file, int line);
|
27
24
|
|
28
|
-
#endif /*
|
25
|
+
#endif /* OJ_TRACE_H */
|
data/ext/oj/util.c
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
// Copyright (c) 2019 Peter Ohler. All rights reserved.
|
2
|
+
|
3
|
+
#include "util.h"
|
4
|
+
|
5
|
+
#include <stdbool.h>
|
6
|
+
#include <stdint.h>
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <string.h>
|
9
|
+
#include <time.h>
|
10
|
+
|
11
|
+
#define SECS_PER_DAY 86400LL
|
12
|
+
#define SECS_PER_YEAR 31536000LL
|
13
|
+
#define SECS_PER_LEAP 31622400LL
|
14
|
+
#define SECS_PER_QUAD_YEAR (SECS_PER_YEAR * 3 + SECS_PER_LEAP)
|
15
|
+
#define SECS_PER_CENT (SECS_PER_QUAD_YEAR * 24 + SECS_PER_YEAR * 4)
|
16
|
+
#define SECS_PER_LEAP_CENT (SECS_PER_CENT + SECS_PER_DAY)
|
17
|
+
#define SECS_PER_QUAD_CENT (SECS_PER_CENT * 4 + SECS_PER_DAY)
|
18
|
+
|
19
|
+
static int64_t eom_secs[] = {
|
20
|
+
2678400, // January (31)
|
21
|
+
5097600, // February (28) 2419200 2505600
|
22
|
+
7776000, // March (31)
|
23
|
+
10368000, // April (30 2592000
|
24
|
+
13046400, // May (31)
|
25
|
+
15638400, // June (30)
|
26
|
+
18316800, // July (31)
|
27
|
+
20995200, // August (31)
|
28
|
+
23587200, // September (30)
|
29
|
+
26265600, // October (31)
|
30
|
+
28857600, // November (30)
|
31
|
+
31536000, // December (31)
|
32
|
+
};
|
33
|
+
|
34
|
+
static int64_t eom_leap_secs[] = {
|
35
|
+
2678400, // January (31)
|
36
|
+
5184000, // February (28) 2419200 2505600
|
37
|
+
7862400, // March (31)
|
38
|
+
10454400, // April (30 2592000
|
39
|
+
13132800, // May (31)
|
40
|
+
15724800, // June (30)
|
41
|
+
18403200, // July (31)
|
42
|
+
21081600, // August (31)
|
43
|
+
23673600, // September (30)
|
44
|
+
26352000, // October (31)
|
45
|
+
28944000, // November (30)
|
46
|
+
31622400, // December (31)
|
47
|
+
};
|
48
|
+
|
49
|
+
|
50
|
+
void
|
51
|
+
sec_as_time(int64_t secs, TimeInfo ti) {
|
52
|
+
int64_t qc = 0;
|
53
|
+
int64_t c = 0;
|
54
|
+
int64_t qy = 0;
|
55
|
+
int64_t y = 0;
|
56
|
+
bool leap = false;
|
57
|
+
int64_t *ms;
|
58
|
+
int m;
|
59
|
+
int shift = 0;
|
60
|
+
|
61
|
+
secs += 62167219200LL; // normalize to first day of the year 0
|
62
|
+
if (secs < 0) {
|
63
|
+
shift = -secs / SECS_PER_QUAD_CENT;
|
64
|
+
shift++;
|
65
|
+
secs += shift * SECS_PER_QUAD_CENT;
|
66
|
+
}
|
67
|
+
qc = secs / SECS_PER_QUAD_CENT;
|
68
|
+
secs = secs - qc * SECS_PER_QUAD_CENT;
|
69
|
+
if (secs < SECS_PER_LEAP) {
|
70
|
+
leap = true;
|
71
|
+
} else if (secs < SECS_PER_QUAD_YEAR) {
|
72
|
+
if (SECS_PER_LEAP <= secs) {
|
73
|
+
secs -= SECS_PER_LEAP;
|
74
|
+
y = secs / SECS_PER_YEAR;
|
75
|
+
secs = secs - y * SECS_PER_YEAR;
|
76
|
+
y++;
|
77
|
+
leap = false;
|
78
|
+
}
|
79
|
+
} else if (secs < SECS_PER_LEAP_CENT) { // first century in 400 years is a leap century (one extra day)
|
80
|
+
qy = secs / SECS_PER_QUAD_YEAR;
|
81
|
+
secs = secs - qy * SECS_PER_QUAD_YEAR;
|
82
|
+
if (secs < SECS_PER_LEAP) {
|
83
|
+
leap = true;
|
84
|
+
} else {
|
85
|
+
secs -= SECS_PER_LEAP;
|
86
|
+
y = secs / SECS_PER_YEAR;
|
87
|
+
secs = secs - y * SECS_PER_YEAR;
|
88
|
+
y++;
|
89
|
+
}
|
90
|
+
} else {
|
91
|
+
secs -= SECS_PER_LEAP_CENT;
|
92
|
+
c = secs / SECS_PER_CENT;
|
93
|
+
secs = secs - c * SECS_PER_CENT;
|
94
|
+
c++;
|
95
|
+
if (secs < SECS_PER_YEAR * 4) {
|
96
|
+
y = secs / SECS_PER_YEAR;
|
97
|
+
secs = secs - y * SECS_PER_YEAR;
|
98
|
+
} else {
|
99
|
+
secs -= SECS_PER_YEAR * 4;
|
100
|
+
qy = secs / SECS_PER_QUAD_YEAR;
|
101
|
+
secs = secs - qy * SECS_PER_QUAD_YEAR;
|
102
|
+
qy++;
|
103
|
+
if (secs < SECS_PER_LEAP) {
|
104
|
+
leap = true;
|
105
|
+
} else {
|
106
|
+
secs -= SECS_PER_LEAP;
|
107
|
+
y = secs / SECS_PER_YEAR;
|
108
|
+
secs = secs - y * SECS_PER_YEAR;
|
109
|
+
y++;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
ti->year = (int)((qc - (int64_t)shift) * 400 + c * 100 + qy * 4 + y);
|
114
|
+
if (leap) {
|
115
|
+
ms = eom_leap_secs;
|
116
|
+
} else {
|
117
|
+
ms = eom_secs;
|
118
|
+
}
|
119
|
+
for (m = 1; m <= 12; m++, ms++) {
|
120
|
+
if (secs < *ms) {
|
121
|
+
if (1 < m) {
|
122
|
+
secs -= *(ms - 1);
|
123
|
+
}
|
124
|
+
ti->mon = m;
|
125
|
+
break;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
ti->day = (int)(secs / 86400LL);
|
129
|
+
secs = secs - (int64_t)ti->day * 86400LL;
|
130
|
+
ti->day++;
|
131
|
+
ti->hour = (int)(secs / 3600LL);
|
132
|
+
secs = secs - (int64_t)ti->hour * 3600LL;
|
133
|
+
ti->min = (int)(secs / 60LL);
|
134
|
+
secs = secs - (int64_t)ti->min * 60LL;
|
135
|
+
ti->sec = (int)secs;
|
136
|
+
}
|
data/ext/oj/util.h
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
// Copyright (c) 2019 Peter Ohler. All rights reserved.
|
2
|
+
|
3
|
+
#ifndef OJ_UTIL_H
|
4
|
+
#define OJ_UTIL_H
|
5
|
+
|
6
|
+
#include <stdint.h>
|
7
|
+
|
8
|
+
typedef struct _timeInfo {
|
9
|
+
int sec;
|
10
|
+
int min;
|
11
|
+
int hour;
|
12
|
+
int day;
|
13
|
+
int mon;
|
14
|
+
int year;
|
15
|
+
} *TimeInfo;
|
16
|
+
|
17
|
+
extern void sec_as_time(int64_t secs, TimeInfo ti);
|
18
|
+
|
19
|
+
#endif /* OJ_UTIL_H */
|