oj 3.7.4 → 3.11.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -4
  3. data/ext/oj/buf.h +6 -34
  4. data/ext/oj/cache8.c +3 -3
  5. data/ext/oj/cache8.h +5 -33
  6. data/ext/oj/circarray.c +5 -9
  7. data/ext/oj/circarray.h +5 -8
  8. data/ext/oj/code.c +3 -6
  9. data/ext/oj/code.h +7 -10
  10. data/ext/oj/compat.c +11 -14
  11. data/ext/oj/custom.c +108 -75
  12. data/ext/oj/dump.c +132 -92
  13. data/ext/oj/dump.h +6 -7
  14. data/ext/oj/dump_compat.c +37 -34
  15. data/ext/oj/dump_leaf.c +3 -6
  16. data/ext/oj/dump_object.c +23 -17
  17. data/ext/oj/dump_strict.c +7 -9
  18. data/ext/oj/encode.h +6 -32
  19. data/ext/oj/err.c +2 -5
  20. data/ext/oj/err.h +6 -34
  21. data/ext/oj/extconf.rb +6 -0
  22. data/ext/oj/fast.c +39 -56
  23. data/ext/oj/hash.c +11 -39
  24. data/ext/oj/hash.h +5 -33
  25. data/ext/oj/hash_test.c +3 -31
  26. data/ext/oj/mimic_json.c +65 -44
  27. data/ext/oj/object.c +38 -69
  28. data/ext/oj/odd.c +18 -17
  29. data/ext/oj/odd.h +6 -9
  30. data/ext/oj/oj.c +139 -93
  31. data/ext/oj/oj.h +43 -35
  32. data/ext/oj/parse.c +164 -60
  33. data/ext/oj/parse.h +30 -31
  34. data/ext/oj/rails.c +119 -83
  35. data/ext/oj/rails.h +4 -7
  36. data/ext/oj/reader.c +5 -8
  37. data/ext/oj/reader.h +7 -10
  38. data/ext/oj/resolve.c +4 -7
  39. data/ext/oj/resolve.h +4 -7
  40. data/ext/oj/rxclass.c +8 -11
  41. data/ext/oj/rxclass.h +8 -11
  42. data/ext/oj/saj.c +9 -12
  43. data/ext/oj/scp.c +4 -7
  44. data/ext/oj/sparse.c +67 -33
  45. data/ext/oj/stream_writer.c +16 -15
  46. data/ext/oj/strict.c +9 -12
  47. data/ext/oj/string_writer.c +27 -8
  48. data/ext/oj/trace.c +5 -8
  49. data/ext/oj/trace.h +9 -12
  50. data/ext/oj/util.c +136 -0
  51. data/ext/oj/util.h +19 -0
  52. data/ext/oj/val_stack.c +28 -36
  53. data/ext/oj/val_stack.h +19 -50
  54. data/ext/oj/wab.c +29 -29
  55. data/lib/oj.rb +0 -8
  56. data/lib/oj/json.rb +1 -1
  57. data/lib/oj/mimic.rb +46 -2
  58. data/lib/oj/version.rb +2 -2
  59. data/pages/Modes.md +47 -45
  60. data/pages/Options.md +43 -10
  61. data/pages/Rails.md +60 -21
  62. data/pages/Security.md +1 -1
  63. data/test/activesupport5/abstract_unit.rb +45 -0
  64. data/test/activesupport5/decoding_test.rb +68 -60
  65. data/test/activesupport5/encoding_test.rb +111 -96
  66. data/test/activesupport5/encoding_test_cases.rb +33 -25
  67. data/test/activesupport5/test_helper.rb +43 -21
  68. data/test/activesupport5/time_zone_test_helpers.rb +18 -3
  69. data/test/activesupport6/abstract_unit.rb +44 -0
  70. data/test/activesupport6/decoding_test.rb +133 -0
  71. data/test/activesupport6/encoding_test.rb +507 -0
  72. data/test/activesupport6/encoding_test_cases.rb +98 -0
  73. data/test/activesupport6/test_common.rb +17 -0
  74. data/test/activesupport6/test_helper.rb +163 -0
  75. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  76. data/test/bar.rb +24 -6
  77. data/test/baz.rb +16 -0
  78. data/test/foo.rb +26 -57
  79. data/test/helper.rb +10 -0
  80. data/test/json_gem/json_common_interface_test.rb +8 -3
  81. data/test/json_gem/json_generator_test.rb +15 -3
  82. data/test/json_gem/test_helper.rb +8 -0
  83. data/test/prec.rb +23 -0
  84. data/test/sample_json.rb +1 -1
  85. data/test/test_compat.rb +21 -10
  86. data/test/test_custom.rb +135 -8
  87. data/test/test_integer_range.rb +1 -2
  88. data/test/test_object.rb +35 -2
  89. data/test/test_rails.rb +35 -0
  90. data/test/test_strict.rb +24 -1
  91. data/test/test_various.rb +52 -63
  92. data/test/test_writer.rb +19 -2
  93. data/test/tests.rb +1 -0
  94. data/test/zoo.rb +13 -0
  95. metadata +100 -75
@@ -1,13 +1,10 @@
1
- /* stream_writer.c
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 "oj.h"
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
- rb_funcall(sw->stream, oj_write_id, 1, rb_str_new(sw->sw.out.buf, size));
40
- break;
41
- case STREAM_IO:
42
- rb_funcall(sw->stream, oj_write_id, 1, rb_str_new(sw->sw.out.buf, size));
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 _StreamWriter);
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
- /* strict.c
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(struct _ParseInfo *pi) {
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(struct _ParseInfo *pi) {
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(struct _ParseInfo *pi, const char *key, size_t klen) {
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(struct _ParseInfo *pi, Val parent, NumInfo ni) {
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 _ParseInfo pi;
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 _ParseInfo pi;
200
+ struct _parseInfo pi;
204
201
 
205
202
  parse_info_init(&pi);
206
203
  pi.options = oj_default_options;
@@ -1,13 +1,12 @@
1
- /* strwriter.c
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 _StrWriter);
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
- /* trace.h
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
- /* trace.h
2
- * Copyright (c) 2018, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2018 Peter Ohler. All rights reserved.
5
2
 
6
- #ifndef __OJ_TRACE_H__
7
- #define __OJ_TRACE_H__
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 _ParseInfo;
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 _ParseInfo *pi, const char *file, int line);
24
- extern void oj_trace_parse_call(const char *func, struct _ParseInfo *pi, const char *file, int line, VALUE obj);
25
- extern void oj_trace_parse_hash_end(struct _ParseInfo *pi, const char *file, int line);
26
- extern void oj_trace_parse_array_end(struct _ParseInfo *pi, const char *file, int line);
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 /* __OJ_TRACE_H__ */
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 */