oj 3.7.4 → 3.11.2
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.
- 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 */
|