[macruby-changes] [4416] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Aug 9 16:08:01 PDT 2010
Revision: 4416
http://trac.macosforge.org/projects/ruby/changeset/4416
Author: martinlagardette at apple.com
Date: 2010-08-09 16:08:00 -0700 (Mon, 09 Aug 2010)
Log Message:
-----------
Better C implementation for Iconv
- Based off Ruby19 trunk
- Fixes #66 and #825
Modified Paths:
--------------
MacRuby/trunk/encoding.c
MacRuby/trunk/ext/iconv/extconf.rb
MacRuby/trunk/ext/iconv/iconv.c
MacRuby/trunk/rakelib/builder/builder.rb
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/close_tags.txt
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/conv_tags.txt
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/failure_tags.txt
Removed Paths:
-------------
MacRuby/trunk/lib/iconv.rb
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/charset_map_tags.txt
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/failure/
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/iconv_tags.txt
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/new_tags.txt
MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/open_tags.txt
Modified: MacRuby/trunk/encoding.c
===================================================================
--- MacRuby/trunk/encoding.c 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/encoding.c 2010-08-09 23:08:00 UTC (rev 4416)
@@ -516,6 +516,15 @@
return index_of_encoding(rb_enc_get(obj));
}
+void
+rb_enc_set_index(VALUE obj, int encindex)
+{
+ if (encindex < ENCODINGS_COUNT) {
+ return ;
+ }
+ rb_str_force_encoding(obj, rb_encodings[encindex]);
+}
+
int
rb_to_encoding_index(VALUE enc)
{
Modified: MacRuby/trunk/ext/iconv/extconf.rb
===================================================================
--- MacRuby/trunk/ext/iconv/extconf.rb 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/ext/iconv/extconf.rb 2010-08-09 23:08:00 UTC (rev 4416)
@@ -42,6 +42,7 @@
end
$cleanfiles << wrapper
end
+ $INCFLAGS << ' -I../..'
create_makefile("iconv")
if conf
open("Makefile", "a") do |mf|
Modified: MacRuby/trunk/ext/iconv/iconv.c
===================================================================
--- MacRuby/trunk/ext/iconv/iconv.c 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/ext/iconv/iconv.c 2010-08-09 23:08:00 UTC (rev 4416)
@@ -13,12 +13,14 @@
**********************************************************************/
-#include "ruby/ruby.h"
+#include "ruby/macruby.h"
+#include "ruby/node.h"
+#include "vm.h"
+#include "encoding.h"
#include <errno.h>
#include <iconv.h>
#include <assert.h>
#include "ruby/st.h"
-#include "ruby/intern.h"
#include "ruby/encoding.h"
/*
@@ -27,20 +29,20 @@
* == Summary
*
* Ruby extension for charset conversion.
- *
+ *
* == Abstract
*
* Iconv is a wrapper class for the UNIX 95 <tt>iconv()</tt> function family,
* which translates string between various encoding systems.
- *
+ *
* See Open Group's on-line documents for more details.
* * <tt>iconv.h</tt>: http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.h.html
* * <tt>iconv_open()</tt>: http://www.opengroup.org/onlinepubs/007908799/xsh/iconv_open.html
* * <tt>iconv()</tt>: http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.html
* * <tt>iconv_close()</tt>: http://www.opengroup.org/onlinepubs/007908799/xsh/iconv_close.html
- *
+ *
* Which coding systems are available is platform-dependent.
- *
+ *
* == Examples
*
* 1. Simple conversion between two charsets.
@@ -67,6 +69,12 @@
* 4. Shorthand for (3).
*
* Iconv.iconv(to, from, *input.to_a)
+ *
+ * == Attentions
+ *
+ * Even if some extentions of implementation dependent are useful,
+ * DON'T USE those extentions in libraries and scripts to widely distribute.
+ * If you want to use those feature, use String#encode.
*/
/* Invalid value for iconv_t is -1 but 0 for VALUE, I hope VALUE is
@@ -101,6 +109,7 @@
static ID rb_success, rb_failed;
static VALUE iconv_fail _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg));
+static VALUE iconv_fail_retry _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg));
static VALUE iconv_failure_initialize _((VALUE error, VALUE mesg, VALUE success, VALUE failed));
static VALUE iconv_failure_success _((VALUE self));
static VALUE iconv_failure_failed _((VALUE self));
@@ -109,8 +118,8 @@
static void iconv_dfree _((void *cd));
static VALUE iconv_free _((VALUE cd));
static VALUE iconv_try _((iconv_t cd, const char **inptr, size_t *inlen, char **outptr, size_t *outlen));
-static VALUE rb_str_derive _((VALUE str, const char* ptr, int len));
-static VALUE iconv_convert _((iconv_t cd, VALUE str, int start, int length, int toidx,
+static VALUE rb_str_derive _((VALUE str, const char* ptr, long len));
+static VALUE iconv_convert _((iconv_t cd, VALUE str, long start, long length, int toidx,
struct iconv_env_t* env));
static VALUE iconv_s_allocate _((VALUE klass));
static VALUE iconv_initialize _((int argc, VALUE *argv, VALUE self));
@@ -136,59 +145,135 @@
return charset_map;
}
+static VALUE
+strip_glibc_option(VALUE *code)
+{
+ VALUE val = StringValue(*code);
+ const char *ptr = RSTRING_PTR(val), *pend = RSTRING_END(val);
+ const char *slash = memchr(ptr, '/', pend - ptr);
+
+ if (slash && slash < pend - 1 && slash[1] == '/') {
+ VALUE opt = rb_str_subseq(val, slash - ptr, pend - slash);
+ val = rb_str_subseq(val, 0, slash - ptr);
+ *code = val;
+ return opt;
+ }
+ return 0;
+}
+
static char *
map_charset(VALUE *code)
{
- VALUE val = *code;
+ VALUE val = StringValue(*code);
if (RHASH_SIZE(charset_map)) {
VALUE key = rb_funcall2(val, rb_intern("downcase"), 0, 0);
StringValuePtr(key);
val = rb_hash_aref(charset_map, key);
- if (val != Qnil)
+ if (!NIL_P(val)) {
*code = val;
+ }
}
return StringValuePtr(*code);
}
+NORETURN(static void rb_iconv_sys_fail(const char *s));
+static void
+rb_iconv_sys_fail(const char *s)
+{
+ if (errno == 0) {
+ rb_exc_raise(iconv_fail(rb_eIconvBrokenLibrary, Qnil, Qnil, NULL, s));
+ }
+ rb_sys_fail(s);
+}
+
+#define rb_sys_fail(s) rb_iconv_sys_fail(s)
+
static iconv_t
iconv_create(VALUE to, VALUE from, struct rb_iconv_opt_t *opt, int *idx)
{
+ VALUE toopt = strip_glibc_option(&to);
+ VALUE fromopt = strip_glibc_option(&from);
+ VALUE toenc = 0, fromenc = 0;
const char* tocode = map_charset(&to);
const char* fromcode = map_charset(&from);
iconv_t cd;
+ int retry = 0;
*idx = rb_enc_find_index(tocode);
- cd = iconv_open(tocode, fromcode);
- if (cd == (iconv_t)-1) {
+ if (toopt) {
+ toenc = rb_str_plus(to, toopt);
+ tocode = RSTRING_PTR(toenc);
+ }
+ if (fromopt) {
+ fromenc = rb_str_plus(from, fromopt);
+ fromcode = RSTRING_PTR(fromenc);
+ }
+ while ((cd = iconv_open(tocode, fromcode)) == (iconv_t)-1) {
+ int inval = 0;
switch (errno) {
case EMFILE:
case ENFILE:
case ENOMEM:
- rb_gc();
- cd = iconv_open(tocode, fromcode);
+ if (!retry++) {
+ rb_gc();
+ continue;
+ }
+ break;
+ case EINVAL:
+ retry = 0;
+ inval = 1;
+ if (toenc) {
+ tocode = RSTRING_PTR(to);
+ rb_str_resize(toenc, 0);
+ toenc = 0;
+ continue;
+ }
+ if (fromenc) {
+ fromcode = RSTRING_PTR(from);
+ rb_str_resize(fromenc, 0);
+ fromenc = 0;
+ continue;
+ }
+ break;
}
- if (cd == (iconv_t)-1) {
- int inval = errno == EINVAL;
+ {
const char *s = inval ? "invalid encoding " : "iconv";
- volatile VALUE msg = rb_str_new(0, strlen(s) + RSTRING_LEN(to) +
- RSTRING_LEN(from) + 8);
+ VALUE error = rb_str_new2(inval ? "invalid encoding " : "iconv");
+ VALUE format = rb_str_new2("%s(\"%s\", \"%s\")");
+ VALUE format_args = rb_ary_new3(3, error, to, from);
+ VALUE msg = rb_str_format(RARRAY_LEN(format_args),
+ RARRAY_PTR(format_args), format);
- sprintf(RSTRING_PTR(msg), "%s(\"%s\", \"%s\")",
- s, RSTRING_PTR(to), RSTRING_PTR(from));
s = RSTRING_PTR(msg);
- rb_str_set_len(msg, strlen(s));
- if (!inval) rb_sys_fail(s);
- iconv_fail(rb_eIconvInvalidEncoding,
- Qnil, rb_ary_new3(2, to, from), NULL, s);
+ if (!inval) {
+ rb_sys_fail(s);
+ }
+ rb_exc_raise(iconv_fail(rb_eIconvInvalidEncoding, Qnil,
+ rb_ary_new3(2, to, from), NULL, s));
}
}
+ if (toopt || fromopt) {
+ if (toopt && fromopt && RTEST(rb_str_equal(toopt, fromopt))) {
+ fromopt = 0;
+ }
+ if (toopt && fromopt) {
+ rb_warning("encoding option isn't portable: %s, %s",
+ RSTRING_PTR(toopt) + 2, RSTRING_PTR(fromopt) + 2);
+ }
+ else {
+ rb_warning("encoding option isn't portable: %s",
+ (toopt ? RSTRING_PTR(toopt) : RSTRING_PTR(fromopt)) + 2);
+ }
+ }
+
if (opt) {
#ifdef ICONV_SET_TRANSLITERATE
if (opt->transliterate != Qundef) {
int flag = RTEST(opt->transliterate);
+ rb_warning("encoding option isn't portable: transliterate");
if (iconvctl(cd, ICONV_SET_TRANSLITERATE, (void *)&flag))
rb_sys_fail("ICONV_SET_TRANSLITERATE");
}
@@ -196,6 +281,7 @@
#ifdef ICONV_SET_DISCARD_ILSEQ
if (opt->discard_ilseq != Qundef) {
int flag = RTEST(opt->discard_ilseq);
+ rb_warning("encoding option isn't portable: discard_ilseq");
if (iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, (void *)&flag))
rb_sys_fail("ICONV_SET_DISCARD_ILSEQ");
}
@@ -275,7 +361,8 @@
static VALUE
iconv_failure_initialize(VALUE error, VALUE mesg, VALUE success, VALUE failed)
{
- rb_call_super(1, &mesg);
+ rb_vm_call_super(error, sel_registerName("initialize:"), 1, &mesg);
+ //rb_call_super(1, &mesg);
rb_ivar_set(error, rb_success, success);
rb_ivar_set(error, rb_failed, failed);
return error;
@@ -305,14 +392,20 @@
args[2] = rb_ary_new4(env->argc, env->argv);
}
}
- error = rb_class_new_instance(3, args, error);
+ return rb_class_new_instance(3, args, error);
+}
+
+static VALUE
+iconv_fail_retry(VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg)
+{
+ error = iconv_fail(error, success, failed, env, mesg);
if (!rb_block_given_p()) rb_exc_raise(error);
rb_set_errinfo(error);
return rb_yield(failed);
}
static VALUE
-rb_str_derive(VALUE str, const char* ptr, int len)
+rb_str_derive(VALUE str, const char* ptr, long len)
{
VALUE ret;
@@ -327,7 +420,7 @@
}
static VALUE
-iconv_convert(iconv_t cd, VALUE str, int start, int length, int toidx, struct iconv_env_t* env)
+iconv_convert(iconv_t cd, VALUE str, long start, long length, int toidx, struct iconv_env_t* env)
{
VALUE ret = Qfalse;
VALUE error = Qfalse;
@@ -351,7 +444,7 @@
error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
if (RTEST(error)) {
unsigned int i;
- rescue = iconv_fail(error, Qnil, Qnil, env, 0);
+ rescue = iconv_fail_retry(error, Qnil, Qnil, env, 0);
if (TYPE(rescue) == T_ARRAY) {
str = RARRAY_LEN(rescue) > 0 ? RARRAY_AT(rescue, 0) : Qnil;
}
@@ -368,23 +461,15 @@
length = 0;
}
else {
- int slen;
+ long slen;
StringValue(str);
slen = RSTRING_LEN(str);
inptr = RSTRING_PTR(str);
- if (start < 0 ? (start += slen) < 0 : start >= slen)
- length = 0;
- else if (length < 0 && (length += slen + 1) < 0)
- length = 0;
- else if ((length -= start) < 0)
- length = 0;
- else {
- inptr += start;
- if (length > slen)
- length = slen;
- }
+ inptr += start;
+ if (length < 0 || length > start + slen)
+ length = slen - start;
}
instart = inptr;
inlen = length;
@@ -398,11 +483,15 @@
errmsg[0] = 0;
error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
- if (0 <= outlen && outlen <= sizeof(buffer)) {
+ if (
+#if SIGNEDNESS_OF_SIZE_T < 0
+ 0 <= outlen &&
+#endif
+ outlen <= sizeof(buffer)) {
outlen = sizeof(buffer) - outlen;
if (NIL_P(error) || /* something converted */
- outlen > inptr - tmpstart || /* input can't contain output */
- (outlen < inptr - tmpstart && inlen > 0) || /* something skipped */
+ outlen > (size_t)(inptr - tmpstart) || /* input can't contain output */
+ (outlen < (size_t)(inptr - tmpstart) && inlen > 0) || /* something skipped */
memcmp(buffer, tmpstart, outlen)) /* something differs */
{
if (NIL_P(str)) {
@@ -443,7 +532,7 @@
rb_str_cat(ret, instart, inptr - instart);
}
str = rb_str_derive(str, inptr, inlen);
- rescue = iconv_fail(error, ret, str, env, errmsg);
+ rescue = iconv_fail_retry(error, ret, str, env, errmsg);
if (TYPE(rescue) == T_ARRAY) {
if ((len = RARRAY_LEN(rescue)) > 0)
rb_str_concat(ret, RARRAY_AT(rescue, 0));
@@ -552,7 +641,7 @@
*
* Creates new code converter from a coding-system designated with +from+
* to another one designated with +to+.
- *
+ *
* === Parameters
*
* +to+:: encoding name for destination
@@ -577,7 +666,7 @@
iconv_free(check_iconv(self));
DATA_PTR(self) = NULL;
DATA_PTR(self) = (void *)ICONV2VALUE(iconv_create(to, from, &opt, &idx));
- if (idx >= 0) ENCODING_SET(self, idx);
+ if (idx >= 0) rb_enc_set_index(self, idx);
return self;
}
@@ -601,7 +690,7 @@
cd = ICONV2VALUE(iconv_create(to, from, &opt, &idx));
self = Data_Wrap_Struct(self, NULL, ICONV_FREE, (void *)cd);
- if (idx >= 0) ENCODING_SET(self, idx);
+ if (idx >= 0) rb_enc_set_index(self, idx);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, self, (VALUE(*)())iconv_finish, self);
@@ -732,6 +821,7 @@
}
#endif
+#if defined(HAVE_ICONVLIST) || defined(HAVE___ICONV_FREE_LIST)
static VALUE
iconv_s_list(void)
{
@@ -762,11 +852,12 @@
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AT(ary, i));
}
-#else
- rb_notimplement();
#endif
return Qnil;
}
+#else
+#define iconv_s_list rb_f_notimplement
+#endif
/*
* Document-method: close
@@ -784,7 +875,7 @@
{
iconv_t cd = VALUE2ICONV((VALUE)DATA_PTR(self));
DATA_PTR(self) = NULL;
- return iconv_convert(cd, Qnil, 0, 0, ENCODING_GET(self), NULL);
+ return iconv_convert(cd, Qnil, 0, 0, rb_enc_get_index(self), NULL);
}
static VALUE
@@ -828,16 +919,32 @@
{
VALUE str, n1, n2;
VALUE cd = check_iconv(self);
+ long start = 0, length = 0, slen = 0;
- n1 = n2 = Qnil;
rb_scan_args(argc, argv, "12", &str, &n1, &n2);
+ if (!NIL_P(str)) {
+ VALUE n = rb_str_length(StringValue(str));
+ slen = NUM2LONG(n);
- str = iconv_convert(VALUE2ICONV(cd), str,
- NIL_P(n1) ? 0 : NUM2INT(n1),
- NIL_P(n2) ? -1 : NUM2INT(n2),
- ENCODING_GET(self),
- NULL);
- return str;
+ if (!NIL_P(n1)) {
+ start = NUM2LONG(n1);
+ if (start < 0) {
+ start += slen;
+ }
+ if (start < 0) {
+ return rb_str_new2("");
+ }
+ }
+ if (!NIL_P(n2)) {
+ length = NUM2LONG(n2);
+ }
+ if (NIL_P(n2) || length < 0) {
+ length = slen;
+ }
+ str = rb_str_subseq(str, start, length);
+ }
+
+ return iconv_convert(VALUE2ICONV(cd), str, 0, -1, rb_enc_get_index(self), NULL);
}
/*
@@ -853,7 +960,7 @@
{
iconv_t cd = VALUE2ICONV(check_iconv(self));
VALUE str, s;
- int toidx = ENCODING_GET(self);
+ int toidx = rb_enc_get_index(self);
str = iconv_convert(cd, Qnil, 0, 0, toidx, NULL);
if (argc > 0) {
@@ -870,6 +977,7 @@
return str;
}
+#ifdef ICONV_TRIVIALP
/*
* Document-method: trivial?
* call-seq: trivial?
@@ -879,16 +987,16 @@
static VALUE
iconv_trivialp(VALUE self)
{
-#ifdef ICONV_TRIVIALP
int trivial = 0;
iconv_ctl(self, ICONV_TRIVIALP, trivial);
if (trivial) return Qtrue;
+ return Qfalse;
+}
#else
- rb_notimplement();
+#define iconv_trivialp rb_f_notimplement
#endif
- return Qfalse;
-}
+#ifdef ICONV_GET_TRANSLITERATE
/*
* Document-method: transliterate?
* call-seq: transliterate?
@@ -898,16 +1006,16 @@
static VALUE
iconv_get_transliterate(VALUE self)
{
-#ifdef ICONV_GET_TRANSLITERATE
int trans = 0;
iconv_ctl(self, ICONV_GET_TRANSLITERATE, trans);
if (trans) return Qtrue;
+ return Qfalse;
+}
#else
- rb_notimplement();
+#define iconv_get_transliterate rb_f_notimplement
#endif
- return Qfalse;
-}
+#ifdef ICONV_SET_TRANSLITERATE
/*
* Document-method: transliterate=
* call-seq: cd.transliterate = flag
@@ -917,15 +1025,15 @@
static VALUE
iconv_set_transliterate(VALUE self, VALUE transliterate)
{
-#ifdef ICONV_SET_TRANSLITERATE
int trans = RTEST(transliterate);
iconv_ctl(self, ICONV_SET_TRANSLITERATE, trans);
+ return self;
+}
#else
- rb_notimplement();
+#define iconv_set_transliterate rb_f_notimplement
#endif
- return self;
-}
+#ifdef ICONV_GET_DISCARD_ILSEQ
/*
* Document-method: discard_ilseq?
* call-seq: discard_ilseq?
@@ -935,16 +1043,16 @@
static VALUE
iconv_get_discard_ilseq(VALUE self)
{
-#ifdef ICONV_GET_DISCARD_ILSEQ
int dis = 0;
iconv_ctl(self, ICONV_GET_DISCARD_ILSEQ, dis);
if (dis) return Qtrue;
+ return Qfalse;
+}
#else
- rb_notimplement();
+#define iconv_get_discard_ilseq rb_f_notimplement
#endif
- return Qfalse;
-}
+#ifdef ICONV_SET_DISCARD_ILSEQ
/*
* Document-method: discard_ilseq=
* call-seq: cd.discard_ilseq = flag
@@ -954,14 +1062,13 @@
static VALUE
iconv_set_discard_ilseq(VALUE self, VALUE discard_ilseq)
{
-#ifdef ICONV_SET_DISCARD_ILSEQ
int dis = RTEST(discard_ilseq);
iconv_ctl(self, ICONV_SET_DISCARD_ILSEQ, dis);
+ return self;
+}
#else
- rb_notimplement();
+#define iconv_set_discard_ilseq rb_f_notimplement
#endif
- return self;
-}
/*
* Document-method: ctlmethods
@@ -1017,7 +1124,7 @@
* call-seq: failed
*
* Returns substring of the original string passed to Iconv that starts at the
- * character caused the exception.
+ * character caused the exception.
*/
static VALUE
iconv_failure_failed(VALUE self)
@@ -1034,7 +1141,7 @@
static VALUE
iconv_failure_inspect(VALUE self)
{
- char *cname = rb_class2name(CLASS_OF(self));
+ const char *cname = rb_class2name(CLASS_OF(self));
VALUE success = rb_attr_get(self, rb_success);
VALUE failed = rb_attr_get(self, rb_failed);
VALUE str = rb_str_buf_cat2(rb_str_new2("#<"), cname);
@@ -1047,13 +1154,13 @@
/*
* Document-class: Iconv::InvalidEncoding
- *
+ *
* Requested coding-system is not available on this system.
*/
/*
* Document-class: Iconv::IllegalSequence
- *
+ *
* Input conversion stopped due to an input byte that does not belong to
* the input codeset, or the output codeset does not contain the
* character.
@@ -1061,20 +1168,20 @@
/*
* Document-class: Iconv::InvalidCharacter
- *
+ *
* Input conversion stopped due to an incomplete character or shift
* sequence at the end of the input buffer.
*/
/*
* Document-class: Iconv::OutOfRange
- *
+ *
* Iconv library internal error. Must not occur.
*/
/*
* Document-class: Iconv::BrokenLibrary
- *
+ *
* Detected a bug of underlying iconv(3) libray.
* * returns an error without setting errno properly
*/
@@ -1122,8 +1229,8 @@
id_transliterate = rb_intern("transliterate");
id_discard_ilseq = rb_intern("discard_ilseq");
- rb_gc_register_address(&charset_map);
charset_map = rb_hash_new();
+ GC_RETAIN(charset_map);
rb_define_singleton_method(rb_cIconv, "charset_map", charset_map_get, 0);
}
Deleted: MacRuby/trunk/lib/iconv.rb
===================================================================
--- MacRuby/trunk/lib/iconv.rb 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/lib/iconv.rb 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,57 +0,0 @@
-# MacRuby implementation of iconv.
-#
-# This file is covered by the Ruby license. See COPYING for more details.
-#
-# Copyright (C) 2009-2010, Apple Inc. All rights reserved.
-
-framework 'Foundation'
-
-class Iconv
- # TODO: lots of things... help!
-
- def self.iconv(to, from, str)
- new(from, to).iconv(str)
- end
-
- def initialize(to, from, options=nil)
- @to_enc = ns_encoding(to)
- @from_enc = ns_encoding(from)
- end
-
- def iconv(str, start=0, length=-1)
- # Not sure if it's the right thing to do...
- data = CFStringCreateExternalRepresentation(nil, str, @to_enc, 0)
- if data.nil?
- raise "can't retrieve data from `#{str}'"
- end
- dest = CFStringCreateFromExternalRepresentation(nil, data, @to_enc)
- if dest.nil?
- raise "can't convert data from `#{str}'"
- end
- CFRelease(data)
- CFRelease(dest)
- dest.mutableCopy
- end
-
- private
-
- ENCS = {}
- def ns_encoding(str)
- if ENCS.empty?
- # Build database.
- ptr = CFStringGetListOfAvailableEncodings()
- i = 0
- while (enc = ptr[i]) != KCFStringEncodingInvalidId
- enc_name = CFStringConvertEncodingToIANACharSetName(enc)
- ENCS[enc_name] = enc
- i += 1
- end
- end
- str = str.downcase
- enc = ENCS[str]
- if enc.nil?
- raise "unrecognized encoding `#{enc}'"
- end
- return enc
- end
-end
Modified: MacRuby/trunk/rakelib/builder/builder.rb
===================================================================
--- MacRuby/trunk/rakelib/builder/builder.rb 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/rakelib/builder/builder.rb 2010-08-09 23:08:00 UTC (rev 4416)
@@ -2,7 +2,7 @@
EXTENSIONS = %w{
ripper digest etc readline libyaml fcntl socket zlib bigdecimal openssl json
- nkf
+ nkf iconv
}.sort
class Builder
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/charset_map_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/charset_map_tags.txt 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/charset_map_tags.txt 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,2 +0,0 @@
-fails:Iconv.charset_map acts as a map
-fails:Iconv.charset_map returns nil when given an unknown encoding name
Modified: MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/close_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/close_tags.txt 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/close_tags.txt 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,3 +1 @@
-fails:Iconv#close ignores multiple calls
-fails:Iconv#close does not raise an exception if called inside an .open block
fails:Iconv#close returns a string containing the byte sequence to change the output buffer to its initial shift state
Modified: MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/conv_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/conv_tags.txt 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/conv_tags.txt 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,3 +1 @@
-fails:Iconv.conv raises a TypeError when encoding names are not Strings or string-compatible
-fails:Iconv.conv raises an Iconv::InvalidEncoding exception when an encoding cannot be found
fails:Iconv.conv acts exactly as if opening a converter and invoking #iconv once
Modified: MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/failure_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/failure_tags.txt 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/failure_tags.txt 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,6 +1 @@
fails:Iconv::Failure is a module
-fails:Iconv::Failure is included by Iconv::InvalidEncoding
-fails:Iconv::Failure is included by Iconv::IllegalSequence
-fails:Iconv::Failure is included by Iconv::InvalidCharacter
-fails:Iconv::Failure is included by Iconv::OutOfRange
-fails:Iconv::Failure is included by Iconv::BrokenLibrary
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/iconv_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/iconv_tags.txt 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/iconv_tags.txt 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,23 +0,0 @@
-fails:Iconv#iconv raises an ArgumentError when called on a closed converter
-fails:Iconv#iconv when given a string or string-like parameter returns a converted version of it
-fails:Iconv#iconv keeps context between calls
-fails:Iconv#iconv when given a negative start position counts from the end of string
-fails:Iconv#iconv when the end parameter is omitted or nil goes until the end of the string
-fails:Iconv#iconv when given a positive length
-fails:Iconv#iconv when given a negative length
-fails:Iconv#iconv raises Iconv::IllegalSequence when faced with an invalid byte for the source encoding
-fails:Iconv#iconv raises Iconv::IllegalSequence when a character cannot be represented on the target encoding
-fails:Iconv#iconv raises Iconv::InvalidCharacter when an incomplete character or shift sequence happens at the end of the input buffer
-fails:Iconv#iconv sanitizes invalid upper bounds
-fails:Iconv#iconv returns a blank string on invalid lower bounds
-fails:Iconv.iconv converts a series of strings with a single converter
-fails:Iconv.iconv returns an empty array when given no strings to convert
-fails:Iconv.iconv raises a TypeError when encoding names are not Strings or string-compatible
-fails:Iconv.iconv raises an Iconv::InvalidEncoding exception when an encoding cannot be found
-fails:The 'utf-8' encoder emits proper representations for characters outside the Basic Multilingual Plane
-fails:The 'utf-16' encoder emits an empty string when the source input is empty
-fails:The 'utf-16' encoder emits a byte-order mark on first non-empty output
-fails:The 'utf-16be' decoder does not emit a byte-order mark
-fails:The 'utf-16be' decoder treats possible byte-order marks as regular characters
-fails:The 'utf-16le' decoder does not emit a byte-order mark
-fails:The 'utf-16le' decoder treats possible byte-order marks as regular characters
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/new_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/new_tags.txt 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/new_tags.txt 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,4 +0,0 @@
-fails:Iconv.new creates a new encoding converter
-fails:Iconv.new when called from a subclass of Iconv instantiates an object of that class
-fails:Iconv.new raises a TypeError when encoding names are not Strings or string-compatible
-fails:Iconv.new raises an Iconv::InvalidEncoding exception when an encoding cannot be found
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/open_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/open_tags.txt 2010-08-06 23:48:44 UTC (rev 4415)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/iconv/open_tags.txt 2010-08-09 23:08:00 UTC (rev 4416)
@@ -1,6 +0,0 @@
-fails:Iconv.open creates a new encoding converter
-fails:Iconv.open when called from a subclass of Iconv instantiates an object of that class
-fails:Iconv.open raises an Iconv::InvalidEncoding exception when an encoding cannot be found
-fails:Iconv.open with a block invokes the block exactly once
-fails:Iconv.open with a block yields the converter
-fails:Iconv.open with a block returns the result of the block
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100809/c443af37/attachment-0001.html>
More information about the macruby-changes
mailing list