mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* transcode.c (transcode_loop): call default handler of the given
hash, method, proc or [] method as fallback. [ruby-dev:42692] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c207b0b727
commit
5bf72d1fa6
5 changed files with 73 additions and 9 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Tue Dec 7 22:05:25 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* transcode.c (transcode_loop): call default handler of the given
|
||||||
|
hash, method, proc or [] method as fallback. [ruby-dev:42692]
|
||||||
|
|
||||||
Tue Dec 7 21:59:37 2010 Kouhei Sutou <kou@cozmixng.org>
|
Tue Dec 7 21:59:37 2010 Kouhei Sutou <kou@cozmixng.org>
|
||||||
|
|
||||||
* lib/rexml/light/node.rb: remove circular require.
|
* lib/rexml/light/node.rb: remove circular require.
|
||||||
|
|
|
@ -340,6 +340,7 @@ int rb_proc_arity(VALUE);
|
||||||
VALUE rb_proc_lambda_p(VALUE);
|
VALUE rb_proc_lambda_p(VALUE);
|
||||||
VALUE rb_binding_new(void);
|
VALUE rb_binding_new(void);
|
||||||
VALUE rb_obj_method(VALUE, VALUE);
|
VALUE rb_obj_method(VALUE, VALUE);
|
||||||
|
VALUE rb_obj_is_method(VALUE);
|
||||||
VALUE rb_method_call(int, VALUE*, VALUE);
|
VALUE rb_method_call(int, VALUE*, VALUE);
|
||||||
int rb_mod_method_arity(VALUE, ID);
|
int rb_mod_method_arity(VALUE, ID);
|
||||||
int rb_obj_method_arity(VALUE, ID);
|
int rb_obj_method_arity(VALUE, ID);
|
||||||
|
|
10
proc.c
10
proc.c
|
@ -28,7 +28,6 @@ VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
|
||||||
|
|
||||||
static VALUE bmcall(VALUE, VALUE);
|
static VALUE bmcall(VALUE, VALUE);
|
||||||
static int method_arity(VALUE);
|
static int method_arity(VALUE);
|
||||||
static int rb_obj_is_method(VALUE m);
|
|
||||||
rb_iseq_t *rb_method_get_iseq(VALUE method);
|
rb_iseq_t *rb_method_get_iseq(VALUE method);
|
||||||
|
|
||||||
/* Proc */
|
/* Proc */
|
||||||
|
@ -893,10 +892,15 @@ static const rb_data_type_t method_data_type = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int
|
VALUE
|
||||||
rb_obj_is_method(VALUE m)
|
rb_obj_is_method(VALUE m)
|
||||||
{
|
{
|
||||||
return rb_typeddata_is_kind_of(m, &method_data_type);
|
if (rb_typeddata_is_kind_of(m, &method_data_type)) {
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
|
|
@ -1947,4 +1947,21 @@ class TestTranscode < Test::Unit::TestCase
|
||||||
assert_equal("[ISU]", "\u{1F4BA}".encode("SJIS-KDDI",
|
assert_equal("[ISU]", "\u{1F4BA}".encode("SJIS-KDDI",
|
||||||
fallback: {"\u{1F4BA}" => "[ISU]"}))
|
fallback: {"\u{1F4BA}" => "[ISU]"}))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_fallback_hash_default
|
||||||
|
fallback = Hash.new {|h, x| "U+%.4X" % x.unpack("U")}
|
||||||
|
assert_equal("U+3042", "\u{3042}".encode("US-ASCII", fallback: fallback))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fallback_proc
|
||||||
|
fallback = proc {|x| "U+%.4X" % x.unpack("U")}
|
||||||
|
assert_equal("U+3042", "\u{3042}".encode("US-ASCII", fallback: fallback))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fallback_method
|
||||||
|
def (fallback = "U+%.4X").escape(x)
|
||||||
|
self % x.unpack("U")
|
||||||
|
end
|
||||||
|
assert_equal("U+3042", "\u{3042}".encode("US-ASCII", fallback: fallback.method(:escape)))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
49
transcode.c
49
transcode.c
|
@ -21,7 +21,7 @@ VALUE rb_eConverterNotFoundError;
|
||||||
|
|
||||||
VALUE rb_cEncodingConverter;
|
VALUE rb_cEncodingConverter;
|
||||||
|
|
||||||
static VALUE sym_invalid, sym_undef, sym_replace, sym_fallback;
|
static VALUE sym_invalid, sym_undef, sym_replace, sym_fallback, sym_aref;
|
||||||
static VALUE sym_xml, sym_text, sym_attr;
|
static VALUE sym_xml, sym_text, sym_attr;
|
||||||
static VALUE sym_universal_newline;
|
static VALUE sym_universal_newline;
|
||||||
static VALUE sym_crlf_newline;
|
static VALUE sym_crlf_newline;
|
||||||
|
@ -2240,6 +2240,26 @@ output_replacement_character(rb_econv_t *ec)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
#define hash_fallback rb_hash_aref
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
proc_fallback(VALUE fallback, VALUE c)
|
||||||
|
{
|
||||||
|
return rb_proc_call(fallback, rb_ary_new4(1, &c));
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
method_fallback(VALUE fallback, VALUE c)
|
||||||
|
{
|
||||||
|
return rb_method_call(1, &c, fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
aref_fallback(VALUE fallback, VALUE c)
|
||||||
|
{
|
||||||
|
return rb_funcall3(fallback, sym_aref, 1, &c);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
|
transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
|
||||||
const unsigned char *in_stop, unsigned char *out_stop,
|
const unsigned char *in_stop, unsigned char *out_stop,
|
||||||
|
@ -2257,13 +2277,27 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
|
||||||
int max_output;
|
int max_output;
|
||||||
VALUE exc;
|
VALUE exc;
|
||||||
VALUE fallback = Qnil;
|
VALUE fallback = Qnil;
|
||||||
|
VALUE (*fallback_func)(VALUE, VALUE) = 0;
|
||||||
|
|
||||||
ec = rb_econv_open_opts(src_encoding, dst_encoding, ecflags, ecopts);
|
ec = rb_econv_open_opts(src_encoding, dst_encoding, ecflags, ecopts);
|
||||||
if (!ec)
|
if (!ec)
|
||||||
rb_exc_raise(rb_econv_open_exc(src_encoding, dst_encoding, ecflags));
|
rb_exc_raise(rb_econv_open_exc(src_encoding, dst_encoding, ecflags));
|
||||||
|
|
||||||
if (!NIL_P(ecopts) && TYPE(ecopts) == T_HASH)
|
if (!NIL_P(ecopts) && TYPE(ecopts) == T_HASH) {
|
||||||
fallback = rb_hash_aref(ecopts, sym_fallback);
|
fallback = rb_hash_aref(ecopts, sym_fallback);
|
||||||
|
if (RB_TYPE_P(fallback, T_HASH)) {
|
||||||
|
fallback_func = hash_fallback;
|
||||||
|
}
|
||||||
|
else if (rb_obj_is_proc(fallback)) {
|
||||||
|
fallback_func = proc_fallback;
|
||||||
|
}
|
||||||
|
else if (rb_obj_is_method(fallback)) {
|
||||||
|
fallback_func = method_fallback;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fallback_func = aref_fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
last_tc = ec->last_tc;
|
last_tc = ec->last_tc;
|
||||||
max_output = last_tc ? last_tc->transcoder->max_output : 1;
|
max_output = last_tc ? last_tc->transcoder->max_output : 1;
|
||||||
|
|
||||||
|
@ -2275,8 +2309,8 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos,
|
||||||
(const char *)ec->last_error.error_bytes_start,
|
(const char *)ec->last_error.error_bytes_start,
|
||||||
ec->last_error.error_bytes_len,
|
ec->last_error.error_bytes_len,
|
||||||
rb_enc_find(ec->last_error.source_encoding));
|
rb_enc_find(ec->last_error.source_encoding));
|
||||||
rep = rb_hash_lookup2(fallback, rep, Qundef);
|
rep = (*fallback_func)(fallback, rep);
|
||||||
if (rep != Qundef) {
|
if (rep != Qundef && !NIL_P(rep)) {
|
||||||
StringValue(rep);
|
StringValue(rep);
|
||||||
ret = rb_econv_insert_output(ec, (const unsigned char *)RSTRING_PTR(rep),
|
ret = rb_econv_insert_output(ec, (const unsigned char *)RSTRING_PTR(rep),
|
||||||
RSTRING_LEN(rep), rb_enc_name(rb_enc_get(rep)));
|
RSTRING_LEN(rep), rb_enc_name(rb_enc_get(rep)));
|
||||||
|
@ -2479,8 +2513,10 @@ rb_econv_prepare_opts(VALUE opthash, VALUE *opts)
|
||||||
|
|
||||||
v = rb_hash_aref(opthash, sym_fallback);
|
v = rb_hash_aref(opthash, sym_fallback);
|
||||||
if (!NIL_P(v)) {
|
if (!NIL_P(v)) {
|
||||||
v = rb_convert_type(v, T_HASH, "Hash", "to_hash");
|
VALUE h = rb_check_hash_type(v);
|
||||||
if (!NIL_P(v)) {
|
if (NIL_P(h)
|
||||||
|
? (rb_obj_is_proc(v) || rb_obj_is_method(v) || rb_respond_to(v, sym_aref))
|
||||||
|
: (v = h, 1)) {
|
||||||
if (NIL_P(newhash))
|
if (NIL_P(newhash))
|
||||||
newhash = rb_hash_new();
|
newhash = rb_hash_new();
|
||||||
rb_hash_aset(newhash, sym_fallback, v);
|
rb_hash_aset(newhash, sym_fallback, v);
|
||||||
|
@ -4258,6 +4294,7 @@ Init_transcode(void)
|
||||||
sym_undef = ID2SYM(rb_intern("undef"));
|
sym_undef = ID2SYM(rb_intern("undef"));
|
||||||
sym_replace = ID2SYM(rb_intern("replace"));
|
sym_replace = ID2SYM(rb_intern("replace"));
|
||||||
sym_fallback = ID2SYM(rb_intern("fallback"));
|
sym_fallback = ID2SYM(rb_intern("fallback"));
|
||||||
|
sym_aref = ID2SYM(rb_intern("[]"));
|
||||||
sym_xml = ID2SYM(rb_intern("xml"));
|
sym_xml = ID2SYM(rb_intern("xml"));
|
||||||
sym_text = ID2SYM(rb_intern("text"));
|
sym_text = ID2SYM(rb_intern("text"));
|
||||||
sym_attr = ID2SYM(rb_intern("attr"));
|
sym_attr = ID2SYM(rb_intern("attr"));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue