da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * iconv intercept
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * minimally provides { utf*<=>bin ascii<=>ebcdic* }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <dirent.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG_TRACE 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ICONV_LIST_PRIVATE_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ccode.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ctype.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <iconv.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "lclib.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_lib_iconv_open
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_t iconv_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_f iconv_f
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_list_t iconv_list_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_open iconv_open
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv iconv
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_close iconv_close
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_list iconv_list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_move iconv_move
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_name iconv_name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _ast_iconv_write iconv_write
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef E2BIG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define E2BIG ENOMEM
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef EILSEQ
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define EILSEQ EIO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RETURN(e,n,fn) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*fn && !e) e = E2BIG; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e) { errno = e; return (size_t)(-1); } \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Map_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const unsigned char* map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _ast_iconv_f fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Map_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Conv_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iconv_t cvt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Map_t from;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Map_t to;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Conv_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Conv_t* freelist[4];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int freeindex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char name_local[] = "local";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char name_native[] = "native";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const _ast_iconv_list_t codes[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "utf",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "un|unicode|utf",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "multibyte 8-bit unicode",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "UTF-%s",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "8",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CC_UTF,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "ume",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "um|ume|utf?(-)7",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "multibyte 7-bit unicode",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "UTF-7",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CC_UME,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "euc",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "(big|euc)*",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "euc family",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CC_ICONV,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "dos",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "dos?(-)?(855)",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "dos code page",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "DOS855",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CC_ICONV,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "ucs",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "ucs?(-)?(2)?(be)|utf-16?(be)",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "unicode runes",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "UCS-%s",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "2",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CC_UCS,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "ucs-le",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "ucs?(-)?(2)le|utf-16le",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "little endian unicode runes",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "UCS-%sLE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "2",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CC_SCU,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { 0 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _UWIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast_windows.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef CP_UCS2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CP_UCS2 0x0000
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char _win_maps[] = "/reg/local_machine/SOFTWARE/Classes/MIME/Database/Charset";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the codeset index given its name or alias
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the map is in the what? oh, the registry
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_win_codeset(const char* name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char aka[128];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char tmp[128];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d _win_codeset name=%s", __LINE__, name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (name == name_native)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return CP_ACP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strcasecmp(name, "utf") || !strcasecmp(name, "utf8") || !strcasecmp(name, "utf-8"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return CP_UTF8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strcasecmp(name, "ucs") || !strcasecmp(name, "ucs2") || !strcasecmp(name, "ucs-2"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return CP_UCS2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (name[0] == '0' && name[1] == 'x' && (n = strtol(name, &e, 0)) > 0 && !*e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(tmp, sizeof(tmp), "%s/%s", _win_maps, name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sp = sfopen(0, tmp, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (char*)name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((s[0] == 'c' || s[0] == 'C') && (s[1] == 'p' || s[1] == 'P'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!isdigit(s[0]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(tmp, sizeof(tmp), "%s/windows-%s", _win_maps, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sp = sfopen(0, tmp, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = sfgetr(sp, '\n', 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strncasecmp(s, "AliasForCharSet=", 16))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sfvalue(sp) - 17;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s += 16;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n >= sizeof(aka))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sizeof(aka) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(aka, s, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin aka[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = (const char*)aka;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strncasecmp(s, "CodePage=", 9))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s += 9;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strtol(s, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get and check the codeset indices
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic _ast_iconv_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_win_iconv_open(register Conv_t* cc, const char* t, const char* f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d _win_iconv_open f=%s t=%s\n", __LINE__, f, t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((cc->from.index = _win_codeset(f)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (_ast_iconv_t)(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((cc->to.index = _win_codeset(t)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (_ast_iconv_t)(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d _win_iconv_open f=0x%04x t=0x%04x\n", __LINE__, cc->from.index, cc->to.index);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (_ast_iconv_t)cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * even though the indices already check out
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * they could still be rejected
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_win_iconv(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Conv_t* cc = (Conv_t*)cd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t un;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t tz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t fz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t bz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t pz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t oz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin LPWSTR ub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d _win_iconv from=0x%04x to=0x%04x\n", __LINE__, cc->from.index, cc->to.index);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc->from.index == cc->to.index)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * easy
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fz = tz = (*fn < *tn) ? *fn : *tn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(*tb, *fb, fz);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ub = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin un = *fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * from => ucs-2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc->to.index == CP_UCS2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((tz = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)*fn, (LPWSTR)*tb, *tn)) && tz <= *tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fz = *fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tz *= sizeof(WCHAR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * target too small
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * binary search on input size to make it fit
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oz = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pz = *fn / 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fz = *fn - pz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (!(tz = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)fz, (LPWSTR)*tb, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++fz >= *fn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tz *= sizeof(WCHAR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tz == *tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pz /= 2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fz = oz))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tz > *tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fz -= pz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oz = fz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fz += pz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc->from.index == CP_UCS2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin un = *fn / sizeof(WCHAR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ub = (LPWSTR)*fb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(un = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)*fn, (LPWSTR)*tb, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(ub = (LPWSTR)malloc(un * sizeof(WCHAR))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(un = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)*fn, (LPWSTR)ub, un)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ucs-2 => to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tz = WideCharToMultiByte(cc->to.index, 0, (LPCWSTR)ub, un, *tb, *tn, 0, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fz = *fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * target too small
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * binary search on input size to make it fit
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oz = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pz = *fn / 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bz = *fn - pz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (!(fz = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)bz, (LPWSTR)ub, un)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++bz > *fn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tz = WideCharToMultiByte(cc->to.index, 0, (LPCWSTR)ub, fz, *tb, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tz == *tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pz /= 2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fz = oz))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tz > *tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bz -= pz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oz = bz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bz += pz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tz = WideCharToMultiByte(cc->to.index, 0, (LPCWSTR)ub, fz, *tb, tz, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d _win_iconv *fn=%u fz=%u[%u] *tn=%u tz=%u\n", __LINE__, *fn, fz, fz * sizeof(WCHAR), *tn, tz);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fz *= sizeof(WCHAR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ub != (LPWSTR)*fb)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(ub);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb += fz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= fz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb += tz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= tz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nope:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ub && ub != (LPWSTR)*fb)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(ub);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (size_t)(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return canonical character code set name for m
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if b!=0 then canonical name placed in b of size n
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <ccode.h> index returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_name(register const char* m, register char* b, size_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const _ast_iconv_list_t* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const _ast_iconv_list_t* bp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int sub[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[16];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* o;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sizeof(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o = b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = b + n - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = ccmaplist(NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name m=\"%s\"\n", error_info.id, error_info.trace, __LINE__, m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name n=%d bp=%p cp=%p ccode=%d name=\"%s\"\n", error_info.id, error_info.trace, __LINE__, n, bp, cp, cp->ccode, cp->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strgrpmatch(m, cp->match, sub, elementsof(sub) / 2, STR_MAXIMAL|STR_LEFT|STR_ICASE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = m[sub[1]]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sub[1] > n && !isalpha(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sub[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp->ccode < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(++cp)->name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(cp = (const _ast_iconv_list_t*)ccmaplist((_ast_iconv_list_t*)cp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = codes;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp = bp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp->canon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp->index)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m += sub[1]; *m && !isalnum(*m); m++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!isdigit(*m))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = cp->index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = "1";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += sfsprintf(b, e - b, cp->canon, m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (cp->ccode == CC_NATIVE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((locales[AST_LC_CTYPE]->flags & LC_default) || !locales[AST_LC_CTYPE]->charset || !(m = locales[AST_LC_CTYPE]->charset->code) || streq(m, "iso8859-1"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (CC_NATIVE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_EBCDIC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = (const char*)"EBCDIC";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_EBCDIC_I:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = (const char*)"EBCDIC-I";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_EBCDIC_O:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = (const char*)"EBCDIC-O";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = (const char*)"ISO-8859-1";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += sfsprintf(b, e - b, "%s", m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name ccode=%d canon=\"%s\"\n", error_info.id, error_info.trace, __LINE__, cp->ccode, o);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return cp->ccode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (b < e && (c = *m++))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (islower(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = toupper(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name ccode=%d canon=\"%s\"\n", error_info.id, error_info.trace, __LINE__, CC_ICONV, o);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return CC_ICONV;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert utf-8 to bin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinutf2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (t < te && f < fe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c & 0x80)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c & 0x40))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EILSEQ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c & 0x20)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = (c & 0x0F) << 12;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f >= fe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c & 0x40)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EILSEQ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w |= (c & 0x3F) << 6;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = (c & 0x1F) << 6;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f >= fe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w |= (c & 0x3F);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (char*)f - (*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (n = (char*)t - (*tb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert bin to utf-8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbin2utf(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wchar_t w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < fe && t < te)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = *f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(w & ~0x7F))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(w & ~0x7FF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t >= (te - 2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = E2BIG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = 0xC0 + (w >> 6);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(w & ~0xffff))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t >= (te - 3))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = E2BIG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = 0xE0 + (w >> 12);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = 0x80 + ((w >> 6 ) & 0x3F);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EILSEQ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = 0x80 + (w & 0x3F);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (n = (char*)f - (*fb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (char*)t - (*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const unsigned char ume_D[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?!\"#$%&*;<=>@[]^_`{|} \t\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const unsigned char ume_M[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic unsigned char ume_d[UCHAR_MAX+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic unsigned char ume_m[UCHAR_MAX+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NOE 0xFF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define UMEINIT() (ume_d[ume_D[0]]?0:umeinit())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize the ume tables
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinumeinit(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const unsigned char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ume_d[ume_D[0]])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = ume_D;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ume_d[c] = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(ume_m, NOE, sizeof(ume_m));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; c = ume_M[i]; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ume_m[c] = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert utf-7 to bin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinume2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin UMEINIT();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < fe && t < te)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '-' && s > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((w = ume_m[c]) == NOE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (f >= (fe - 2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = (w << 6) | ume_m[*f++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = (w << 6) | ume_m[*f++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(w & ~0xFF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (t >= (te - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = E2BIG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = (w >> 8) & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (char*)f - (*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (n = (char*)t - (*tb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert bin to utf-7
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbin2ume(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wchar_t w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin UMEINIT();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < fe && t < (te - s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = *f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(w & ~0x7F) && ume_d[w])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '-';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (t >= (te - (4 + s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = E2BIG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '+';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = ume_M[(w >> 12) & 0x3F];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = ume_M[(w >> 6) & 0x3F];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = ume_M[w & 0x3F];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '-';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (n = (char*)f - (*fb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (char*)t - (*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert ucs-2 to bin with no byte swap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinucs2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < (fe - 1) && t < te)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = (w << 8) | *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(w & ~0xFF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (t >= (te - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f -= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = E2BIG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = (w >> 8) & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (char*)f - (*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (n = (char*)t - (*tb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert bin to ucs-2 with no byte swap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbin2ucs(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wchar_t w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < fe && t < (te - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = *f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = (w >> 8) & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (n = (char*)f - (*fb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (char*)t - (*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert ucs-2 to bin with byte swap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinscu2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < (fe - 1) && t < te)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = w | (*f++ << 8);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(w & ~0xFF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (t >= (te - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f -= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = E2BIG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = (w >> 8) & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (char*)f - (*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (n = (char*)t - (*tb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert bin to ucs-2 with byte swap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic size_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbin2scu(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* te;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wchar_t w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe = f + (*fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin te = t + (*tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < fe && t < (te - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = *f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = w & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = (w >> 8) & 0xFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= (n = (char*)f - (*fb));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb = (char*)f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= (char*)t - (*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb = (char*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RETURN(e, n, fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open a character code conversion map from f to t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_open(const char* t, const char* f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Conv_t* cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int tc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char fr[64];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char to[64];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d _ast_iconv_open f=%s t=%s\n", __LINE__, f, t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!t || !*t || *t == '-' && !*(t + 1) || !strcasecmp(t, name_local) || !strcasecmp(t, name_native))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = name_native;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!f || !*f || *f == '-' && !*(f + 1) || !strcasecmp(t, name_local) || !strcasecmp(f, name_native))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = name_native;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the ast identify is always (iconv_t)(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t == f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (iconv_t)(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fc = _ast_iconv_name(f, fr, sizeof(fr));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tc = _ast_iconv_name(t, to, sizeof(to));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d _ast_iconv_open f=%s:%s:%d t=%s:%s:%d\n", __LINE__, f, fr, fc, t, to, tc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fc != CC_ICONV && fc == tc || streq(fr, to))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (iconv_t)(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * first check the free list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < elementsof(freelist); i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((cc = freelist[i]) && streq(to, cc->to.name) && streq(fr, cc->from.name))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin freelist[i] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_iconv_open
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * reset the shift state if any
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc->cvt != (iconv_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iconv(cc->cvt, NiL, NiL, NiL, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * allocate a new one
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cc = newof(0, Conv_t, 1, strlen(to) + strlen(fr) + 2)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (iconv_t)(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->to.name = (char*)(cc + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.name = strcopy(cc->to.name, to) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(cc->from.name, fr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->cvt = (iconv_t)(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 8 bit maps are the easiest
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fc >= 0 && tc >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.map = ccmap(fc, tc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_iconv_open
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((cc->cvt = iconv_open(to, fr)) != (iconv_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.fun = (_ast_iconv_f)iconv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _UWIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((cc->cvt = _win_iconv_open(cc, to, fr)) != (_ast_iconv_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.fun = (_ast_iconv_f)_win_iconv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (fc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_UTF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.fun = utf2bin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_UME:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.fun = ume2bin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_UCS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.fun = ucs2bin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_SCU:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.fun = scu2bin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_ASCII:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fc < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->from.map = ccmap(fc, CC_ASCII);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (tc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_UTF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->to.fun = bin2utf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_UME:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->to.fun = bin2ume;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_UCS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->to.fun = bin2ucs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_SCU:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->to.fun = bin2scu;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CC_ASCII:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tc < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->to.map = ccmap(CC_ASCII, tc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (iconv_t)cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nope:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (iconv_t)(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close a character code conversion map
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_close(_ast_iconv_t cd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Conv_t* cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Conv_t* oc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cd == (_ast_iconv_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cc = (Conv_t*)cd))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add to the free list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = freeindex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++ i >= elementsof(freelist))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!freelist[i])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i == freeindex)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++ i >= elementsof(freelist))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close the oldest
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (oc = freelist[i])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_iconv_open
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (oc->cvt != (iconv_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = iconv_close(oc->cvt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (oc->buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(oc->buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(oc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin freelist[freeindex = i] = cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy *fb size *fn to *tb size *tn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fb,fn tb,tn updated on return
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Conv_t* cc = (Conv_t*)cd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const unsigned char* m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* tfb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t tfn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fb || !*fb)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* TODO: reset to the initial state */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!tb || !*tb)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* TODO: write the initial state shift sequence */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *tn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc->from.fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc->to.fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cc->buf && !(cc->buf = oldof(0, char, cc->size = SF_BUFSIZE, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOMEM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = cc->buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = cc->size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tfb = *fb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tfn = *fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*cc->from.fun)(cc->cvt, &tfb, &tfn, &b, &i) == (size_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tfn = b - cc->buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tfb = cc->buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (*cc->to.fun)(cc->cvt, &tfb, &tfn, tb, tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = tfb - cc->buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb += i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*cc->from.fun)(cc->cvt, fb, fn, tb, tn) == (size_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n -= *tn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m = cc->to.map)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (t = e - n; t < e; t++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t = m[*t];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (cc->to.fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(m = cc->from.map))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (*cc->to.fun)(cc->cvt, fb, fn, tb, tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cc->buf && !(cc->buf = oldof(0, char, cc->size = SF_BUFSIZE, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOMEM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((n = *fn) > cc->size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = cc->size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = f + n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(b = cc->buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = m[*f++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (*cc->to.fun)(cc->cvt, &b, fn, tb, tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb += b - cc->buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n > *fn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc && (m = cc->from.map))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (unsigned char*)(*fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = f + n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (unsigned char*)(*tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (f < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = m[*f++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(*tb, *fb, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fb += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fn -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tb += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tn -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * write *fb size *fn to op
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fb,fn updated on return
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * total bytes written to op returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_write(_ast_iconv_t cd, Sfio_t* op, char** fb, size_t* fn, size_t* e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* tb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* ts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t tn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tn = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*fn > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tb = (char*)sfreserve(op, -(tn + 1), SF_WRITE|SF_LOCKR)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r ? r : -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ts = tb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tn = sfvalue(op);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d iconv_write ts=%p tn=%d", __LINE__, ts, tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (_ast_iconv(cd, fb, fn, &ts, &tn) == (size_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ssize_t _r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d iconv_write %d => %d `%-.*s'", __LINE__, *fn, tn, *fn, *fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _r = _ast_iconv(cd, fb, fn, &ts, &tn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d iconv_write %d => %d [%d]", __LINE__, *fn, tn, _r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (_r != (size_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (errno == E2BIG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*e)++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!tn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ts++ = *(*fb)++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tn--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fn)--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG_TRACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerror(DEBUG_TRACE, "AHA#%d iconv_write %d", __LINE__, ts - tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(op, tb, ts - tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r += ts - tb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * move n bytes from ip to op
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_move(_ast_iconv_t cd, Sfio_t* ip, Sfio_t* op, size_t n, size_t* e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* fb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* fs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* tb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* ts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t fo;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t tn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ssize_t r = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int locked;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fn != SF_UNBOUND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn = -((ssize_t)(fn & (((size_t)(~0))>>1)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fb = (char*)sfreserve(ip, fn, locked = SF_LOCKR)) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin !(fb = (char*)sfreserve(ip, fn, locked = 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fs = fb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn = fo = sfvalue(ip);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tb = (char*)sfreserve(op, SF_UNBOUND, SF_WRITE|SF_LOCKR)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfread(ip, fb, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r ? r : -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ts = tb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tn = sfvalue(op);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (_ast_iconv(cd, &fs, &fn, &ts, &tn) != (size_t)(-1) && fn > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tn > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ts++ = '_';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tn--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*e)++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fs++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(op, tb, ts - tb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r += ts - tb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (locked)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfread(ip, fb, fs - fb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = fn; --i >= (fs - fb);)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfungetc(ip, fb[i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n != SF_UNBOUND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n <= (fs - fb))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n -= fs - fb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fn == fo)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * iconv_list_t iterator
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * call with arg 0 to start
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * prev return value is current arg
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_list_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_ast_iconv_list(_ast_iconv_list_t* cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _UWIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct dirent* ent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp = newof(0, _ast_iconv_list_t, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ccmaplist(NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cp->data = opendir(_win_maps)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ccmaplist(NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp->data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ent = readdir((DIR*)cp->data))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp->name = cp->match = cp->desc = (const char*)ent->d_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin closedir((DIR*)cp->data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ccmaplist(NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ccmaplist(NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp->ccode >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (cp = ccmaplist(cp)) ? cp : (_ast_iconv_list_t*)codes;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (++cp)->name ? cp : (_ast_iconv_list_t*)0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}