diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index d60fbba41..5248a9e26 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -31,7 +31,7 @@ typedef struct JSON_Generator_StateStruct { #define RB_UNLIKELY(cond) (cond) #endif -static VALUE mJSON, cState, cFragment, mString_Extend, eGeneratorError, eNestingError, Encoding_UTF_8; +static VALUE mJSON, cState, cFragment, eGeneratorError, eNestingError, Encoding_UTF_8; static ID i_to_s, i_to_json, i_new, i_pack, i_unpack, i_create_id, i_extend, i_encode; static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan, @@ -835,18 +835,6 @@ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self) return cState_partial_generate(Vstate, self, generate_json_float, Qfalse); } -/* - * call-seq: String.included(modul) - * - * Extends _modul_ with the String::Extend module. - */ -static VALUE mString_included_s(VALUE self, VALUE modul) -{ - VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend); - rb_call_super(1, &modul); - return result; -} - /* * call-seq: to_json(*) * @@ -861,51 +849,6 @@ static VALUE mString_to_json(int argc, VALUE *argv, VALUE self) return cState_partial_generate(Vstate, self, generate_json_string, Qfalse); } -/* - * call-seq: to_json_raw_object() - * - * This method creates a raw object hash, that can be nested into - * other data structures and will be generated as a raw string. This - * method should be used, if you want to convert raw strings to JSON - * instead of UTF-8 strings, e. g. binary data. - */ -static VALUE mString_to_json_raw_object(VALUE self) -{ - VALUE ary; - VALUE result = rb_hash_new(); - rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self))); - ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*")); - rb_hash_aset(result, rb_utf8_str_new_lit("raw"), ary); - return result; -} - -/* - * call-seq: to_json_raw(*args) - * - * This method creates a JSON text from the result of a call to - * to_json_raw_object of this String. - */ -static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self) -{ - VALUE obj = mString_to_json_raw_object(self); - Check_Type(obj, T_HASH); - return mHash_to_json(argc, argv, obj); -} - -/* - * call-seq: json_create(o) - * - * Raw Strings are JSON Objects (the raw bytes are stored in an array for the - * key "raw"). The Ruby String can be created by this module method. - */ -static VALUE mString_Extend_json_create(VALUE self, VALUE o) -{ - VALUE ary; - Check_Type(o, T_HASH); - ary = rb_hash_aref(o, rb_str_new2("raw")); - return rb_funcall(ary, i_pack, 1, rb_str_new2("C*")); -} - /* * call-seq: to_json(*) * @@ -2091,13 +2034,7 @@ void Init_generator(void) rb_define_method(mFloat, "to_json", mFloat_to_json, -1); VALUE mString = rb_define_module_under(mGeneratorMethods, "String"); - rb_define_singleton_method(mString, "included", mString_included_s, 1); rb_define_method(mString, "to_json", mString_to_json, -1); - rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1); - rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0); - - mString_Extend = rb_define_module_under(mString, "Extend"); - rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1); VALUE mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass"); rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1); diff --git a/java/src/json/ext/GeneratorMethods.java b/java/src/json/ext/GeneratorMethods.java index eb31b9efc..3019ae091 100644 --- a/java/src/json/ext/GeneratorMethods.java +++ b/java/src/json/ext/GeneratorMethods.java @@ -43,9 +43,6 @@ static void populate(RuntimeInfo info, RubyModule module) { defineMethods(module, "Object", RbObject.class); defineMethods(module, "String", RbString.class); defineMethods(module, "TrueClass", RbTrue.class); - - RubyModule stringExtend = module.defineModuleUnder("String").defineModuleUnder("Extend"); - stringExtend.defineAnnotatedMethods(StringExtend.class); } /** @@ -118,95 +115,6 @@ public static IRubyObject to_json(ThreadContext context, IRubyObject vSelf) { public static IRubyObject to_json(ThreadContext context, IRubyObject vSelf, IRubyObject arg0) { return Generator.generateJson(context, (RubyString)vSelf, Generator.STRING_HANDLER, arg0); } - - /** - * {@link RubyString String}#to_json_raw(*) - * - *

This method creates a JSON text from the result of a call to - * {@link #to_json_raw_object} of this String. - */ - @JRubyMethod - public static IRubyObject to_json_raw(ThreadContext context, IRubyObject vSelf) { - RubyHash obj = toJsonRawObject(context, Utils.ensureString(vSelf)); - return Generator.generateJson(context, obj, Generator.HASH_HANDLER); - } - - @JRubyMethod - public static IRubyObject to_json_raw(ThreadContext context, IRubyObject vSelf, IRubyObject arg0) { - RubyHash obj = toJsonRawObject(context, Utils.ensureString(vSelf)); - return Generator.generateJson(context, obj, Generator.HASH_HANDLER, arg0); - } - - /** - * {@link RubyString String}#to_json_raw_object(*) - * - *

This method creates a raw object Hash, that can be nested into - * other data structures and will be unparsed as a raw string. This - * method should be used if you want to convert raw strings to JSON - * instead of UTF-8 strings, e.g. binary data. - */ - @JRubyMethod - public static IRubyObject to_json_raw_object(ThreadContext context, IRubyObject vSelf) { - return toJsonRawObject(context, Utils.ensureString(vSelf)); - } - - private static RubyHash toJsonRawObject(ThreadContext context, - RubyString self) { - Ruby runtime = context.runtime; - RubyHash result = RubyHash.newHash(runtime); - - IRubyObject createId = RuntimeInfo.forRuntime(runtime) - .jsonModule.get().callMethod(context, "create_id"); - result.op_aset(context, createId, self.getMetaClass().to_s()); - - ByteList bl = self.getByteList(); - byte[] uBytes = bl.unsafeBytes(); - RubyArray array = runtime.newArray(bl.length()); - for (int i = bl.begin(), t = bl.begin() + bl.length(); i < t; i++) { - array.store(i, runtime.newFixnum(uBytes[i] & 0xff)); - } - - result.op_aset(context, runtime.newString("raw"), array); - return result; - } - - @JRubyMethod(module=true) - public static IRubyObject included(ThreadContext context, IRubyObject extendModule, IRubyObject module) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.runtime); - return module.callMethod(context, "extend", ((RubyModule) extendModule).getConstant("Extend")); - } - } - - public static class StringExtend { - /** - * {@link RubyString String}#json_create(o) - * - *

Raw Strings are JSON Objects (the raw bytes are stored in an - * array for the key "raw"). The Ruby String can be created by this - * module method. - */ - @JRubyMethod - public static IRubyObject json_create(ThreadContext context, - IRubyObject vSelf, IRubyObject vHash) { - Ruby runtime = context.runtime; - RubyHash o = vHash.convertToHash(); - IRubyObject rawData = o.fastARef(runtime.newString("raw")); - if (rawData == null) { - throw runtime.newArgumentError("\"raw\" value not defined " - + "for encoded String"); - } - RubyArray ary = Utils.ensureArray(rawData); - byte[] bytes = new byte[ary.getLength()]; - for (int i = 0, t = ary.getLength(); i < t; i++) { - IRubyObject element = ary.eltInternal(i); - if (element instanceof RubyFixnum) { - bytes[i] = (byte)RubyNumeric.fix2long(element); - } else { - throw runtime.newTypeError(element, runtime.getFixnum()); - } - } - return runtime.newString(new ByteList(bytes, false)); - } } public static class RbTrue { diff --git a/lib/json/add/core.rb b/lib/json/add/core.rb index 485f097ff..61ff45421 100644 --- a/lib/json/add/core.rb +++ b/lib/json/add/core.rb @@ -7,6 +7,7 @@ require 'json/add/exception' require 'json/add/range' require 'json/add/regexp' +require 'json/add/string' require 'json/add/struct' require 'json/add/symbol' require 'json/add/time' diff --git a/lib/json/add/string.rb b/lib/json/add/string.rb new file mode 100644 index 000000000..46f07967c --- /dev/null +++ b/lib/json/add/string.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class String + # call-seq: json_create(o) + # + # Raw Strings are JSON Objects (the raw bytes are stored in an array for the + # key "raw"). The Ruby String can be created by this class method. + def self.json_create(object) + object["raw"].pack("C*") + end + + # call-seq: to_json_raw_object() + # + # This method creates a raw object hash, that can be nested into + # other data structures and will be generated as a raw string. This + # method should be used, if you want to convert raw strings to JSON + # instead of UTF-8 strings, e. g. binary data. + def to_json_raw_object + { + JSON.create_id => self.class.name, + "raw" => unpack("C*"), + } + end + + # call-seq: to_json_raw(*args) + # + # This method creates a JSON text from the result of a call to + # to_json_raw_object of this String. + def to_json_raw(...) + to_json_raw_object.to_json(...) + end +end \ No newline at end of file diff --git a/lib/json/truffle_ruby/generator.rb b/lib/json/truffle_ruby/generator.rb index c814106de..aba20068a 100644 --- a/lib/json/truffle_ruby/generator.rb +++ b/lib/json/truffle_ruby/generator.rb @@ -635,39 +635,6 @@ def to_json(state = nil, *args) rescue Encoding::UndefinedConversionError => error raise ::JSON::GeneratorError.new(error.message, self) end - - # Module that holds the extending methods if, the String module is - # included. - module Extend - # Raw Strings are JSON Objects (the raw bytes are stored in an - # array for the key "raw"). The Ruby String can be created by this - # module method. - def json_create(o) - o['raw'].pack('C*') - end - end - - # Extends _modul_ with the String::Extend module. - def self.included(modul) - modul.extend Extend - end - - # This method creates a raw object hash, that can be nested into - # other data structures and will be unparsed as a raw string. This - # method should be used, if you want to convert raw strings to JSON - # instead of UTF-8 strings, e. g. binary data. - def to_json_raw_object - { - JSON.create_id => self.class.name, - 'raw' => self.unpack('C*'), - } - end - - # This method creates a JSON text from the result of - # a call to to_json_raw_object of this String. - def to_json_raw(*args) - to_json_raw_object.to_json(*args) - end end module TrueClass