diff options
-rw-r--r-- | java/src/json/ext/Generator.java | 9 | ||||
-rw-r--r-- | java/src/json/ext/GeneratorState.java | 4 | ||||
-rw-r--r-- | java/src/json/ext/Parser.java | 76 | ||||
-rw-r--r-- | java/src/json/ext/Parser.rl | 4 | ||||
-rw-r--r-- | json.gemspec | 2 | ||||
-rw-r--r-- | json_pure.gemspec | 2 | ||||
-rw-r--r-- | lib/json/add/time.rb | 5 | ||||
-rw-r--r-- | lib/json/common.rb | 8 | ||||
-rw-r--r-- | lib/json/pure/generator.rb | 12 |
9 files changed, 75 insertions, 47 deletions
diff --git a/java/src/json/ext/Generator.java b/java/src/json/ext/Generator.java index 78dc078..ecceb27 100644 --- a/java/src/json/ext/Generator.java +++ b/java/src/json/ext/Generator.java @@ -167,9 +167,16 @@ public final class Generator { } RubyString generateNew(Session session, T object) { + RubyString result; ByteList buffer = new ByteList(guessSize(session, object)); generate(session, object, buffer); - return RubyString.newString(session.getRuntime(), buffer); + result = RubyString.newString(session.getRuntime(), buffer); + ThreadContext context = session.getContext(); + RuntimeInfo info = session.getInfo(); + if (info.encodingsSupported()) { + result.force_encoding(context, info.utf8.get()); + } + return result; } abstract void generate(Session session, T object, ByteList buffer); diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java index 65ee984..0584959 100644 --- a/java/src/json/ext/GeneratorState.java +++ b/java/src/json/ext/GeneratorState.java @@ -212,6 +212,10 @@ public class GeneratorState extends RubyObject { throw Utils.newException(context, Utils.M_GENERATOR_ERROR, "only generation of JSON objects or arrays allowed"); } + RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (info.encodingsSupported()) { + result.force_encoding(context, info.utf8.get()); + } return result; } diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 0058f95..5ba13ad 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -1477,6 +1477,10 @@ case 5: } if (cs >= JSON_string_first_final && result != null) { + RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (info.encodingsSupported() && result instanceof RubyString) { + ((RubyString)result).force_encoding(context, info.utf8.get()); + } res.update(result, p + 1); } else { res.update(null, p + 1); @@ -1484,7 +1488,7 @@ case 5: } -// line 1488 "Parser.java" +// line 1492 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1597,7 +1601,7 @@ static final int JSON_array_error = 0; static final int JSON_array_en_main = 1; -// line 693 "Parser.rl" +// line 697 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1617,14 +1621,14 @@ static final int JSON_array_en_main = 1; } -// line 1623 "Parser.java" +// line 1625 "Parser.java" { cs = JSON_array_start; } -// line 714 "Parser.rl" +// line 716 "Parser.rl" -// line 1630 "Parser.java" +// line 1632 "Parser.java" { int _klen; int _trans = 0; @@ -1705,7 +1709,7 @@ case 1: switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 662 "Parser.rl" +// line 666 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1722,13 +1726,13 @@ case 1: } break; case 1: -// line 677 "Parser.rl" +// line 681 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1734 "Parser.java" +// line 1736 "Parser.java" } } } @@ -1748,7 +1752,7 @@ case 5: break; } } -// line 715 "Parser.rl" +// line 717 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1758,7 +1762,7 @@ case 5: } -// line 1764 "Parser.java" +// line 1766 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1881,7 +1885,7 @@ static final int JSON_object_error = 0; static final int JSON_object_en_main = 1; -// line 774 "Parser.rl" +// line 776 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1906,14 +1910,14 @@ static final int JSON_object_en_main = 1; } -// line 1912 "Parser.java" +// line 1914 "Parser.java" { cs = JSON_object_start; } -// line 798 "Parser.rl" +// line 800 "Parser.rl" -// line 1919 "Parser.java" +// line 1921 "Parser.java" { int _klen; int _trans = 0; @@ -1994,7 +1998,7 @@ case 1: switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 729 "Parser.rl" +// line 731 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2011,7 +2015,7 @@ case 1: } break; case 1: -// line 744 "Parser.rl" +// line 746 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -2031,13 +2035,13 @@ case 1: } break; case 2: -// line 762 "Parser.rl" +// line 764 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2043 "Parser.java" +// line 2045 "Parser.java" } } } @@ -2057,7 +2061,7 @@ case 5: break; } } -// line 799 "Parser.rl" +// line 801 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2090,7 +2094,7 @@ case 5: } -// line 2096 "Parser.java" +// line 2098 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { @@ -2194,7 +2198,7 @@ static final int JSON_error = 0; static final int JSON_en_main = 1; -// line 864 "Parser.rl" +// line 866 "Parser.rl" public IRubyObject parseStrict() { @@ -2204,16 +2208,16 @@ static final int JSON_en_main = 1; ParserResult res = new ParserResult(); -// line 2210 "Parser.java" +// line 2212 "Parser.java" { cs = JSON_start; } -// line 873 "Parser.rl" +// line 875 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2219 "Parser.java" +// line 2221 "Parser.java" { int _klen; int _trans = 0; @@ -2294,7 +2298,7 @@ case 1: switch ( _JSON_actions[_acts++] ) { case 0: -// line 836 "Parser.rl" +// line 838 "Parser.rl" { currentNesting = 1; parseObject(res, p, pe); @@ -2308,7 +2312,7 @@ case 1: } break; case 1: -// line 848 "Parser.rl" +// line 850 "Parser.rl" { currentNesting = 1; parseArray(res, p, pe); @@ -2321,7 +2325,7 @@ case 1: } } break; -// line 2327 "Parser.java" +// line 2329 "Parser.java" } } } @@ -2341,7 +2345,7 @@ case 5: break; } } -// line 876 "Parser.rl" +// line 878 "Parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2351,7 +2355,7 @@ case 5: } -// line 2357 "Parser.java" +// line 2359 "Parser.java" private static byte[] init__JSON_quirks_mode_actions_0() { return new byte [] { @@ -2454,7 +2458,7 @@ static final int JSON_quirks_mode_error = 0; static final int JSON_quirks_mode_en_main = 1; -// line 904 "Parser.rl" +// line 906 "Parser.rl" public IRubyObject parseQuirksMode() { @@ -2464,16 +2468,16 @@ static final int JSON_quirks_mode_en_main = 1; ParserResult res = new ParserResult(); -// line 2470 "Parser.java" +// line 2472 "Parser.java" { cs = JSON_quirks_mode_start; } -// line 913 "Parser.rl" +// line 915 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2479 "Parser.java" +// line 2481 "Parser.java" { int _klen; int _trans = 0; @@ -2554,7 +2558,7 @@ case 1: switch ( _JSON_quirks_mode_actions[_acts++] ) { case 0: -// line 890 "Parser.rl" +// line 892 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2566,7 +2570,7 @@ case 1: } } break; -// line 2572 "Parser.java" +// line 2574 "Parser.java" } } } @@ -2586,7 +2590,7 @@ case 5: break; } } -// line 916 "Parser.rl" +// line 918 "Parser.rl" if (cs >= JSON_quirks_mode_first_final && p == pe) { return result; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 6d9d4f9..73062cf 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -647,6 +647,10 @@ public class Parser extends RubyObject { } if (cs >= JSON_string_first_final && result != null) { + RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + if (info.encodingsSupported() && result instanceof RubyString) { + ((RubyString)result).force_encoding(context, info.utf8.get()); + } res.update(result, p + 1); } else { res.update(null, p + 1); diff --git a/json.gemspec b/json.gemspec index 1987d46..d351e5c 100644 --- a/json.gemspec +++ b/json.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2012-05-07" + s.date = "2012-05-09" s.description = "This is a JSON implementation as a Ruby extension in C." s.email = "flori@ping.de" s.extensions = ["ext/json/ext/parser/extconf.rb", "ext/json/ext/generator/extconf.rb"] diff --git a/json_pure.gemspec b/json_pure.gemspec index 15ec7de..e0bc321 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Florian Frank"] - s.date = "2012-05-07" + s.date = "2012-05-09" s.description = "This is a JSON implementation in pure Ruby." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc"] diff --git a/lib/json/add/time.rb b/lib/json/add/time.rb index 9755707..338209d 100644 --- a/lib/json/add/time.rb +++ b/lib/json/add/time.rb @@ -20,10 +20,13 @@ class Time # Returns a hash, that will be turned into a JSON object and represent this # object. def as_json(*) + nanoseconds = [ tv_usec * 1000 ] + respond_to?(:tv_nsec) and nanoseconds << tv_nsec + nanoseconds = nanoseconds.max { JSON.create_id => self.class.name, 's' => tv_sec, - 'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000 + 'n' => nanoseconds, } end diff --git a/lib/json/common.rb b/lib/json/common.rb index a30e4ce..05eaf26 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -103,7 +103,13 @@ module JSON MinusInfinity = -Infinity # The base exception for JSON errors. - class JSONError < StandardError; end + class JSONError < StandardError + def self.wrap(exception) + obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}") + obj.set_backtrace exception.backtrace + obj + end + end # This exception is raised if a parser error occurs. class ParserError < JSONError; end diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 3d5f09f..3c81915 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -41,7 +41,6 @@ module JSON if defined?(::Encoding) def utf8_to_json(string) # :nodoc: string = string.dup - string << '' # XXX workaround: avoid buffer sharing string.force_encoding(::Encoding::ASCII_8BIT) string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } string.force_encoding(::Encoding::UTF_8) @@ -50,9 +49,8 @@ module JSON def utf8_to_json_ascii(string) # :nodoc: string = string.dup - string << '' # XXX workaround: avoid buffer sharing string.force_encoding(::Encoding::ASCII_8BIT) - string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } + string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] } string.gsub!(/( (?: [\xc2-\xdf][\x80-\xbf] | @@ -63,16 +61,18 @@ module JSON )/nx) { |c| c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] + s.force_encoding(::Encoding::ASCII_8BIT) s.gsub!(/.{4}/n, '\\\\u\&') + s.force_encoding(::Encoding::UTF_8) } string.force_encoding(::Encoding::UTF_8) string rescue => e - raise GeneratorError, "Caught #{e.class}: #{e}" + raise GeneratorError.wrap(e) end else def utf8_to_json(string) # :nodoc: - string.gsub(/["\\\x0-\x1f]/) { MAP[$&] } + string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] } end def utf8_to_json_ascii(string) # :nodoc: @@ -91,7 +91,7 @@ module JSON } string rescue => e - raise GeneratorError, "Caught #{e.class}: #{e}" + raise GeneratorError.wrap(e) end end module_function :utf8_to_json, :utf8_to_json_ascii |