oj 3.7.4 → 3.13.21

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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1352 -0
  3. data/README.md +29 -8
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +53 -72
  6. data/ext/oj/cache.c +326 -0
  7. data/ext/oj/cache.h +21 -0
  8. data/ext/oj/cache8.c +61 -64
  9. data/ext/oj/cache8.h +12 -39
  10. data/ext/oj/circarray.c +37 -43
  11. data/ext/oj/circarray.h +16 -17
  12. data/ext/oj/code.c +165 -179
  13. data/ext/oj/code.h +27 -29
  14. data/ext/oj/compat.c +174 -194
  15. data/ext/oj/custom.c +809 -866
  16. data/ext/oj/debug.c +132 -0
  17. data/ext/oj/dump.c +848 -863
  18. data/ext/oj/dump.h +81 -67
  19. data/ext/oj/dump_compat.c +85 -123
  20. data/ext/oj/dump_leaf.c +100 -188
  21. data/ext/oj/dump_object.c +527 -656
  22. data/ext/oj/dump_strict.c +315 -338
  23. data/ext/oj/encode.h +7 -34
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +40 -29
  26. data/ext/oj/err.h +48 -48
  27. data/ext/oj/extconf.rb +17 -4
  28. data/ext/oj/fast.c +1070 -1087
  29. data/ext/oj/intern.c +301 -0
  30. data/ext/oj/intern.h +26 -0
  31. data/ext/oj/mimic_json.c +469 -436
  32. data/ext/oj/object.c +525 -593
  33. data/ext/oj/odd.c +154 -138
  34. data/ext/oj/odd.h +37 -38
  35. data/ext/oj/oj.c +1325 -986
  36. data/ext/oj/oj.h +333 -316
  37. data/ext/oj/parse.c +1002 -846
  38. data/ext/oj/parse.h +92 -87
  39. data/ext/oj/parser.c +1557 -0
  40. data/ext/oj/parser.h +91 -0
  41. data/ext/oj/rails.c +888 -878
  42. data/ext/oj/rails.h +11 -14
  43. data/ext/oj/reader.c +141 -147
  44. data/ext/oj/reader.h +73 -89
  45. data/ext/oj/resolve.c +41 -62
  46. data/ext/oj/resolve.h +7 -9
  47. data/ext/oj/rxclass.c +71 -75
  48. data/ext/oj/rxclass.h +18 -19
  49. data/ext/oj/saj.c +443 -486
  50. data/ext/oj/saj2.c +602 -0
  51. data/ext/oj/scp.c +88 -113
  52. data/ext/oj/sparse.c +787 -709
  53. data/ext/oj/stream_writer.c +133 -159
  54. data/ext/oj/strict.c +127 -118
  55. data/ext/oj/string_writer.c +230 -249
  56. data/ext/oj/trace.c +34 -41
  57. data/ext/oj/trace.h +19 -19
  58. data/ext/oj/usual.c +1254 -0
  59. data/ext/oj/util.c +136 -0
  60. data/ext/oj/util.h +20 -0
  61. data/ext/oj/val_stack.c +59 -67
  62. data/ext/oj/val_stack.h +91 -129
  63. data/ext/oj/validate.c +46 -0
  64. data/ext/oj/wab.c +342 -353
  65. data/lib/oj/bag.rb +1 -0
  66. data/lib/oj/easy_hash.rb +5 -4
  67. data/lib/oj/error.rb +1 -1
  68. data/lib/oj/json.rb +1 -1
  69. data/lib/oj/mimic.rb +48 -14
  70. data/lib/oj/saj.rb +20 -6
  71. data/lib/oj/state.rb +8 -7
  72. data/lib/oj/version.rb +2 -2
  73. data/lib/oj.rb +0 -8
  74. data/pages/Compatibility.md +1 -1
  75. data/pages/JsonGem.md +15 -0
  76. data/pages/Modes.md +53 -46
  77. data/pages/Options.md +72 -11
  78. data/pages/Parser.md +309 -0
  79. data/pages/Rails.md +73 -22
  80. data/pages/Security.md +1 -1
  81. data/test/activerecord/result_test.rb +7 -2
  82. data/test/activesupport5/abstract_unit.rb +45 -0
  83. data/test/activesupport5/decoding_test.rb +68 -60
  84. data/test/activesupport5/encoding_test.rb +111 -96
  85. data/test/activesupport5/encoding_test_cases.rb +33 -25
  86. data/test/activesupport5/test_helper.rb +43 -21
  87. data/test/activesupport5/time_zone_test_helpers.rb +18 -3
  88. data/test/activesupport6/abstract_unit.rb +44 -0
  89. data/test/activesupport6/decoding_test.rb +133 -0
  90. data/test/activesupport6/encoding_test.rb +507 -0
  91. data/test/activesupport6/encoding_test_cases.rb +98 -0
  92. data/test/activesupport6/test_common.rb +17 -0
  93. data/test/activesupport6/test_helper.rb +163 -0
  94. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  95. data/test/activesupport7/abstract_unit.rb +49 -0
  96. data/test/activesupport7/decoding_test.rb +125 -0
  97. data/test/activesupport7/encoding_test.rb +486 -0
  98. data/test/activesupport7/encoding_test_cases.rb +104 -0
  99. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  100. data/test/bar.rb +6 -12
  101. data/test/baz.rb +16 -0
  102. data/test/bug.rb +16 -0
  103. data/test/foo.rb +69 -75
  104. data/test/helper.rb +16 -0
  105. data/test/json_gem/json_common_interface_test.rb +8 -3
  106. data/test/json_gem/json_generator_test.rb +18 -4
  107. data/test/json_gem/json_parser_test.rb +9 -0
  108. data/test/json_gem/test_helper.rb +12 -0
  109. data/test/mem.rb +33 -0
  110. data/test/perf.rb +1 -1
  111. data/test/perf_dump.rb +50 -0
  112. data/test/perf_once.rb +58 -0
  113. data/test/perf_parser.rb +189 -0
  114. data/test/perf_scp.rb +11 -10
  115. data/test/perf_strict.rb +17 -23
  116. data/test/prec.rb +23 -0
  117. data/test/sample_json.rb +1 -1
  118. data/test/test_compat.rb +46 -10
  119. data/test/test_custom.rb +147 -8
  120. data/test/test_fast.rb +62 -2
  121. data/test/test_file.rb +25 -2
  122. data/test/test_gc.rb +13 -0
  123. data/test/test_generate.rb +21 -0
  124. data/test/test_hash.rb +11 -1
  125. data/test/test_integer_range.rb +7 -2
  126. data/test/test_object.rb +85 -9
  127. data/test/test_parser.rb +27 -0
  128. data/test/test_parser_saj.rb +335 -0
  129. data/test/test_parser_usual.rb +217 -0
  130. data/test/test_rails.rb +35 -0
  131. data/test/test_saj.rb +1 -1
  132. data/test/test_scp.rb +5 -5
  133. data/test/test_strict.rb +26 -1
  134. data/test/test_various.rb +87 -65
  135. data/test/test_wab.rb +2 -0
  136. data/test/test_writer.rb +19 -2
  137. data/test/tests.rb +1 -1
  138. data/test/zoo.rb +13 -0
  139. metadata +60 -110
  140. data/ext/oj/hash.c +0 -163
  141. data/ext/oj/hash.h +0 -46
  142. data/ext/oj/hash_test.c +0 -512
data/ext/oj/rails.h CHANGED
@@ -1,21 +1,18 @@
1
- /* rails.h
2
- * Copyright (c) 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2017 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
5
3
 
6
- #ifndef __OJ_RAILS_H__
7
- #define __OJ_RAILS_H__
4
+ #ifndef OJ_RAILS_H
5
+ #define OJ_RAILS_H
8
6
 
9
7
  #include "dump.h"
10
8
 
11
- extern void oj_mimic_rails_init();
12
- extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
9
+ extern void oj_mimic_rails_init(void);
10
+ extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
13
11
 
14
- extern bool oj_rails_hash_opt;
15
- extern bool oj_rails_array_opt;
16
- extern bool oj_rails_float_opt;
12
+ extern bool oj_rails_hash_opt;
13
+ extern bool oj_rails_array_opt;
14
+ extern bool oj_rails_float_opt;
17
15
 
18
- extern VALUE oj_optimize_rails(VALUE self);
16
+ extern VALUE oj_optimize_rails(VALUE self);
19
17
 
20
-
21
- #endif /* __OJ_RAILS_H__ */
18
+ #endif /* OJ_RAILS_H */
data/ext/oj/reader.c CHANGED
@@ -1,223 +1,217 @@
1
- /* reader.c
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
5
3
 
6
- #include <stdlib.h>
7
4
  #include <errno.h>
8
5
  #include <stdio.h>
6
+ #include <stdlib.h>
9
7
  #include <strings.h>
10
8
  #include <sys/types.h>
9
+ #ifdef NEEDS_UIO
11
10
  #if NEEDS_UIO
12
- #include <sys/uio.h>
11
+ #include <sys/uio.h>
12
+ #endif
13
13
  #endif
14
- #include <unistd.h>
15
14
  #include <time.h>
15
+ #include <unistd.h>
16
16
 
17
- #include "ruby.h"
18
17
  #include "oj.h"
19
18
  #include "reader.h"
19
+ #include "ruby.h"
20
20
 
21
- #define BUF_PAD 4
22
-
23
- static VALUE rescue_cb(VALUE rdr, VALUE err);
24
- static VALUE io_cb(VALUE rdr);
25
- static VALUE partial_io_cb(VALUE rdr);
26
- static int read_from_io(Reader reader);
27
- static int read_from_fd(Reader reader);
28
- static int read_from_io_partial(Reader reader);
29
- //static int read_from_str(Reader reader);
30
-
31
- void
32
- oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
33
- VALUE io_class = rb_obj_class(io);
34
- VALUE stat;
35
- VALUE ftype;
36
-
37
- reader->head = reader->base;
38
- *((char*)reader->head) = '\0';
39
- reader->end = reader->head + sizeof(reader->base) - BUF_PAD;
40
- reader->tail = reader->head;
41
- reader->read_end = reader->head;
42
- reader->pro = 0;
43
- reader->str = 0;
44
- reader->pos = 0;
45
- reader->line = 1;
46
- reader->col = 0;
47
- reader->free_head = 0;
21
+ #define BUF_PAD 4
22
+
23
+ static VALUE rescue_cb(VALUE rdr, VALUE err);
24
+ static VALUE io_cb(VALUE rdr);
25
+ static VALUE partial_io_cb(VALUE rdr);
26
+ static int read_from_io(Reader reader);
27
+ static int read_from_fd(Reader reader);
28
+ static int read_from_io_partial(Reader reader);
29
+ // static int read_from_str(Reader reader);
30
+
31
+ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
32
+ VALUE io_class = rb_obj_class(io);
33
+ VALUE stat;
34
+ VALUE ftype;
35
+
36
+ reader->head = reader->base;
37
+ *((char *)reader->head) = '\0';
38
+ reader->end = reader->head + sizeof(reader->base) - BUF_PAD;
39
+ reader->tail = reader->head;
40
+ reader->read_end = reader->head;
41
+ reader->pro = 0;
42
+ reader->str = 0;
43
+ reader->pos = 0;
44
+ reader->line = 1;
45
+ reader->col = 0;
46
+ reader->free_head = 0;
48
47
 
49
48
  if (0 != fd) {
50
- reader->read_func = read_from_fd;
51
- reader->fd = fd;
49
+ reader->read_func = read_from_fd;
50
+ reader->fd = fd;
52
51
  } else if (rb_cString == io_class) {
53
- reader->read_func = 0;
54
- reader->in_str = StringValuePtr(io);
55
- reader->head = (char*)reader->in_str;
56
- reader->tail = reader->head;
57
- reader->read_end = reader->head + RSTRING_LEN(io);
52
+ reader->read_func = 0;
53
+ reader->in_str = StringValuePtr(io);
54
+ reader->head = (char *)reader->in_str;
55
+ reader->tail = reader->head;
56
+ reader->read_end = reader->head + RSTRING_LEN(io);
58
57
  } else if (oj_stringio_class == io_class) {
59
- VALUE s = rb_funcall2(io, oj_string_id, 0, 0);
60
-
61
- reader->read_func = 0;
62
- reader->in_str = StringValuePtr(s);
63
- reader->head = (char*)reader->in_str;
64
- reader->tail = reader->head;
65
- reader->read_end = reader->head + RSTRING_LEN(s);
66
- } else if (rb_cFile == io_class &&
67
- Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
68
- Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) &&
69
- 0 == strcmp("file", StringValuePtr(ftype)) &&
70
- 0 == FIX2INT(rb_funcall(io, oj_pos_id, 0))) {
71
- reader->read_func = read_from_fd;
72
- reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
58
+ VALUE s = rb_funcall2(io, oj_string_id, 0, 0);
59
+
60
+ reader->read_func = 0;
61
+ reader->in_str = StringValuePtr(s);
62
+ reader->head = (char *)reader->in_str;
63
+ reader->tail = reader->head;
64
+ reader->read_end = reader->head + RSTRING_LEN(s);
65
+ } else if (rb_cFile == io_class && Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
66
+ Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) &&
67
+ 0 == strcmp("file", StringValuePtr(ftype)) &&
68
+ 0 == FIX2INT(rb_funcall(io, oj_pos_id, 0))) {
69
+ reader->read_func = read_from_fd;
70
+ reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
73
71
  } else if (rb_respond_to(io, oj_readpartial_id)) {
74
- reader->read_func = read_from_io_partial;
75
- reader->io = io;
72
+ reader->read_func = read_from_io_partial;
73
+ reader->io = io;
76
74
  } else if (rb_respond_to(io, oj_read_id)) {
77
- reader->read_func = read_from_io;
78
- reader->io = io;
75
+ reader->read_func = read_from_io;
76
+ reader->io = io;
79
77
  } else if (to_s) {
80
- volatile VALUE rstr = rb_funcall(io, oj_to_s_id, 0);
81
-
82
- reader->read_func = 0;
83
- reader->in_str = StringValuePtr(rstr);
84
- reader->head = (char*)reader->in_str;
85
- reader->tail = reader->head;
86
- reader->read_end = reader->head + RSTRING_LEN(rstr);
87
- } else {
88
- rb_raise(rb_eArgError, "parser io argument must be a String or respond to readpartial() or read().\n");
78
+ volatile VALUE rstr = rb_funcall(io, oj_to_s_id, 0);
79
+
80
+ reader->read_func = 0;
81
+ reader->in_str = StringValuePtr(rstr);
82
+ reader->head = (char *)reader->in_str;
83
+ reader->tail = reader->head;
84
+ reader->read_end = reader->head + RSTRING_LEN(rstr);
85
+ } else {
86
+ rb_raise(rb_eArgError,
87
+ "parser io argument must be a String or respond to readpartial() or read().\n");
89
88
  }
90
89
  }
91
90
 
92
- int
93
- oj_reader_read(Reader reader) {
94
- int err;
95
- size_t shift = 0;
91
+ int oj_reader_read(Reader reader) {
92
+ int err;
93
+ size_t shift = 0;
96
94
 
97
95
  if (0 == reader->read_func) {
98
- return -1;
96
+ return -1;
99
97
  }
100
98
  // if there is not much room to read into, shift or realloc a larger buffer.
101
99
  if (reader->head < reader->tail && 4096 > reader->end - reader->tail) {
102
- if (0 == reader->pro) {
103
- shift = reader->tail - reader->head;
104
- } else {
105
- shift = reader->pro - reader->head - 1; // leave one character so we can backup one
106
- }
107
- if (0 >= shift) { /* no space left so allocate more */
108
- const char *old = reader->head;
109
- size_t size = reader->end - reader->head + BUF_PAD;
110
-
111
- if (reader->head == reader->base) {
112
- reader->head = ALLOC_N(char, size * 2);
113
- memcpy((char*)reader->head, old, size);
114
- } else {
115
- REALLOC_N(reader->head, char, size * 2);
116
- }
117
- reader->free_head = 1;
118
- reader->end = reader->head + size * 2 - BUF_PAD;
119
- reader->tail = reader->head + (reader->tail - old);
120
- reader->read_end = reader->head + (reader->read_end - old);
121
- if (0 != reader->pro) {
122
- reader->pro = reader->head + (reader->pro - old);
123
- }
124
- if (0 != reader->str) {
125
- reader->str = reader->head + (reader->str - old);
126
- }
127
- } else {
128
- memmove((char*)reader->head, reader->head + shift, reader->read_end - (reader->head + shift));
129
- reader->tail -= shift;
130
- reader->read_end -= shift;
131
- if (0 != reader->pro) {
132
- reader->pro -= shift;
133
- }
134
- if (0 != reader->str) {
135
- reader->str -= shift;
136
- }
137
- }
100
+ if (0 == reader->pro) {
101
+ shift = reader->tail - reader->head;
102
+ } else {
103
+ shift = reader->pro - reader->head - 1; // leave one character so we can backup one
104
+ }
105
+ if (0 >= shift) { /* no space left so allocate more */
106
+ const char *old = reader->head;
107
+ size_t size = reader->end - reader->head + BUF_PAD;
108
+
109
+ if (reader->head == reader->base) {
110
+ reader->head = ALLOC_N(char, size * 2);
111
+ memcpy((char *)reader->head, old, size);
112
+ } else {
113
+ REALLOC_N(reader->head, char, size * 2);
114
+ }
115
+ reader->free_head = 1;
116
+ reader->end = reader->head + size * 2 - BUF_PAD;
117
+ reader->tail = reader->head + (reader->tail - old);
118
+ reader->read_end = reader->head + (reader->read_end - old);
119
+ if (0 != reader->pro) {
120
+ reader->pro = reader->head + (reader->pro - old);
121
+ }
122
+ if (0 != reader->str) {
123
+ reader->str = reader->head + (reader->str - old);
124
+ }
125
+ } else {
126
+ memmove((char *)reader->head,
127
+ reader->head + shift,
128
+ reader->read_end - (reader->head + shift));
129
+ reader->tail -= shift;
130
+ reader->read_end -= shift;
131
+ if (0 != reader->pro) {
132
+ reader->pro -= shift;
133
+ }
134
+ if (0 != reader->str) {
135
+ reader->str -= shift;
136
+ }
137
+ }
138
138
  }
139
- err = reader->read_func(reader);
140
- *(char*)reader->read_end = '\0';
139
+ err = reader->read_func(reader);
140
+ *(char *)reader->read_end = '\0';
141
141
 
142
142
  return err;
143
143
  }
144
144
 
145
- static VALUE
146
- rescue_cb(VALUE rbuf, VALUE err) {
147
- VALUE clas = rb_obj_class(err);
145
+ static VALUE rescue_cb(VALUE rbuf, VALUE err) {
146
+ VALUE clas = rb_obj_class(err);
148
147
 
149
148
  if (rb_eTypeError != clas && rb_eEOFError != clas) {
150
- Reader reader = (Reader)rbuf;
149
+ Reader reader = (Reader)rbuf;
151
150
 
152
- rb_raise(clas, "at line %d, column %d\n", reader->line, reader->col);
151
+ rb_raise(clas, "at line %d, column %d\n", reader->line, reader->col);
153
152
  }
154
153
  return Qfalse;
155
154
  }
156
155
 
157
- static VALUE
158
- partial_io_cb(VALUE rbuf) {
159
- Reader reader = (Reader)rbuf;
160
- VALUE args[1];
161
- VALUE rstr;
162
- char *str;
163
- size_t cnt;
156
+ static VALUE partial_io_cb(VALUE rbuf) {
157
+ Reader reader = (Reader)rbuf;
158
+ VALUE args[1];
159
+ VALUE rstr;
160
+ char * str;
161
+ size_t cnt;
164
162
 
165
163
  args[0] = ULONG2NUM(reader->end - reader->tail);
166
- rstr = rb_funcall2(reader->io, oj_readpartial_id, 1, args);
164
+ rstr = rb_funcall2(reader->io, oj_readpartial_id, 1, args);
167
165
  if (Qnil == rstr) {
168
- return Qfalse;
166
+ return Qfalse;
169
167
  }
170
168
  str = StringValuePtr(rstr);
171
169
  cnt = RSTRING_LEN(rstr);
172
- //printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
170
+ // printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
173
171
  strcpy(reader->tail, str);
174
172
  reader->read_end = reader->tail + cnt;
175
173
 
176
174
  return Qtrue;
177
175
  }
178
176
 
179
- static VALUE
180
- io_cb(VALUE rbuf) {
181
- Reader reader = (Reader)rbuf;
182
- VALUE args[1];
183
- VALUE rstr;
184
- char *str;
185
- size_t cnt;
177
+ static VALUE io_cb(VALUE rbuf) {
178
+ Reader reader = (Reader)rbuf;
179
+ VALUE args[1];
180
+ VALUE rstr;
181
+ char * str;
182
+ size_t cnt;
186
183
 
187
184
  args[0] = ULONG2NUM(reader->end - reader->tail);
188
- rstr = rb_funcall2(reader->io, oj_read_id, 1, args);
185
+ rstr = rb_funcall2(reader->io, oj_read_id, 1, args);
189
186
  if (Qnil == rstr) {
190
- return Qfalse;
187
+ return Qfalse;
191
188
  }
192
189
  str = StringValuePtr(rstr);
193
190
  cnt = RSTRING_LEN(rstr);
194
- //printf("*** read %lu bytes, str: '%s'\n", cnt, str);
191
+ // printf("*** read %lu bytes, str: '%s'\n", cnt, str);
195
192
  strcpy(reader->tail, str);
196
193
  reader->read_end = reader->tail + cnt;
197
194
 
198
195
  return Qtrue;
199
196
  }
200
197
 
201
- static int
202
- read_from_io_partial(Reader reader) {
198
+ static int read_from_io_partial(Reader reader) {
203
199
  return (Qfalse == rb_rescue(partial_io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
204
200
  }
205
201
 
206
- static int
207
- read_from_io(Reader reader) {
202
+ static int read_from_io(Reader reader) {
208
203
  return (Qfalse == rb_rescue(io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
209
204
  }
210
205
 
211
- static int
212
- read_from_fd(Reader reader) {
213
- ssize_t cnt;
214
- size_t max = reader->end - reader->tail;
206
+ static int read_from_fd(Reader reader) {
207
+ ssize_t cnt;
208
+ size_t max = reader->end - reader->tail;
215
209
 
216
210
  cnt = read(reader->fd, reader->tail, max);
217
211
  if (cnt <= 0) {
218
- return -1;
212
+ return -1;
219
213
  } else if (0 != cnt) {
220
- reader->read_end = reader->tail + cnt;
214
+ reader->read_end = reader->tail + cnt;
221
215
  }
222
216
  return 0;
223
217
  }
data/ext/oj/reader.h CHANGED
@@ -1,92 +1,84 @@
1
- /* reader.h
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #ifndef OJ_READER_H
5
+ #define OJ_READER_H
5
6
 
6
- #ifndef __OJ_READER_H__
7
- #define __OJ_READER_H__
8
-
9
- typedef struct _Reader {
10
- char base[0x00001000];
11
- char *head;
12
- char *end;
13
- char *tail;
14
- char *read_end; /* one past last character read */
15
- char *pro; /* protection start, buffer can not slide past this point */
16
- char *str; /* start of current string being read */
17
- long pos;
18
- int line;
19
- int col;
20
- int free_head;
21
- int (*read_func)(struct _Reader *reader);
7
+ typedef struct _reader {
8
+ char base[0x00001000];
9
+ char *head;
10
+ char *end;
11
+ char *tail;
12
+ char *read_end; /* one past last character read */
13
+ char *pro; /* protection start, buffer can not slide past this point */
14
+ char *str; /* start of current string being read */
15
+ long pos;
16
+ int line;
17
+ int col;
18
+ int free_head;
19
+ int (*read_func)(struct _reader *reader);
22
20
  union {
23
- int fd;
24
- VALUE io;
25
- const char *in_str;
21
+ int fd;
22
+ VALUE io;
23
+ const char *in_str;
26
24
  };
27
- } *Reader;
25
+ } * Reader;
28
26
 
29
- extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
30
- extern int oj_reader_read(Reader reader);
27
+ extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
28
+ extern int oj_reader_read(Reader reader);
31
29
 
32
- static inline char
33
- reader_get(Reader reader) {
34
- //printf("*** drive get from '%s' from start: %ld buf: %p from read_end: %ld\n", reader->tail, reader->tail - reader->head, reader->head, reader->read_end - reader->tail);
30
+ static inline char reader_get(Reader reader) {
31
+ // printf("*** drive get from '%s' from start: %ld buf: %p from read_end: %ld\n",
32
+ // reader->tail, reader->tail - reader->head, reader->head, reader->read_end - reader->tail);
35
33
  if (reader->read_end <= reader->tail) {
36
- if (0 != oj_reader_read(reader)) {
37
- return '\0';
38
- }
34
+ if (0 != oj_reader_read(reader)) {
35
+ return '\0';
36
+ }
39
37
  }
40
38
  if ('\n' == *reader->tail) {
41
- reader->line++;
42
- reader->col = 0;
39
+ reader->line++;
40
+ reader->col = 0;
43
41
  }
44
42
  reader->col++;
45
43
  reader->pos++;
46
-
44
+
47
45
  return *reader->tail++;
48
46
  }
49
47
 
50
- static inline void
51
- reader_backup(Reader reader) {
48
+ static inline void reader_backup(Reader reader) {
52
49
  reader->tail--;
53
50
  reader->col--;
54
51
  reader->pos--;
55
52
  if (0 >= reader->col) {
56
- reader->line--;
57
- // allow col to be negative since we never backup twice in a row
53
+ reader->line--;
54
+ // allow col to be negative since we never backup twice in a row
58
55
  }
59
56
  }
60
57
 
61
- static inline void
62
- reader_protect(Reader reader) {
58
+ static inline void reader_protect(Reader reader) {
63
59
  reader->pro = reader->tail;
64
- reader->str = reader->tail; // can't have str before pro
60
+ reader->str = reader->tail; // can't have str before pro
65
61
  }
66
62
 
67
- static inline void
68
- reader_release(Reader reader) {
63
+ static inline void reader_release(Reader reader) {
69
64
  reader->pro = 0;
70
65
  }
71
66
 
72
67
  /* Starts by reading a character so it is safe to use with an empty or
73
68
  * compacted buffer.
74
69
  */
75
- static inline char
76
- reader_next_non_white(Reader reader) {
77
- char c;
70
+ static inline char reader_next_non_white(Reader reader) {
71
+ char c;
78
72
 
79
73
  while ('\0' != (c = reader_get(reader))) {
80
- switch(c) {
81
- case ' ':
82
- case '\t':
83
- case '\f':
84
- case '\n':
85
- case '\r':
86
- break;
87
- default:
88
- return c;
89
- }
74
+ switch (c) {
75
+ case ' ':
76
+ case '\t':
77
+ case '\f':
78
+ case '\n':
79
+ case '\r': break;
80
+ default: return c;
81
+ }
90
82
  }
91
83
  return '\0';
92
84
  }
@@ -94,58 +86,50 @@ reader_next_non_white(Reader reader) {
94
86
  /* Starts by reading a character so it is safe to use with an empty or
95
87
  * compacted buffer.
96
88
  */
97
- static inline char
98
- reader_next_white(Reader reader) {
99
- char c;
89
+ static inline char reader_next_white(Reader reader) {
90
+ char c;
100
91
 
101
92
  while ('\0' != (c = reader_get(reader))) {
102
- switch(c) {
103
- case ' ':
104
- case '\t':
105
- case '\f':
106
- case '\n':
107
- case '\r':
108
- case '\0':
109
- return c;
110
- default:
111
- break;
112
- }
93
+ switch (c) {
94
+ case ' ':
95
+ case '\t':
96
+ case '\f':
97
+ case '\n':
98
+ case '\r':
99
+ case '\0': return c;
100
+ default: break;
101
+ }
113
102
  }
114
103
  return '\0';
115
104
  }
116
105
 
117
- static inline int
118
- reader_expect(Reader reader, const char *s) {
106
+ static inline int reader_expect(Reader reader, const char *s) {
119
107
  for (; '\0' != *s; s++) {
120
- if (reader_get(reader) != *s) {
121
- return -1;
122
- }
108
+ if (reader_get(reader) != *s) {
109
+ return -1;
110
+ }
123
111
  }
124
112
  return 0;
125
113
  }
126
114
 
127
- static inline void
128
- reader_cleanup(Reader reader) {
115
+ static inline void reader_cleanup(Reader reader) {
129
116
  if (reader->free_head && 0 != reader->head) {
130
- xfree((char*)reader->head);
131
- reader->head = 0;
132
- reader->free_head = 0;
117
+ xfree((char *)reader->head);
118
+ reader->head = 0;
119
+ reader->free_head = 0;
133
120
  }
134
121
  }
135
122
 
136
- static inline int
137
- is_white(char c) {
138
- switch(c) {
123
+ static inline int is_white(char c) {
124
+ switch (c) {
139
125
  case ' ':
140
126
  case '\t':
141
127
  case '\f':
142
128
  case '\n':
143
- case '\r':
144
- return 1;
145
- default:
146
- break;
129
+ case '\r': return 1;
130
+ default: break;
147
131
  }
148
132
  return 0;
149
133
  }
150
134
 
151
- #endif /* __OJ_READER_H__ */
135
+ #endif /* OJ_READER_H */