oj 3.16.1 → 3.16.4

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.
data/ext/oj/parser.c CHANGED
@@ -1114,9 +1114,6 @@ static void parse(ojParser p, const byte *json) {
1114
1114
  p->map = trail_map;
1115
1115
  }
1116
1116
  }
1117
- if (0 < p->depth) {
1118
- parse_error(p, "parse error, not closed");
1119
- }
1120
1117
  if (0 == p->depth) {
1121
1118
  switch (p->map[256]) {
1122
1119
  case '0':
@@ -1164,6 +1161,17 @@ static void parser_mark(void *ptr) {
1164
1161
  }
1165
1162
  }
1166
1163
 
1164
+ static const rb_data_type_t oj_parser_type = {
1165
+ "Oj/parser",
1166
+ {
1167
+ parser_mark,
1168
+ parser_free,
1169
+ NULL,
1170
+ },
1171
+ 0,
1172
+ 0,
1173
+ };
1174
+
1167
1175
  extern void oj_set_parser_validator(ojParser p);
1168
1176
  extern void oj_set_parser_saj(ojParser p);
1169
1177
  extern void oj_set_parser_usual(ojParser p);
@@ -1255,7 +1263,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
1255
1263
  rb_hash_foreach(ropts, opt_cb, (VALUE)p);
1256
1264
  }
1257
1265
  }
1258
- return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1266
+ return TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
1259
1267
  }
1260
1268
 
1261
1269
  // Create a new parser without setting the delegate. The parser is
@@ -1275,7 +1283,7 @@ VALUE oj_parser_new(void) {
1275
1283
  buf_init(&p->buf);
1276
1284
  p->map = value_map;
1277
1285
 
1278
- return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1286
+ return TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
1279
1287
  }
1280
1288
 
1281
1289
  // Set set the options from a hash (ropts).
@@ -1294,53 +1302,41 @@ void oj_parser_set_option(ojParser p, VALUE ropts) {
1294
1302
  * - no options
1295
1303
  *
1296
1304
  * - *:saj*
1297
- * - _cache_keys=_ sets the value of the _cache_keys_ flag.
1298
- * - _cache_keys_ returns the value of the _cache_keys_ flag.
1299
- * - _cache_strings=_ sets the value of the _cache_strings_ to an positive integer less than 35. Strings shorter than
1300
- * that length are cached.
1301
- * - _cache_strings_ returns the value of the _cache_strings_ integer value.
1302
- * - _handler=_ sets the SAJ handler
1303
- * - _handler_ returns the SAJ handler
1305
+ * - _cache_keys_ is a flag indicating hash keys should be cached.
1306
+ * - _cache_strings_ is a positive integer less than 35. Strings shorter than that length are cached.
1307
+ * - _handler_ is the SAJ handler
1304
1308
  *
1305
1309
  * - *:usual*
1306
- * - _cache_keys=_ sets the value of the _cache_keys_ flag.
1307
- * - _cache_keys_ returns the value of the _cache_keys_ flag.
1308
- * - _cache_strings=_ sets the value of the _cache_strings_ to a positive integer less than 35. Strings shorter than
1309
- * that length are cached.
1310
- * - _cache_strings_ returns the value of the _cache_strings_ integer value.
1311
- * - _cache_expunge=_ sets the value of the _cache_expunge_ where 0 never expunges, 1 expunges slowly, 2 expunges
1312
- * faster, and 3 or higher expunges agressively.
1313
- * - _cache_expunge_ returns the value of the _cache_expunge_ integer value.
1314
- * - _capacity=_ sets the capacity of the parser. The parser grows automatically but can be updated directly with this
1315
- * call.
1316
- * - _capacity_ returns the current capacity of the parser's internal stack.
1317
- * - _create_id_ returns the value _create_id_ or _nil_ if there is no _create_id_.
1318
- * - _create_id=_ sets the value _create_id_ or if _nil_ unsets it. Parsed JSON objects that include the specified
1319
- * element use the element value as the name of the class to create an object from instead of a Hash.
1320
- * - _decimal=_ sets the approach to how decimals are parser. If _:auto_ then the decimals with significant digits are
1321
- * 16 or less are Floats and long ones are BigDecimal. _:ruby_ uses a call to Ruby to convert a string to a Float.
1322
- * _:float_ always generates a Float. _:bigdecimal_ always results in a BigDecimal.
1323
- * - _decimal_ returns the value of the decimal conversion option which can be :auto (default), :ruby, :float, or
1324
- * :bigdecimal.
1325
- * - _ignore_json_create_ returns the value of the _ignore_json_create_ flag.
1326
- * - _ignore_json_create=_ sets the value of the _ignore_json_create_ flag. When set the class json_create method is
1327
- * ignored on parsing in favor of creating an instance and populating directly.
1328
- * - _missing_class_ return the value of the _missing_class_ indicator.
1329
- * - _missing_class=_ sets the value of the _missing_class_ flag. Valid values are _:auto_ which creates any missing
1330
- * classes on parse, :ignore which ignores and continues as a Hash (default), and :raise which raises an exception if
1331
- * the class is not found.
1332
- * - _omit_null=_ sets the _omit_null_ flag. If true then null values in a map or object are omitted from the
1333
- * resulting Hash or Object.
1334
- * - _omit_null_ returns the value of the _omit_null_ flag.
1335
- * - _symbol_keys=_ sets the flag that indicates Hash keys should be parsed to Symbols versus Strings.
1336
- * - _symbol_keys_ returns the value of the _symbol_keys_ flag.
1310
+ * - _cache_keys_ is a flag indicating hash keys should be cached.
1311
+ * - _cache_strings_ is a positive integer less than 35. Strings shorter than that length are cached.
1312
+ * - _cache_expunge_ dictates when the cache will be expunged where 0 never expunges,
1313
+ * 1 expunges slowly, 2 expunges faster, and 3 or higher expunges agressively.
1314
+ * - _capacity_ is the capacity of the parser's internal stack. The parser grows automatically
1315
+ * but can be updated directly with this call.
1316
+ * - _create_id_ if non-nil is the key that is used to specify the type of object to create
1317
+ * when parsing. Parsed JSON objects that include the specified element use the element
1318
+ * value as the name of the class to create an object from instead of a Hash.
1319
+ * - _decimal_ is the approach to how decimals are parsed. If _:auto_ then
1320
+ * the decimals with significant digits are 16 or less are Floats and long
1321
+ * ones are BigDecimal. _:ruby_ uses a call to Ruby to convert a string to a Float.
1322
+ * _:float_ always generates a Float. _:bigdecimal_ always results in a BigDecimal.
1323
+ * - _ignore_json_create_ is a flag that when set the class json_create method is
1324
+ * ignored on parsing in favor of creating an instance and populating directly.
1325
+ * - _missing_class_ is an indicator that determines how unknown class names are handled.
1326
+ * Valid values are _:auto_ which creates any missing classes on parse, :ignore which ignores
1327
+ * and continues as a Hash (default), and :raise which raises an exception if the class is not found.
1328
+ * - _omit_null_ is a flag that if true then null values in a map or object are omitted
1329
+ * from the resulting Hash or Object.
1330
+ * - _symbol_keys_ is a flag that indicates Hash keys should be parsed to Symbols versus Strings.
1337
1331
  */
1338
1332
  static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
1339
- ojParser p = (ojParser)DATA_PTR(self);
1333
+ ojParser p;
1340
1334
  const char *key = NULL;
1341
1335
  volatile VALUE rkey = *argv;
1342
1336
  volatile VALUE rv = Qnil;
1343
1337
 
1338
+ TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1339
+
1344
1340
  #if HAVE_RB_EXT_RACTOR_SAFE
1345
1341
  // This doesn't seem to do anything.
1346
1342
  rb_ext_ractor_safe(true);
@@ -1366,9 +1362,11 @@ static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
1366
1362
  * Returns the result according to the delegate of the parser.
1367
1363
  */
1368
1364
  static VALUE parser_parse(VALUE self, VALUE json) {
1369
- ojParser p = (ojParser)DATA_PTR(self);
1365
+ ojParser p;
1370
1366
  const byte *ptr = (const byte *)StringValuePtr(json);
1371
1367
 
1368
+ TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1369
+
1372
1370
  parser_reset(p);
1373
1371
  p->start(p);
1374
1372
  parse(p, ptr);
@@ -1382,15 +1380,23 @@ static VALUE load_rescue(VALUE self, VALUE x) {
1382
1380
  }
1383
1381
 
1384
1382
  static VALUE load(VALUE self) {
1385
- ojParser p = (ojParser)DATA_PTR(self);
1383
+ ojParser p;
1386
1384
  volatile VALUE rbuf = rb_str_new2("");
1387
1385
 
1386
+ TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1387
+
1388
1388
  p->start(p);
1389
1389
  while (true) {
1390
1390
  rb_funcall(p->reader, oj_readpartial_id, 2, INT2NUM(16385), rbuf);
1391
1391
  if (0 < RSTRING_LEN(rbuf)) {
1392
1392
  parse(p, (byte *)StringValuePtr(rbuf));
1393
1393
  }
1394
+ if (Qtrue == rb_funcall(p->reader, oj_eofq_id, 0)) {
1395
+ if (0 < p->depth) {
1396
+ parse_error(p, "parse error, not closed");
1397
+ }
1398
+ break;
1399
+ }
1394
1400
  }
1395
1401
  return Qtrue;
1396
1402
  }
@@ -1403,7 +1409,9 @@ static VALUE load(VALUE self) {
1403
1409
  * Returns the result according to the delegate of the parser.
1404
1410
  */
1405
1411
  static VALUE parser_load(VALUE self, VALUE reader) {
1406
- ojParser p = (ojParser)DATA_PTR(self);
1412
+ ojParser p;
1413
+
1414
+ TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1407
1415
 
1408
1416
  parser_reset(p);
1409
1417
  p->reader = reader;
@@ -1420,10 +1428,12 @@ static VALUE parser_load(VALUE self, VALUE reader) {
1420
1428
  * Returns the result according to the delegate of the parser.
1421
1429
  */
1422
1430
  static VALUE parser_file(VALUE self, VALUE filename) {
1423
- ojParser p = (ojParser)DATA_PTR(self);
1431
+ ojParser p;
1424
1432
  const char *path;
1425
1433
  int fd;
1426
1434
 
1435
+ TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1436
+
1427
1437
  path = StringValuePtr(filename);
1428
1438
 
1429
1439
  parser_reset(p);
@@ -1467,7 +1477,9 @@ static VALUE parser_file(VALUE self, VALUE filename) {
1467
1477
  * Returns the current state of the just_one [_Boolean_] option.
1468
1478
  */
1469
1479
  static VALUE parser_just_one(VALUE self) {
1470
- ojParser p = (ojParser)DATA_PTR(self);
1480
+ ojParser p;
1481
+
1482
+ TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1471
1483
 
1472
1484
  return p->just_one ? Qtrue : Qfalse;
1473
1485
  }
@@ -1481,7 +1493,9 @@ static VALUE parser_just_one(VALUE self) {
1481
1493
  * Returns the current state of the just_one [_Boolean_] option.
1482
1494
  */
1483
1495
  static VALUE parser_just_one_set(VALUE self, VALUE v) {
1484
- ojParser p = (ojParser)DATA_PTR(self);
1496
+ ojParser p;
1497
+
1498
+ TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1485
1499
 
1486
1500
  p->just_one = (Qtrue == v);
1487
1501
 
@@ -1505,7 +1519,7 @@ static VALUE parser_usual(VALUE self) {
1505
1519
  buf_init(&p->buf);
1506
1520
  p->map = value_map;
1507
1521
  oj_set_parser_usual(p);
1508
- usual_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1522
+ usual_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
1509
1523
  rb_gc_register_address(&usual_parser);
1510
1524
  }
1511
1525
  return usual_parser;
@@ -1528,7 +1542,7 @@ static VALUE parser_saj(VALUE self) {
1528
1542
  buf_init(&p->buf);
1529
1543
  p->map = value_map;
1530
1544
  oj_set_parser_saj(p);
1531
- saj_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1545
+ saj_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
1532
1546
  rb_gc_register_address(&saj_parser);
1533
1547
  }
1534
1548
  return saj_parser;
@@ -1550,7 +1564,7 @@ static VALUE parser_validate(VALUE self) {
1550
1564
  buf_init(&p->buf);
1551
1565
  p->map = value_map;
1552
1566
  oj_set_parser_validator(p);
1553
- validate_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
1567
+ validate_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
1554
1568
  rb_gc_register_address(&validate_parser);
1555
1569
  }
1556
1570
  return validate_parser;
data/ext/oj/parser.h CHANGED
@@ -32,9 +32,9 @@ typedef struct _num {
32
32
  long double dub;
33
33
  int64_t fixnum; // holds all digits
34
34
  uint32_t len;
35
- int16_t div; // 10^div
35
+ int16_t div; // 10^div
36
36
  int16_t exp;
37
- uint8_t shift; // shift of fixnum to get decimal
37
+ uint8_t shift; // shift of fixnum to get decimal
38
38
  bool neg;
39
39
  bool exp_neg;
40
40
  // for numbers as strings, reuse buf
data/ext/oj/rails.c CHANGED
@@ -639,6 +639,17 @@ static void encoder_mark(void *ptr) {
639
639
  }
640
640
  }
641
641
 
642
+ static const rb_data_type_t oj_encoder_type = {
643
+ "Oj/encoder",
644
+ {
645
+ encoder_mark,
646
+ encoder_free,
647
+ NULL,
648
+ },
649
+ 0,
650
+ 0,
651
+ };
652
+
642
653
  /* Document-method: new
643
654
  * call-seq: new(options=nil)
644
655
  *
@@ -656,7 +667,7 @@ static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
656
667
  oj_parse_options(*argv, &e->opts);
657
668
  e->arg = *argv;
658
669
  }
659
- return Data_Wrap_Struct(encoder_class, encoder_mark, encoder_free, e);
670
+ return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e);
660
671
  }
661
672
 
662
673
  static VALUE resolve_classpath(const char *name) {
@@ -748,7 +759,8 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
748
759
  * - *classes* [_Class_] a list of classes to optimize
749
760
  */
750
761
  static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) {
751
- Encoder e = (Encoder)DATA_PTR(self);
762
+ Encoder e;
763
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
752
764
 
753
765
  optimize(argc, argv, &e->ropts, true);
754
766
 
@@ -804,7 +816,8 @@ rails_mimic_json(VALUE self) {
804
816
  * - *classes* [_Class_] a list of classes to deoptimize
805
817
  */
806
818
  static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
807
- Encoder e = (Encoder)DATA_PTR(self);
819
+ Encoder e;
820
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
808
821
 
809
822
  optimize(argc, argv, &e->ropts, false);
810
823
 
@@ -833,8 +846,11 @@ static VALUE rails_deoptimize(int argc, VALUE *argv, VALUE self) {
833
846
  * @return true if the class is being optimized for rails and false otherwise
834
847
  */
835
848
  static VALUE encoder_optimized(VALUE self, VALUE clas) {
836
- Encoder e = (Encoder)DATA_PTR(self);
837
- ROpt ro = oj_rails_get_opt(&e->ropts, clas);
849
+ Encoder e;
850
+ ROpt ro;
851
+
852
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
853
+ ro = oj_rails_get_opt(&e->ropts, clas);
838
854
 
839
855
  if (NULL == ro) {
840
856
  return Qfalse;
@@ -940,7 +956,8 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
940
956
  * Returns encoded object as a JSON string.
941
957
  */
942
958
  static VALUE encoder_encode(VALUE self, VALUE obj) {
943
- Encoder e = (Encoder)DATA_PTR(self);
959
+ Encoder e;
960
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
944
961
 
945
962
  if (Qnil != e->arg) {
946
963
  VALUE argv[1] = {e->arg};
data/ext/oj/reader.c CHANGED
@@ -101,7 +101,7 @@ int oj_reader_read(Reader reader) {
101
101
  } else {
102
102
  shift = reader->pro - reader->head - 1; // leave one character so we can backup one
103
103
  }
104
- if (0 >= shift) { /* no space left so allocate more */
104
+ if (0 >= shift) { /* no space left so allocate more */
105
105
  const char *old = reader->head;
106
106
  size_t size = reader->end - reader->head + BUF_PAD;
107
107
 
data/ext/oj/saj.c CHANGED
@@ -578,7 +578,7 @@ static void saj_parse(VALUE handler, char *json) {
578
578
  /* initialize parse info */
579
579
  pi.str = json;
580
580
  pi.s = json;
581
- #if IS_WINDOWS
581
+ #if IS_WINDOWS || !defined(HAVE_GETRLIMIT)
582
582
  pi.stack_min = (void *)((char *)&obj - (512L * 1024L)); /* assume a 1M stack and give half to ruby */
583
583
  #else
584
584
  {
@@ -587,7 +587,7 @@ static void saj_parse(VALUE handler, char *json) {
587
587
  if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
588
588
  pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
589
589
  } else {
590
- pi.stack_min = 0; /* indicates not to check stack limit */
590
+ pi.stack_min = 0; /* indicates not to check stack limit */
591
591
  }
592
592
  }
593
593
  #endif
@@ -21,6 +21,17 @@ static void stream_writer_free(void *ptr) {
21
21
  OJ_R_FREE(ptr);
22
22
  }
23
23
 
24
+ static const rb_data_type_t oj_stream_writer_type = {
25
+ "Oj/stream_writer",
26
+ {
27
+ NULL,
28
+ stream_writer_free,
29
+ NULL,
30
+ },
31
+ 0,
32
+ 0,
33
+ };
34
+
24
35
  static void stream_writer_reset_buf(StreamWriter sw) {
25
36
  sw->sw.out.cur = sw->sw.out.buf;
26
37
  *sw->sw.out.cur = '\0';
@@ -120,7 +131,7 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
120
131
  sw->type = type;
121
132
  sw->fd = fd;
122
133
 
123
- return Data_Wrap_Struct(oj_stream_writer_class, 0, stream_writer_free, sw);
134
+ return TypedData_Wrap_Struct(oj_stream_writer_class, &oj_stream_writer_type, sw);
124
135
  }
125
136
 
126
137
  /* Document-method: push_key
@@ -133,7 +144,8 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
133
144
  * - *key* [_String_] the key pending for the next push
134
145
  */
135
146
  static VALUE stream_writer_push_key(VALUE self, VALUE key) {
136
- StreamWriter sw = (StreamWriter)DATA_PTR(self);
147
+ StreamWriter sw;
148
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
137
149
 
138
150
  oj_str_writer_push_key(&sw->sw, StringValuePtr(key));
139
151
  if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
@@ -151,7 +163,8 @@ static VALUE stream_writer_push_key(VALUE self, VALUE key) {
151
163
  * - *key* [_String_] the key if adding to an object in the JSON document
152
164
  */
153
165
  static VALUE stream_writer_push_object(int argc, VALUE *argv, VALUE self) {
154
- StreamWriter sw = (StreamWriter)DATA_PTR(self);
166
+ StreamWriter sw;
167
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
155
168
 
156
169
  switch (argc) {
157
170
  case 0: oj_str_writer_push_object(&sw->sw, 0); break;
@@ -179,7 +192,8 @@ static VALUE stream_writer_push_object(int argc, VALUE *argv, VALUE self) {
179
192
  * - *key* [_String_] the key if adding to an object in the JSON document
180
193
  */
181
194
  static VALUE stream_writer_push_array(int argc, VALUE *argv, VALUE self) {
182
- StreamWriter sw = (StreamWriter)DATA_PTR(self);
195
+ StreamWriter sw;
196
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
183
197
 
184
198
  switch (argc) {
185
199
  case 0: oj_str_writer_push_array(&sw->sw, 0); break;
@@ -206,15 +220,16 @@ static VALUE stream_writer_push_array(int argc, VALUE *argv, VALUE self) {
206
220
  * - *key* [_String_] the key if adding to an object in the JSON document
207
221
  */
208
222
  static VALUE stream_writer_push_value(int argc, VALUE *argv, VALUE self) {
209
- StreamWriter sw = (StreamWriter)DATA_PTR(self);
223
+ StreamWriter sw;
224
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
210
225
 
211
226
  switch (argc) {
212
- case 1: oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); break;
227
+ case 1: oj_str_writer_push_value((StrWriter)sw, *argv, 0); break;
213
228
  case 2:
214
229
  if (Qnil == argv[1]) {
215
- oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
230
+ oj_str_writer_push_value((StrWriter)sw, *argv, 0);
216
231
  } else {
217
- oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
232
+ oj_str_writer_push_value((StrWriter)sw, *argv, StringValuePtr(argv[1]));
218
233
  }
219
234
  break;
220
235
  default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'."); break;
@@ -235,15 +250,16 @@ static VALUE stream_writer_push_value(int argc, VALUE *argv, VALUE self) {
235
250
  * - *key* [_String_] the key if adding to an object in the JSON document
236
251
  */
237
252
  static VALUE stream_writer_push_json(int argc, VALUE *argv, VALUE self) {
238
- StreamWriter sw = (StreamWriter)DATA_PTR(self);
253
+ StreamWriter sw;
254
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
239
255
 
240
256
  switch (argc) {
241
- case 1: oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); break;
257
+ case 1: oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), 0); break;
242
258
  case 2:
243
259
  if (Qnil == argv[1]) {
244
- oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
260
+ oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), 0);
245
261
  } else {
246
- oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), StringValuePtr(argv[1]));
262
+ oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), StringValuePtr(argv[1]));
247
263
  }
248
264
  break;
249
265
  default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
@@ -261,7 +277,8 @@ static VALUE stream_writer_push_json(int argc, VALUE *argv, VALUE self) {
261
277
  * currently open.
262
278
  */
263
279
  static VALUE stream_writer_pop(VALUE self) {
264
- StreamWriter sw = (StreamWriter)DATA_PTR(self);
280
+ StreamWriter sw;
281
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
265
282
 
266
283
  oj_str_writer_pop(&sw->sw);
267
284
  if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
@@ -277,7 +294,8 @@ static VALUE stream_writer_pop(VALUE self) {
277
294
  * currently open.
278
295
  */
279
296
  static VALUE stream_writer_pop_all(VALUE self) {
280
- StreamWriter sw = (StreamWriter)DATA_PTR(self);
297
+ StreamWriter sw;
298
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
281
299
 
282
300
  oj_str_writer_pop_all(&sw->sw);
283
301
  stream_writer_write(sw);
@@ -291,7 +309,9 @@ static VALUE stream_writer_pop_all(VALUE self) {
291
309
  * Flush any remaining characters in the buffer.
292
310
  */
293
311
  static VALUE stream_writer_flush(VALUE self) {
294
- stream_writer_write((StreamWriter)DATA_PTR(self));
312
+ StreamWriter sw;
313
+ TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
314
+ stream_writer_write(sw);
295
315
 
296
316
  return Qnil;
297
317
  }
@@ -225,7 +225,7 @@ void oj_str_writer_pop_all(StrWriter sw) {
225
225
  }
226
226
  }
227
227
 
228
- static void str_writer_free(void *ptr) {
228
+ static void string_writer_free(void *ptr) {
229
229
  StrWriter sw;
230
230
 
231
231
  if (0 == ptr) {
@@ -239,6 +239,23 @@ static void str_writer_free(void *ptr) {
239
239
  OJ_R_FREE(ptr);
240
240
  }
241
241
 
242
+ static const rb_data_type_t oj_string_writer_type = {
243
+ "Oj/string_writer",
244
+ {
245
+ NULL,
246
+ string_writer_free,
247
+ NULL,
248
+ },
249
+ 0,
250
+ 0,
251
+ };
252
+
253
+ StrWriter oj_str_writer_unwrap(VALUE writer) {
254
+ StrWriter sw;
255
+ TypedData_Get_Struct(writer, struct _strWriter, &oj_string_writer_type, sw);
256
+ return sw;
257
+ }
258
+
242
259
  /* Document-method: new
243
260
  * call-seq: new(io, options)
244
261
  *
@@ -266,7 +283,7 @@ static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
266
283
  sw->out.argv = argv + 1;
267
284
  sw->out.indent = sw->opts.indent;
268
285
 
269
- return Data_Wrap_Struct(oj_string_writer_class, 0, str_writer_free, sw);
286
+ return TypedData_Wrap_Struct(oj_string_writer_class, &oj_string_writer_type, sw);
270
287
  }
271
288
 
272
289
  /* Document-method: push_key
@@ -278,7 +295,8 @@ static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
278
295
  * - *key* [_String_] the key pending for the next push
279
296
  */
280
297
  static VALUE str_writer_push_key(VALUE self, VALUE key) {
281
- StrWriter sw = (StrWriter)DATA_PTR(self);
298
+ StrWriter sw;
299
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
282
300
 
283
301
  oj_str_writer_push_key(sw, StringValuePtr(key));
284
302
 
@@ -293,7 +311,8 @@ static VALUE str_writer_push_key(VALUE self, VALUE key) {
293
311
  * - *key* [_String_] the key if adding to an object in the JSON document
294
312
  */
295
313
  static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
296
- StrWriter sw = (StrWriter)DATA_PTR(self);
314
+ StrWriter sw;
315
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
297
316
 
298
317
  switch (argc) {
299
318
  case 0: oj_str_writer_push_object(sw, 0); break;
@@ -321,7 +340,8 @@ static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
321
340
  * - *key* [_String_] the key if adding to an object in the JSON document
322
341
  */
323
342
  static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
324
- StrWriter sw = (StrWriter)DATA_PTR(self);
343
+ StrWriter sw;
344
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
325
345
 
326
346
  switch (argc) {
327
347
  case 0: oj_str_writer_push_array(sw, 0); break;
@@ -349,13 +369,16 @@ static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
349
369
  * - *key* [_String_] the key if adding to an object in the JSON document
350
370
  */
351
371
  static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) {
372
+ StrWriter sw;
373
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
374
+
352
375
  switch (argc) {
353
- case 1: oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); break;
376
+ case 1: oj_str_writer_push_value(sw, *argv, 0); break;
354
377
  case 2:
355
378
  if (Qnil == argv[1]) {
356
- oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
379
+ oj_str_writer_push_value(sw, *argv, 0);
357
380
  } else {
358
- oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
381
+ oj_str_writer_push_value(sw, *argv, StringValuePtr(argv[1]));
359
382
  }
360
383
  break;
361
384
  default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'."); break;
@@ -373,13 +396,16 @@ static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) {
373
396
  * - *key* [_String_] the key if adding to an object in the JSON document
374
397
  */
375
398
  static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) {
399
+ StrWriter sw;
400
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
401
+
376
402
  switch (argc) {
377
- case 1: oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); break;
403
+ case 1: oj_str_writer_push_json(sw, StringValuePtr(*argv), 0); break;
378
404
  case 2:
379
405
  if (Qnil == argv[1]) {
380
- oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
406
+ oj_str_writer_push_json(sw, StringValuePtr(*argv), 0);
381
407
  } else {
382
- oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), StringValuePtr(argv[1]));
408
+ oj_str_writer_push_json(sw, StringValuePtr(*argv), StringValuePtr(argv[1]));
383
409
  }
384
410
  break;
385
411
  default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
@@ -393,7 +419,10 @@ static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) {
393
419
  * currently open.
394
420
  */
395
421
  static VALUE str_writer_pop(VALUE self) {
396
- oj_str_writer_pop((StrWriter)DATA_PTR(self));
422
+ StrWriter sw;
423
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
424
+
425
+ oj_str_writer_pop(sw);
397
426
  return Qnil;
398
427
  }
399
428
 
@@ -404,7 +433,10 @@ static VALUE str_writer_pop(VALUE self) {
404
433
  * currently open.
405
434
  */
406
435
  static VALUE str_writer_pop_all(VALUE self) {
407
- oj_str_writer_pop_all((StrWriter)DATA_PTR(self));
436
+ StrWriter sw;
437
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
438
+
439
+ oj_str_writer_pop_all(sw);
408
440
 
409
441
  return Qnil;
410
442
  }
@@ -415,7 +447,8 @@ static VALUE str_writer_pop_all(VALUE self) {
415
447
  * Reset the writer back to the empty state.
416
448
  */
417
449
  static VALUE str_writer_reset(VALUE self) {
418
- StrWriter sw = (StrWriter)DATA_PTR(self);
450
+ StrWriter sw;
451
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
419
452
 
420
453
  sw->depth = 0;
421
454
  *sw->types = '\0';
@@ -434,8 +467,9 @@ static VALUE str_writer_reset(VALUE self) {
434
467
  * *return* [_String_]
435
468
  */
436
469
  static VALUE str_writer_to_s(VALUE self) {
437
- StrWriter sw = (StrWriter)DATA_PTR(self);
438
- VALUE rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf);
470
+ StrWriter sw;
471
+ TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
472
+ VALUE rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf);
439
473
 
440
474
  return oj_encode(rstr);
441
475
  }