ruby-changes:38189
From: hsbt <ko1@a...>
Date: Sun, 12 Apr 2015 23:22:42 +0900 (JST)
Subject: [ruby-changes:38189] hsbt:r50267 (trunk): * ext/json/*, test/json/*: Reverted r50231. Because it's not works with
hsbt 2015-04-12 17:36:37 +0900 (Sun, 12 Apr 2015) New Revision: 50267 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50267 Log: * ext/json/*, test/json/*: Reverted r50231. Because it's not works with cross-compile environment. Added directories: trunk/ext/json/ trunk/ext/json/fbuffer/ trunk/ext/json/generator/ trunk/ext/json/lib/ trunk/ext/json/lib/json/ trunk/ext/json/lib/json/add/ trunk/ext/json/parser/ trunk/test/json/ trunk/test/json/fixtures/ Added files: trunk/ext/json/extconf.rb trunk/ext/json/fbuffer/fbuffer.h trunk/ext/json/generator/depend trunk/ext/json/generator/extconf.rb trunk/ext/json/generator/generator.c trunk/ext/json/generator/generator.h trunk/ext/json/lib/json/add/bigdecimal.rb trunk/ext/json/lib/json/add/complex.rb trunk/ext/json/lib/json/add/core.rb trunk/ext/json/lib/json/add/date.rb trunk/ext/json/lib/json/add/date_time.rb trunk/ext/json/lib/json/add/exception.rb trunk/ext/json/lib/json/add/ostruct.rb trunk/ext/json/lib/json/add/range.rb trunk/ext/json/lib/json/add/rational.rb trunk/ext/json/lib/json/add/regexp.rb trunk/ext/json/lib/json/add/struct.rb trunk/ext/json/lib/json/add/symbol.rb trunk/ext/json/lib/json/add/time.rb trunk/ext/json/lib/json/common.rb trunk/ext/json/lib/json/ext.rb trunk/ext/json/lib/json/generic_object.rb trunk/ext/json/lib/json/version.rb trunk/ext/json/lib/json.rb trunk/ext/json/parser/depend trunk/ext/json/parser/extconf.rb trunk/ext/json/parser/parser.c trunk/ext/json/parser/parser.h trunk/ext/json/parser/parser.rl trunk/ext/json/parser/prereq.mk trunk/test/json/fixtures/fail1.json trunk/test/json/fixtures/fail10.json trunk/test/json/fixtures/fail11.json trunk/test/json/fixtures/fail12.json trunk/test/json/fixtures/fail13.json trunk/test/json/fixtures/fail14.json trunk/test/json/fixtures/fail18.json trunk/test/json/fixtures/fail19.json trunk/test/json/fixtures/fail2.json trunk/test/json/fixtures/fail20.json trunk/test/json/fixtures/fail21.json trunk/test/json/fixtures/fail22.json trunk/test/json/fixtures/fail23.json trunk/test/json/fixtures/fail24.json trunk/test/json/fixtures/fail25.json trunk/test/json/fixtures/fail27.json trunk/test/json/fixtures/fail28.json trunk/test/json/fixtures/fail3.json trunk/test/json/fixtures/fail4.json trunk/test/json/fixtures/fail5.json trunk/test/json/fixtures/fail6.json trunk/test/json/fixtures/fail7.json trunk/test/json/fixtures/fail8.json trunk/test/json/fixtures/fail9.json trunk/test/json/fixtures/pass1.json trunk/test/json/fixtures/pass15.json trunk/test/json/fixtures/pass16.json trunk/test/json/fixtures/pass17.json trunk/test/json/fixtures/pass2.json trunk/test/json/fixtures/pass26.json trunk/test/json/fixtures/pass3.json trunk/test/json/setup_variant.rb trunk/test/json/test_json.rb trunk/test/json/test_json_addition.rb trunk/test/json/test_json_encoding.rb trunk/test/json/test_json_fixtures.rb trunk/test/json/test_json_generate.rb trunk/test/json/test_json_generic_object.rb trunk/test/json/test_json_string_matching.rb trunk/test/json/test_json_unicode.rb Modified files: trunk/ChangeLog trunk/defs/default_gems trunk/gems/bundled_gems trunk/lib/rdoc/rubygems_hook.rb trunk/lib/rdoc/test_case.rb trunk/lib/rubygems/test_case.rb trunk/test/rdoc/test_rdoc_generator_darkfish.rb trunk/test/rdoc/test_rdoc_generator_json_index.rb trunk/test/rdoc/test_rdoc_rubygems_hook.rb trunk/test/rdoc/test_rdoc_servlet.rb trunk/test/ruby/test_extlibs.rb trunk/test/rubygems/test_gem_commands_install_command.rb trunk/test/rubygems/test_gem_commands_update_command.rb Index: defs/default_gems =================================================================== --- defs/default_gems (revision 50266) +++ defs/default_gems (revision 50267) @@ -1,2 +1,3 @@ https://github.com/ruby/ruby/blob/trunk/defs/default_gems#L1 # gem base directory versioning file [executable files under bin] rdoc lib/rdoc lib/rdoc.rb [rdoc ri] +json ext/json ext/json/lib/json/version.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 50266) +++ ChangeLog (revision 50267) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Apr 12 17:35:17 2015 SHIBATA Hiroshi <shibata.hiroshi@g...> + + * ext/json/*, test/json/*: Reverted r50231. Because it's not works with + cross-compile environment. + Sun Apr 12 15:34:59 2015 Nobuyoshi Nakada <nobu@r...> * parse.y (arg): fix segfault by null caused by syntax error. Index: gems/bundled_gems =================================================================== --- gems/bundled_gems (revision 50266) +++ gems/bundled_gems (revision 50267) @@ -2,4 +2,3 @@ power_assert 0.2.2 https://github.com/ruby/ruby/blob/trunk/gems/bundled_gems#L2 test-unit 3.0.9 minitest 5.4.3 rake 10.4.2 -json 1.8.2 Index: lib/rubygems/test_case.rb =================================================================== --- lib/rubygems/test_case.rb (revision 50266) +++ lib/rubygems/test_case.rb (revision 50267) @@ -21,16 +21,7 @@ end https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L21 # them while we're testing rubygems, and thus we can't actually load them. unless Gem::Dependency.new('rdoc', '>= 3.10').matching_specs.empty? gem 'rdoc' - begin - gem 'json' - rescue Gem::LoadError - # for Ruby 2.3.0 - end -end - -begin - require 'json' -rescue LoadError + gem 'json' end require 'minitest/autorun' Index: lib/rdoc/rubygems_hook.rb =================================================================== --- lib/rdoc/rubygems_hook.rb (revision 50266) +++ lib/rdoc/rubygems_hook.rb (revision 50267) @@ -3,11 +3,6 @@ require 'rubygems/user_interaction' https://github.com/ruby/ruby/blob/trunk/lib/rdoc/rubygems_hook.rb#L3 require 'fileutils' require 'rdoc' -begin - require 'json' -rescue LoadError -end - ## # Gem::RDoc provides methods to generate RDoc and ri data for installed gems # upon gem installation. @@ -205,7 +200,7 @@ class RDoc::RubygemsHook https://github.com/ruby/ruby/blob/trunk/lib/rdoc/rubygems_hook.rb#L200 @generate_ri and (@force or not File.exist? @ri_dir) document 'darkfish', options, @rdoc_dir if - defined?(JSON) and @generate_rdoc and (@force or not File.exist? @rdoc_dir) + @generate_rdoc and (@force or not File.exist? @rdoc_dir) end ## @@ -255,3 +250,4 @@ class RDoc::RubygemsHook https://github.com/ruby/ruby/blob/trunk/lib/rdoc/rubygems_hook.rb#L250 end end + Index: lib/rdoc/test_case.rb =================================================================== --- lib/rdoc/test_case.rb (revision 50266) +++ lib/rdoc/test_case.rb (revision 50267) @@ -6,11 +6,6 @@ rescue NoMethodError, Gem::LoadError https://github.com/ruby/ruby/blob/trunk/lib/rdoc/test_case.rb#L6 # for ruby tests end -begin - require 'json' -rescue LoadError -end - require 'minitest/autorun' require 'minitest/benchmark' if ENV['BENCHMARK'] @@ -219,3 +214,4 @@ $LOAD_PATH.each do |load_path| https://github.com/ruby/ruby/blob/trunk/lib/rdoc/test_case.rb#L214 break if load_path[0] == ?/ load_path.replace File.expand_path load_path end if RUBY_VERSION < '1.9' + Index: ext/json/fbuffer/fbuffer.h =================================================================== --- ext/json/fbuffer/fbuffer.h (revision 0) +++ ext/json/fbuffer/fbuffer.h (revision 50267) @@ -0,0 +1,190 @@ https://github.com/ruby/ruby/blob/trunk/ext/json/fbuffer/fbuffer.h#L1 + +#ifndef _FBUFFER_H_ +#define _FBUFFER_H_ + +#include "ruby.h" + +#ifndef RHASH_SIZE +#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries) +#endif + +#ifndef RFLOAT_VALUE +#define RFLOAT_VALUE(val) (RFLOAT(val)->value) +#endif + +#ifndef RARRAY_PTR +#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr +#endif +#ifndef RARRAY_LEN +#define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len +#endif +#ifndef RSTRING_PTR +#define RSTRING_PTR(string) RSTRING(string)->ptr +#endif +#ifndef RSTRING_LEN +#define RSTRING_LEN(string) RSTRING(string)->len +#endif + +#ifdef PRIsVALUE +# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) +# define RB_OBJ_STRING(obj) (obj) +#else +# define PRIsVALUE "s" +# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) +# define RB_OBJ_STRING(obj) StringValueCStr(obj) +#endif + +#ifdef HAVE_RUBY_ENCODING_H +#include "ruby/encoding.h" +#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) +#else +#define FORCE_UTF8(obj) +#endif + +/* We don't need to guard objects for rbx, so let's do nothing at all. */ +#ifndef RB_GC_GUARD +#define RB_GC_GUARD(object) +#endif + +typedef struct FBufferStruct { + unsigned long initial_length; + char *ptr; + unsigned long len; + unsigned long capa; +} FBuffer; + +#define FBUFFER_INITIAL_LENGTH_DEFAULT 1024 + +#define FBUFFER_PTR(fb) (fb->ptr) +#define FBUFFER_LEN(fb) (fb->len) +#define FBUFFER_CAPA(fb) (fb->capa) +#define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb) + +static FBuffer *fbuffer_alloc(unsigned long initial_length); +static void fbuffer_free(FBuffer *fb); +static void fbuffer_clear(FBuffer *fb); +static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len); +#ifdef JSON_GENERATOR +static void fbuffer_append_long(FBuffer *fb, long number); +#endif +static void fbuffer_append_char(FBuffer *fb, char newchr); +#ifdef JSON_GENERATOR +static FBuffer *fbuffer_dup(FBuffer *fb); +static VALUE fbuffer_to_s(FBuffer *fb); +#endif + +static FBuffer *fbuffer_alloc(unsigned long initial_length) +{ + FBuffer *fb; + if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; + fb = ALLOC(FBuffer); + memset((void *) fb, 0, sizeof(FBuffer)); + fb->initial_length = initial_length; + return fb; +} + +static void fbuffer_free(FBuffer *fb) +{ + if (fb->ptr) ruby_xfree(fb->ptr); + ruby_xfree(fb); +} + +static void fbuffer_clear(FBuffer *fb) +{ + fb->len = 0; +} + +static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested) +{ + unsigned long required; + + if (!fb->ptr) { + fb->ptr = ALLOC_N(char, fb->initial_length); + fb->capa = fb->initial_length; + } + + for (required = fb->capa; requested > required - fb->len; required <<= 1); + + if (required > fb->capa) { + REALLOC_N(fb->ptr, char, required); + fb->capa = required; + } +} + +static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) +{ + if (len > 0) { + fbuffer_inc_capa(fb, len); + MEMCPY(fb->ptr + fb->len, newstr, char, len); + fb->len += len; + } +} + +#ifdef JSON_GENERATOR +static void fbuffer_append_str(FBuffer *fb, VALUE str) +{ + const char *newstr = StringValuePtr(str); + unsigned long len = RSTRING_LEN(str); + + RB_GC_GUARD(str); + + fbuffer_append(fb, newstr, len); +} +#endif + +static void fbuffer_append_char(FBuffer *fb, char newchr) +{ + fbuffer_inc_capa(fb, 1); + *(fb->ptr + fb->len) = newchr; + fb->len++; +} + +#ifdef JSON_GENERATOR +static void freverse(char *start, char *end) +{ + char c; + + while (end > start) { + c = *end, *end-- = *start, *start++ = c; + } +} + +static long fltoa(long number, char *buf) +{ + static char digits[] = "0123456789"; + long sign = number; + char* tmp = buf; + + if (sign < 0) number = -number; + do *tmp++ = digits[number % 10]; while (number /= 10); + if (sign < 0) *tmp++ = '-'; + freverse(buf, tmp - 1); + return tmp - buf; +} + +static void fbuffer_append_long(FBuffer *fb, long number) +{ + char buf[20]; + unsigned long len = fltoa(number, buf); + fbuffer_append(fb, buf, len); +} + +static FBuffer *fbuffer_dup(FBuffer *fb) +{ + unsigned long len = fb->len; + FBuffer *result; + + result = fbuffer_alloc(len); + fbuffer_append(result, FBUFFER_PAIR(fb)); + return result; +} + +static VALUE fbuffer_to_s(FBuffer *fb) +{ + VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb)); + fbuffer_free(fb); + FORCE_UTF8(result); + return result; +} +#endif +#endif Index: ext/json/generator/depend =================================================================== --- ext/json/generator/depend (revision 0) +++ ext/json/generator/depend (revision 50267) @@ -0,0 +1,21 @@ https://github.com/ruby/ruby/blob/trunk/ext/json/generator/depend#L1 +$(OBJS): $(ruby_headers) +generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h + +# AUTOGENERATED DEPENDENCIES START +generator.o: $(RUBY_EXTCONF_H) +generator.o: $(arch_hdrdir)/ruby/config.h +generator.o: $(hdrdir)/ruby/defines.h +generator.o: $(hdrdir)/ruby/encoding.h +generator.o: $(hdrdir)/ruby/intern.h +generator.o: $(hdrdir)/ruby/missing.h +generator.o: $(hdrdir)/ruby/oniguruma.h +generator.o: $(hdrdir)/ruby/re.h +generator.o: $(hdrdir)/ruby/regex.h +generator.o: $(hdrdir)/ruby/ruby.h +generator.o: $(hdrdir)/ruby/st.h +generator.o: $(hdrdir)/ruby/subst.h +generator.o: $(top_srcdir)/ext/json/fbuffer/fbuffer.h +generator.o: $(top_srcdir)/include/ruby.h +generator.o: generator.c +generator.o: generator.h +# AUTOGENERATED DEPENDENCIES END Index: ext/json/generator/generator.c =================================================================== --- ext/json/generator/generator.c (revision 0) +++ ext/json/generator/generator.c (revision 50267) @@ -0,0 +1,1463 @@ https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L1 +#include "../fbuffer/fbuffer.h" +#include "generator.h" + +#ifdef HAVE_RUBY_ENCODING_H +static VALUE CEncoding_UTF_8; +static ID i_encoding, i_encode; +#endif + +static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject, + mHash, mArray, mFixnum, mBignum, mFloat, mString, mString_Extend, + mTrueClass, mFalseClass, mNilClass, eGeneratorError, + eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE, + i_SAFE_STATE_PROTOTYPE; + +static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before, + i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only, + i_quirks_mode, i_pack, i_unpack, i_create_id, i_extend, i_key_p, + i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth, + i_buffer_initial_length, i_dup; + +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +/* + * Index into the table below with the first byte of a UTF-8 sequence to + * get the number of trailing bytes that are supposed to follow it. + * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is + * left as-is for anyone who may want to do such conversion, which was + * allowed in earlier algorithms. + */ +static const char trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +/* + * Magic values subtracted from a buffer value during UTF8 conversion. + * This table contains as many values as there might be trailing bytes + * in a UTF-8 sequence. + */ +static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; + +/* + * Utility routine to tell whether a sequence of bytes is legal UTF-8. + * This must be called with the length pre-determined by the first byte. + * If not calling this from ConvertUTF8to*, then the length can be set by: + * length = trailingBytesForUTF8[*source]+1; + * and the sequence is illegal right away if there aren't that many bytes + * available. + * If presented with a length > 4, this returns 0. The Unicode + * definition of UTF-8 goes up to 4-byte sequences. + */ +static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length) +{ + UTF8 a; + const UTF8 *srcptr = source+length; + switch (length) { + default: return 0; + /* Everything else falls through when "1"... */ + case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; + case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; + case 2: if ((a = (*--srcptr)) > 0xBF) return 0; + + switch (*source) { + /* no fall-through in this inner switch */ + case 0xE0: if (a < 0xA0) return 0; break; + case 0xED: if (a > 0x9F) return 0; break; + case 0xF0: if (a < 0x90) return 0; break; + case 0xF4: if (a > 0x8F) return 0; break; + default: if (a < 0x80) return 0; + } + + case 1: if (*source >= 0x80 && *source < 0xC2) return 0; + } + if (*source > 0xF4) return 0; + return 1; +} + +/* Escapes the UTF16 character and stores the result in the buffer buf. */ +static void unicode_escape(char *buf, UTF16 character) +{ + const char *digits = "0123456789abcdef"; + + buf[2] = digits[character >> 12]; + buf[3] = digits[(character >> 8) & 0xf]; + buf[4] = digits[(character >> 4) & 0xf]; + buf[5] = digits[character & 0xf]; +} + +/* Escapes the UTF16 character and stores the result in the buffer buf, then + * the buffer buf is appended to the FBuffer buffer. */ +static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 + character) +{ + unicode_escape(buf, character); + fbuffer_append(buffer, buf, 6); +} + +/* Converts string to a JSON string in FBuffer buffer, where all but the ASCII + * and control characters are JSON escaped. */ +static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string) +{ + const UTF8 *source = (UTF8 *) RSTRING_PTR(string); + const UTF8 *sourceEnd = source + RSTRING_LEN(string); + char buf[6] = { '\\', 'u' }; + + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + rb_raise(rb_path2class("JSON::GeneratorError"), + "partial character in source, but hit end"); + } + if (!isLegalUTF8(source, extraBytesToRead+1)) { + rb_raise(rb_path2class("JSON::GeneratorError"), + "source sequence is illegal/malformed utf-8"); + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ + case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { +#if UNI_STRICT_CONVERSION + source -= (extraBytesToRead+1); /* return to the illegal value itself */ + rb_raise(rb_path2class("JSON::GeneratorError"), + "source sequence is illegal/malformed utf-8"); +#else + unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR); +#endif + } else { + /* normal case */ + if (ch >= 0x20 && ch <= 0x7f) { + switch (ch) { + case '\\': + fbuffer_append(buffer, "\\\\", 2); + break; + case '"': + fbuffer_append(buffer, "\\\"", 2); + break; + default: + fbuffer_append_char(buffer, (char)ch); + break; + } + } else { + switch (ch) { + case '\n': + fbuffer_append(buffer, "\\n", 2); + break; + case '\r': + fbuffer_append(buffer, "\\r", 2); + break; + case '\t': + fbuffer_append(buffer, "\\t", 2); + break; + case '\f': + fbuffer_append(buffer, "\\f", 2); + break; + case '\b': + fbuffer_append(buffer, "\\b", 2); + break; + default: + unicode_escape_to_buffer(buffer, buf, (UTF16) ch); + break; + } + } + } + } else if (ch > UNI_MAX_UTF16) { +#if UNI_STRICT_CONVERSION + source -= (extraBytesToRead+1); /* return to the start */ + rb_raise(rb_path2class("JSON::GeneratorError"), + "source sequence is illegal/malformed utf8"); +#else + unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR); +#endif + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + ch -= halfBase; + unicode_escape_to_buffer(buffer, buf, (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START)); + unicode_escape_to_buffer(buffer, buf, (UTF16)((ch & halfMask) + UNI_SUR_LOW_START)); + } + } +} + +/* Converts string to a JSON string in FBuffer buffer, where only the + * characters required by the JSON standard are JSON escaped. The remaining + * characters (should be UTF8) are just passed through and appended to the + * result. */ +static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string) +{ + const char *ptr = RSTRING_PTR(string), *p; + unsigned long len = RSTRING_LEN(string), start = 0, end = 0; + const char *escape = NULL; + int escape_len; + unsigned char c; + char buf[6] = { '\\', 'u' }; + + for (start = 0, end = 0; end < len;) { + p = ptr + end; + c = (unsigned char) *p; + if (c < 0x20) { + switch (c) { + case '\n': + escape = "\\n"; + escape_len = 2; + break; + case '\r': + escape = "\\r"; + (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/