79 #define VALUE2ICONV(v) ((iconv_t)((VALUE)(v) ^ -1))
80 #define ICONV2VALUE(c) ((VALUE)(c) ^ -1)
117 static VALUE iconv_try _((iconv_t
cd,
const char **inptr,
size_t *inlen,
char **outptr,
size_t *outlen));
150 const char *slash = memchr(ptr,
'/', pend - ptr);
152 if (slash && slash < pend - 1 && slash[1] ==
'/') {
187 #define rb_sys_fail(s) rb_iconv_sys_fail(s)
194 VALUE toenc = 0, fromenc = 0;
210 while ((cd = iconv_open(tocode, fromcode)) == (iconv_t)-1) {
239 const char *s = inval ?
"invalid encoding " :
"iconv";
253 if (toopt || fromopt) {
257 if (toopt && fromopt) {
258 rb_warning(
"encoding option isn't portable: %s, %s",
262 rb_warning(
"encoding option isn't portable: %s",
268 #ifdef ICONV_SET_TRANSLITERATE
271 rb_warning(
"encoding option isn't portable: transliterate");
272 if (iconvctl(cd, ICONV_SET_TRANSLITERATE, (
void *)&flag))
276 #ifdef ICONV_SET_DISCARD_ILSEQ
279 rb_warning(
"encoding option isn't portable: discard_ilseq");
280 if (iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, (
void *)&flag))
295 #define ICONV_FREE iconv_dfree
316 iconv_try(iconv_t
cd,
const char **inptr,
size_t *inlen,
char **outptr,
size_t *outlen)
318 #ifdef ICONV_INPTR_CONST
319 #define ICONV_INPTR_CAST
321 #define ICONV_INPTR_CAST (char **)
327 if (ret == (
size_t)-1) {
344 else if (*inlen > 0) {
354 #define FAILED_MAXLEN 16
385 *(env->
argv) = failed;
395 error =
iconv_fail(error, success, failed, env, mesg);
422 const char *inptr, *instart;
429 if (cd == (iconv_t)-1)
437 outlen =
sizeof(buffer);
438 error =
iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
449 else if (!
NIL_P(str)) {
465 if (length < 0 || length > start + slen)
466 length = slen - start;
473 const char *tmpstart = inptr;
475 outlen =
sizeof(buffer);
478 error =
iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
481 #
if SIGNEDNESS_OF_SIZE_T < 0
484 outlen <=
sizeof(buffer)) {
485 outlen =
sizeof(buffer) - outlen;
487 outlen > (size_t)(inptr - tmpstart) ||
488 (outlen < (size_t)(inptr - tmpstart) && inlen > 0) ||
489 memcmp(buffer, tmpstart, outlen))
500 ret =
rb_str_new(instart, tmpstart - instart);
509 inptr = tmpstart + outlen;
514 sprintf(errmsg,
"bug?(output length = %ld)", (
long)(
sizeof(buffer) - outlen));
525 else if (inptr > instart) {
540 else if (!
NIL_P(rescue)) {
551 else if (inptr > instart) {
577 #ifdef ICONV_SET_TRANSLITERATE
585 #ifdef ICONV_SET_DISCARD_ILSEQ
595 if (strcmp(s,
"transliterate") == 0) {
596 #ifdef ICONV_SET_TRANSLITERATE
603 if (strcmp(s,
"discard_ilseq") == 0) {
604 #ifdef ICONV_SET_DISCARD_ILSEQ
623 if (!
NIL_P(options)) {
628 #define iconv_ctl(self, func, val) (\
629 iconvctl(VALUE2ICONV(check_iconv(self)), func, (void *)&(val)) ? \
630 rb_sys_fail(#func) : (void)0)
704 0, -1, env->
toidx, env);
705 env->append(env->
ret, s);
711 env->append(env->
ret, s);
743 arg.
argc = argc -= 2;
779 #ifdef HAVE_ICONVLIST
780 struct iconv_name_list
782 unsigned int namescount;
783 const char *
const *
names;
788 list_iconv_i(
VALUE ptr)
790 struct iconv_name_list *
p = (
struct iconv_name_list *)ptr;
791 unsigned int i, namescount = p->namescount;
792 const char *
const *
names = p->names;
795 for (i = 0; i < namescount; i++) {
805 list_iconv(
unsigned int namescount,
const char *
const *names,
void *data)
808 struct iconv_name_list
list;
810 list.namescount = namescount;
818 #if defined(HAVE_ICONVLIST) || defined(HAVE___ICONV_FREE_LIST)
822 #ifdef HAVE_ICONVLIST
827 iconvlist(list_iconv, args);
828 state = *(
int *)args;
830 if (args[1])
return args[1];
831 #elif defined(HAVE___ICONV_FREE_LIST)
836 if (__iconv_get_list(&list, &sz))
return Qnil;
839 for (i = 0; i < sz; i++) {
842 __iconv_free_list(list, sz);
853 #define iconv_s_list rb_f_notimplement
880 if (!cd)
return Qnil;
916 long start = 0, length = 0, slen = 0;
924 if (
NIL_P(n1) || ((start =
NUM2LONG(n1)) < 0 ? (start += slen) >= 0 : start < slen)) {
928 if (start > 0 || length > 0) {
933 start = (ps =
rb_enc_nth(s, e, start, enc)) - s;
973 #ifdef ICONV_TRIVIALP
984 iconv_ctl(
self, ICONV_TRIVIALP, trivial);
985 if (trivial)
return Qtrue;
989 #define iconv_trivialp rb_f_notimplement
992 #ifdef ICONV_GET_TRANSLITERATE
1003 iconv_ctl(
self, ICONV_GET_TRANSLITERATE, trans);
1004 if (trans)
return Qtrue;
1008 #define iconv_get_transliterate rb_f_notimplement
1011 #ifdef ICONV_SET_TRANSLITERATE
1022 iconv_ctl(
self, ICONV_SET_TRANSLITERATE, trans);
1026 #define iconv_set_transliterate rb_f_notimplement
1029 #ifdef ICONV_GET_DISCARD_ILSEQ
1040 iconv_ctl(
self, ICONV_GET_DISCARD_ILSEQ, dis);
1041 if (dis)
return Qtrue;
1045 #define iconv_get_discard_ilseq rb_f_notimplement
1048 #ifdef ICONV_SET_DISCARD_ILSEQ
1058 int dis =
RTEST(discard_ilseq);
1059 iconv_ctl(
self, ICONV_SET_DISCARD_ILSEQ, dis);
1063 #define iconv_set_discard_ilseq rb_f_notimplement
1076 #ifdef ICONV_TRIVIALP
1079 #ifdef ICONV_GET_TRANSLITERATE
1082 #ifdef ICONV_SET_TRANSLITERATE
1085 #ifdef ICONV_GET_DISCARD_ILSEQ
1088 #ifdef ICONV_SET_DISCARD_ILSEQ
1185 static const char message[] =
1186 ": iconv will be deprecated in the future, use String#encode instead.\n";
1192 if (strncmp(
RSTRING_PTR(s),
"<internal:", 10) != 0) {
1201 rb_str_cat(msg, message,
sizeof(message) - 1);