diff --git a/ext/oj/cache.c b/ext/oj/cache.c index ddbbafd6..5669b676 100644 --- a/ext/oj/cache.c +++ b/ext/oj/cache.c @@ -260,7 +260,8 @@ void cache_set_expunge_rate(Cache c, int rate) { c->xrate = (uint8_t)rate; } -void cache_free(Cache c) { +void cache_free(void *data) { + Cache c = (Cache)data; uint64_t i; for (i = 0; i < c->size; i++) { @@ -276,7 +277,8 @@ void cache_free(Cache c) { OJ_FREE(c); } -void cache_mark(Cache c) { +void cache_mark(void *data) { + Cache c = (Cache)data; uint64_t i; #if !HAVE_PTHREAD_MUTEX_INIT diff --git a/ext/oj/cache.h b/ext/oj/cache.h index 84579a70..d372b69a 100644 --- a/ext/oj/cache.h +++ b/ext/oj/cache.h @@ -10,10 +10,11 @@ #define CACHE_MAX_KEY 35 struct _cache; +typedef struct _cache *Cache; extern struct _cache *cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking); -extern void cache_free(struct _cache *c); -extern void cache_mark(struct _cache *c); +extern void cache_free(void *data); +extern void cache_mark(void *data); extern void cache_set_form(struct _cache *c, VALUE (*form)(const char *str, size_t len)); extern VALUE cache_intern(struct _cache *c, const char *key, size_t len); extern void cache_set_expunge_rate(struct _cache *c, int rate); diff --git a/ext/oj/dump.c b/ext/oj/dump.c index 1a6d813d..1f5bfbe9 100644 --- a/ext/oj/dump.c +++ b/ext/oj/dump.c @@ -727,8 +727,11 @@ static void debug_raise(const char *orig, size_t cnt, int line) { void oj_dump_raw_json(VALUE obj, int depth, Out out) { if (oj_string_writer_class == rb_obj_class(obj)) { - StrWriter sw = (StrWriter)DATA_PTR(obj); - size_t len = sw->out.cur - sw->out.buf; + StrWriter sw; + size_t len; + + sw = oj_str_writer_unwrap(obj); + len = sw->out.cur - sw->out.buf; if (0 < len) { len--; diff --git a/ext/oj/fast.c b/ext/oj/fast.c index ee53716d..841e0d50 100644 --- a/ext/oj/fast.c +++ b/ext/oj/fast.c @@ -780,11 +780,10 @@ static VALUE parse_json(VALUE clas, char *json, bool given) { } } #endif - doc->json = json; - self = TypedData_Wrap_Struct(clas, &oj_doc_type, doc); - doc->self = self; - DATA_PTR(doc->self) = doc; - result = rb_protect(protect_open_proc, (VALUE)&pi, &ex); + doc->json = json; + self = TypedData_Wrap_Struct(clas, &oj_doc_type, doc); + doc->self = self; + result = rb_protect(protect_open_proc, (VALUE)&pi, &ex); if (given || 0 != ex) { DATA_PTR(doc->self) = NULL; // TBD is this needed? @@ -1609,7 +1608,9 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) { * Oj::Doc.open('[1,2,3]') { |doc| doc.size() } #=> 4 */ static VALUE doc_size(VALUE self) { - return ULONG2NUM(((Doc)DATA_PTR(self))->size); + Doc d; + TypedData_Get_Struct(self, struct _doc, &oj_doc_type, d); + return ULONG2NUM(d->size); } /* @overload close() => nil diff --git a/ext/oj/intern.c b/ext/oj/intern.c index 075bd1c3..ea12ebce 100644 --- a/ext/oj/intern.c +++ b/ext/oj/intern.c @@ -85,20 +85,31 @@ static VALUE form_attr(const char *str, size_t len) { return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding); } +static const rb_data_type_t oj_cache_type = { + "Oj/cache", + { + cache_mark, + cache_free, + NULL, + }, + 0, + 0, +}; + void oj_hash_init(void) { VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject); rb_undef_alloc_func(cache_class); struct _cache *str_cache = cache_create(0, form_str, true, true); - str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache); + str_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, str_cache); rb_gc_register_address(&str_cache_obj); struct _cache *sym_cache = cache_create(0, form_sym, true, true); - sym_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, sym_cache); + sym_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, sym_cache); rb_gc_register_address(&sym_cache_obj); struct _cache *attr_cache = cache_create(0, form_attr, false, true); - attr_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, attr_cache); + attr_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, attr_cache); rb_gc_register_address(&attr_cache_obj); memset(class_hash.slots, 0, sizeof(class_hash.slots)); @@ -118,17 +129,23 @@ oj_str_intern(const char *key, size_t len) { #if HAVE_RB_ENC_INTERNED_STR && 0 return rb_enc_interned_str(key, len, rb_utf8_encoding()); #else - return cache_intern(DATA_PTR(str_cache_obj), key, len); + Cache c; + TypedData_Get_Struct(str_cache_obj, struct _cache, &oj_cache_type, c); + return cache_intern(c, key, len); #endif } VALUE oj_sym_intern(const char *key, size_t len) { - return cache_intern(DATA_PTR(sym_cache_obj), key, len); + Cache c; + TypedData_Get_Struct(sym_cache_obj, struct _cache, &oj_cache_type, c); + return cache_intern(c, key, len); } ID oj_attr_intern(const char *key, size_t len) { - return cache_intern(DATA_PTR(attr_cache_obj), key, len); + Cache c; + TypedData_Get_Struct(attr_cache_obj, struct _cache, &oj_cache_type, c); + return cache_intern(c, key, len); } static uint64_t hash_calc(const uint8_t *key, size_t len) { diff --git a/ext/oj/oj.h b/ext/oj/oj.h index b7a9934f..2d9b96e2 100644 --- a/ext/oj/oj.h +++ b/ext/oj/oj.h @@ -262,6 +262,8 @@ extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out); extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts); extern char *oj_longlong_to_string(long long num, bool negative, char *buf); +extern StrWriter oj_str_writer_unwrap(VALUE writer); + extern void oj_str_writer_push_key(StrWriter sw, const char *key); extern void oj_str_writer_push_object(StrWriter sw, const char *key); extern void oj_str_writer_push_array(StrWriter sw, const char *key); diff --git a/ext/oj/parser.c b/ext/oj/parser.c index 02ce2151..2ad234a4 100644 --- a/ext/oj/parser.c +++ b/ext/oj/parser.c @@ -1164,6 +1164,17 @@ static void parser_mark(void *ptr) { } } +static const rb_data_type_t oj_parser_type = { + "Oj/parser", + { + parser_mark, + parser_free, + NULL, + }, + 0, + 0, +}; + extern void oj_set_parser_validator(ojParser p); extern void oj_set_parser_saj(ojParser p); extern void oj_set_parser_usual(ojParser p); @@ -1255,7 +1266,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) { rb_hash_foreach(ropts, opt_cb, (VALUE)p); } } - return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p); + return TypedData_Wrap_Struct(parser_class, &oj_parser_type, p); } // Create a new parser without setting the delegate. The parser is @@ -1275,7 +1286,7 @@ VALUE oj_parser_new(void) { buf_init(&p->buf); p->map = value_map; - return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p); + return TypedData_Wrap_Struct(parser_class, &oj_parser_type, p); } // Set set the options from a hash (ropts). @@ -1322,11 +1333,13 @@ void oj_parser_set_option(ojParser p, VALUE ropts) { * - _symbol_keys_ is a flag that indicates Hash keys should be parsed to Symbols versus Strings. */ static VALUE parser_missing(int argc, VALUE *argv, VALUE self) { - ojParser p = (ojParser)DATA_PTR(self); + ojParser p; const char *key = NULL; volatile VALUE rkey = *argv; volatile VALUE rv = Qnil; + TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p); + #if HAVE_RB_EXT_RACTOR_SAFE // This doesn't seem to do anything. rb_ext_ractor_safe(true); @@ -1352,9 +1365,11 @@ static VALUE parser_missing(int argc, VALUE *argv, VALUE self) { * Returns the result according to the delegate of the parser. */ static VALUE parser_parse(VALUE self, VALUE json) { - ojParser p = (ojParser)DATA_PTR(self); + ojParser p; const byte *ptr = (const byte *)StringValuePtr(json); + TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p); + parser_reset(p); p->start(p); parse(p, ptr); @@ -1368,9 +1383,11 @@ static VALUE load_rescue(VALUE self, VALUE x) { } static VALUE load(VALUE self) { - ojParser p = (ojParser)DATA_PTR(self); + ojParser p; volatile VALUE rbuf = rb_str_new2(""); + TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p); + p->start(p); while (true) { rb_funcall(p->reader, oj_readpartial_id, 2, INT2NUM(16385), rbuf); @@ -1389,7 +1406,9 @@ static VALUE load(VALUE self) { * Returns the result according to the delegate of the parser. */ static VALUE parser_load(VALUE self, VALUE reader) { - ojParser p = (ojParser)DATA_PTR(self); + ojParser p; + + TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p); parser_reset(p); p->reader = reader; @@ -1406,10 +1425,12 @@ static VALUE parser_load(VALUE self, VALUE reader) { * Returns the result according to the delegate of the parser. */ static VALUE parser_file(VALUE self, VALUE filename) { - ojParser p = (ojParser)DATA_PTR(self); + ojParser p; const char *path; int fd; + TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p); + path = StringValuePtr(filename); parser_reset(p); @@ -1453,7 +1474,9 @@ static VALUE parser_file(VALUE self, VALUE filename) { * Returns the current state of the just_one [_Boolean_] option. */ static VALUE parser_just_one(VALUE self) { - ojParser p = (ojParser)DATA_PTR(self); + ojParser p; + + TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p); return p->just_one ? Qtrue : Qfalse; } @@ -1467,7 +1490,9 @@ static VALUE parser_just_one(VALUE self) { * Returns the current state of the just_one [_Boolean_] option. */ static VALUE parser_just_one_set(VALUE self, VALUE v) { - ojParser p = (ojParser)DATA_PTR(self); + ojParser p; + + TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p); p->just_one = (Qtrue == v); @@ -1491,7 +1516,7 @@ static VALUE parser_usual(VALUE self) { buf_init(&p->buf); p->map = value_map; oj_set_parser_usual(p); - usual_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p); + usual_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p); rb_gc_register_address(&usual_parser); } return usual_parser; @@ -1514,7 +1539,7 @@ static VALUE parser_saj(VALUE self) { buf_init(&p->buf); p->map = value_map; oj_set_parser_saj(p); - saj_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p); + saj_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p); rb_gc_register_address(&saj_parser); } return saj_parser; @@ -1536,7 +1561,7 @@ static VALUE parser_validate(VALUE self) { buf_init(&p->buf); p->map = value_map; oj_set_parser_validator(p); - validate_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p); + validate_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p); rb_gc_register_address(&validate_parser); } return validate_parser; diff --git a/ext/oj/rails.c b/ext/oj/rails.c index fa48cc8b..91fed0db 100644 --- a/ext/oj/rails.c +++ b/ext/oj/rails.c @@ -639,6 +639,17 @@ static void encoder_mark(void *ptr) { } } +static const rb_data_type_t oj_encoder_type = { + "Oj/encoder", + { + encoder_mark, + encoder_free, + NULL, + }, + 0, + 0, +}; + /* Document-method: new * call-seq: new(options=nil) * @@ -656,7 +667,7 @@ static VALUE encoder_new(int argc, VALUE *argv, VALUE self) { oj_parse_options(*argv, &e->opts); e->arg = *argv; } - return Data_Wrap_Struct(encoder_class, encoder_mark, encoder_free, e); + return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e); } static VALUE resolve_classpath(const char *name) { @@ -748,7 +759,8 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) { * - *classes* [_Class_] a list of classes to optimize */ static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) { - Encoder e = (Encoder)DATA_PTR(self); + Encoder e; + TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e); optimize(argc, argv, &e->ropts, true); @@ -804,7 +816,8 @@ rails_mimic_json(VALUE self) { * - *classes* [_Class_] a list of classes to deoptimize */ static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) { - Encoder e = (Encoder)DATA_PTR(self); + Encoder e; + TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e); optimize(argc, argv, &e->ropts, false); @@ -833,8 +846,11 @@ static VALUE rails_deoptimize(int argc, VALUE *argv, VALUE self) { * @return true if the class is being optimized for rails and false otherwise */ static VALUE encoder_optimized(VALUE self, VALUE clas) { - Encoder e = (Encoder)DATA_PTR(self); - ROpt ro = oj_rails_get_opt(&e->ropts, clas); + Encoder e; + ROpt ro; + + TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e); + ro = oj_rails_get_opt(&e->ropts, clas); if (NULL == ro) { return Qfalse; @@ -940,7 +956,8 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a * Returns encoded object as a JSON string. */ static VALUE encoder_encode(VALUE self, VALUE obj) { - Encoder e = (Encoder)DATA_PTR(self); + Encoder e; + TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e); if (Qnil != e->arg) { VALUE argv[1] = {e->arg}; diff --git a/ext/oj/stream_writer.c b/ext/oj/stream_writer.c index decc705b..a1cff080 100644 --- a/ext/oj/stream_writer.c +++ b/ext/oj/stream_writer.c @@ -21,6 +21,17 @@ static void stream_writer_free(void *ptr) { OJ_R_FREE(ptr); } +static const rb_data_type_t oj_stream_writer_type = { + "Oj/stream_writer", + { + NULL, + stream_writer_free, + NULL, + }, + 0, + 0, +}; + static void stream_writer_reset_buf(StreamWriter sw) { sw->sw.out.cur = sw->sw.out.buf; *sw->sw.out.cur = '\0'; @@ -120,7 +131,7 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) { sw->type = type; sw->fd = fd; - return Data_Wrap_Struct(oj_stream_writer_class, 0, stream_writer_free, sw); + return TypedData_Wrap_Struct(oj_stream_writer_class, &oj_stream_writer_type, sw); } /* Document-method: push_key @@ -133,7 +144,8 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) { * - *key* [_String_] the key pending for the next push */ static VALUE stream_writer_push_key(VALUE self, VALUE key) { - StreamWriter sw = (StreamWriter)DATA_PTR(self); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); oj_str_writer_push_key(&sw->sw, StringValuePtr(key)); 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) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE stream_writer_push_object(int argc, VALUE *argv, VALUE self) { - StreamWriter sw = (StreamWriter)DATA_PTR(self); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); switch (argc) { 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) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE stream_writer_push_array(int argc, VALUE *argv, VALUE self) { - StreamWriter sw = (StreamWriter)DATA_PTR(self); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); switch (argc) { 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) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE stream_writer_push_value(int argc, VALUE *argv, VALUE self) { - StreamWriter sw = (StreamWriter)DATA_PTR(self); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); switch (argc) { - case 1: oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); break; + case 1: oj_str_writer_push_value((StrWriter)sw, *argv, 0); break; case 2: if (Qnil == argv[1]) { - oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); + oj_str_writer_push_value((StrWriter)sw, *argv, 0); } else { - oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1])); + oj_str_writer_push_value((StrWriter)sw, *argv, StringValuePtr(argv[1])); } break; 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) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE stream_writer_push_json(int argc, VALUE *argv, VALUE self) { - StreamWriter sw = (StreamWriter)DATA_PTR(self); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); switch (argc) { - case 1: oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); break; + case 1: oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), 0); break; case 2: if (Qnil == argv[1]) { - oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); + oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), 0); } else { - oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), StringValuePtr(argv[1])); + oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), StringValuePtr(argv[1])); } break; 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) { * currently open. */ static VALUE stream_writer_pop(VALUE self) { - StreamWriter sw = (StreamWriter)DATA_PTR(self); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); oj_str_writer_pop(&sw->sw); if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) { @@ -277,7 +294,8 @@ static VALUE stream_writer_pop(VALUE self) { * currently open. */ static VALUE stream_writer_pop_all(VALUE self) { - StreamWriter sw = (StreamWriter)DATA_PTR(self); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); oj_str_writer_pop_all(&sw->sw); stream_writer_write(sw); @@ -291,7 +309,9 @@ static VALUE stream_writer_pop_all(VALUE self) { * Flush any remaining characters in the buffer. */ static VALUE stream_writer_flush(VALUE self) { - stream_writer_write((StreamWriter)DATA_PTR(self)); + StreamWriter sw; + TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw); + stream_writer_write(sw); return Qnil; } diff --git a/ext/oj/string_writer.c b/ext/oj/string_writer.c index 6f979482..cb5ff102 100644 --- a/ext/oj/string_writer.c +++ b/ext/oj/string_writer.c @@ -225,7 +225,7 @@ void oj_str_writer_pop_all(StrWriter sw) { } } -static void str_writer_free(void *ptr) { +static void string_writer_free(void *ptr) { StrWriter sw; if (0 == ptr) { @@ -239,6 +239,23 @@ static void str_writer_free(void *ptr) { OJ_R_FREE(ptr); } +static const rb_data_type_t oj_string_writer_type = { + "Oj/string_writer", + { + NULL, + string_writer_free, + NULL, + }, + 0, + 0, +}; + +StrWriter oj_str_writer_unwrap(VALUE writer) { + StrWriter sw; + TypedData_Get_Struct(writer, struct _strWriter, &oj_string_writer_type, sw); + return sw; +} + /* Document-method: new * call-seq: new(io, options) * @@ -266,7 +283,7 @@ static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) { sw->out.argv = argv + 1; sw->out.indent = sw->opts.indent; - return Data_Wrap_Struct(oj_string_writer_class, 0, str_writer_free, sw); + return TypedData_Wrap_Struct(oj_string_writer_class, &oj_string_writer_type, sw); } /* Document-method: push_key @@ -278,7 +295,8 @@ static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) { * - *key* [_String_] the key pending for the next push */ static VALUE str_writer_push_key(VALUE self, VALUE key) { - StrWriter sw = (StrWriter)DATA_PTR(self); + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); oj_str_writer_push_key(sw, StringValuePtr(key)); @@ -293,7 +311,8 @@ static VALUE str_writer_push_key(VALUE self, VALUE key) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) { - StrWriter sw = (StrWriter)DATA_PTR(self); + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); switch (argc) { 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) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) { - StrWriter sw = (StrWriter)DATA_PTR(self); + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); switch (argc) { 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) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) { + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); + switch (argc) { - case 1: oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); break; + case 1: oj_str_writer_push_value(sw, *argv, 0); break; case 2: if (Qnil == argv[1]) { - oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0); + oj_str_writer_push_value(sw, *argv, 0); } else { - oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1])); + oj_str_writer_push_value(sw, *argv, StringValuePtr(argv[1])); } break; 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) { * - *key* [_String_] the key if adding to an object in the JSON document */ static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) { + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); + switch (argc) { - case 1: oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); break; + case 1: oj_str_writer_push_json(sw, StringValuePtr(*argv), 0); break; case 2: if (Qnil == argv[1]) { - oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); + oj_str_writer_push_json(sw, StringValuePtr(*argv), 0); } else { - oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), StringValuePtr(argv[1])); + oj_str_writer_push_json(sw, StringValuePtr(*argv), StringValuePtr(argv[1])); } break; 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) { * currently open. */ static VALUE str_writer_pop(VALUE self) { - oj_str_writer_pop((StrWriter)DATA_PTR(self)); + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); + + oj_str_writer_pop(sw); return Qnil; } @@ -404,7 +433,10 @@ static VALUE str_writer_pop(VALUE self) { * currently open. */ static VALUE str_writer_pop_all(VALUE self) { - oj_str_writer_pop_all((StrWriter)DATA_PTR(self)); + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); + + oj_str_writer_pop_all(sw); return Qnil; } @@ -415,7 +447,8 @@ static VALUE str_writer_pop_all(VALUE self) { * Reset the writer back to the empty state. */ static VALUE str_writer_reset(VALUE self) { - StrWriter sw = (StrWriter)DATA_PTR(self); + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); sw->depth = 0; *sw->types = '\0'; @@ -434,8 +467,9 @@ static VALUE str_writer_reset(VALUE self) { * *return* [_String_] */ static VALUE str_writer_to_s(VALUE self) { - StrWriter sw = (StrWriter)DATA_PTR(self); - VALUE rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf); + StrWriter sw; + TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw); + VALUE rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf); return oj_encode(rstr); } diff --git a/ext/oj/val_stack.c b/ext/oj/val_stack.c index eeaeaf94..b27d0f2e 100644 --- a/ext/oj/val_stack.c +++ b/ext/oj/val_stack.c @@ -8,7 +8,7 @@ #include "odd.h" #include "oj.h" -static void mark(void *ptr) { +static void stack_mark(void *ptr) { ValStack stack = (ValStack)ptr; Val v; @@ -46,6 +46,17 @@ static void mark(void *ptr) { #endif } +static const rb_data_type_t oj_stack_type = { + "Oj/stack", + { + stack_mark, + NULL, + NULL, + }, + 0, + 0, +}; + VALUE oj_stack_init(ValStack stack) { #ifdef HAVE_PTHREAD_MUTEX_INIT @@ -70,7 +81,7 @@ oj_stack_init(ValStack stack) { stack->head->clen = 0; stack->head->next = NEXT_NONE; - return Data_Wrap_Struct(oj_cstack_class, mark, 0, stack); + return TypedData_Wrap_Struct(oj_cstack_class, &oj_stack_type, stack); } const char *oj_stack_next_string(ValNext n) {