#define _KANJI_C_
#include "includes.h"
#ifdef USES_CFSTRING
int global_CFString_Encoding = kCFStringEncodingDOSLatin1;
int ConvertEncodingToUTF8(const char* inCStr, char* outUTF8Buffer, int outUTF8BufferLength, unsigned long scriptEncoding, unsigned long flags);
int ConvertUTF8ToEncoding(const char* inUTF8Buf, int inUTF8BufLength, char* outCStrBuffer, int outCStrBufferLength, unsigned long scriptEncoding, unsigned long flags);
#endif
const char *(*multibyte_strchr)(const char *, int ) = (const char *(*)(const char *, int )) strchr;
const char *(*multibyte_strrchr)(const char *, int ) = (const char *(*)(const char *, int )) strrchr;
const char *(*multibyte_strstr)(const char *, const char *) = (const char *(*)(const char *, const char *)) strstr;
char *(*multibyte_strtok)(char *, const char *) = (char *(*)(char *, const char *)) strtok;
#ifndef KANJI
static size_t skip_non_multibyte_char(char);
static BOOL not_multibyte_char_1(char);
char *(*_dos_to_unix)(char *, BOOL) = dos2unix_format;
char *(*_unix_to_dos)(char *, BOOL) = unix2dos_format;
size_t (*_skip_multibyte_char)(char) = skip_non_multibyte_char;
BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1;
#else
static char *sj_to_sj(char *from, BOOL overwrite);
static size_t skip_kanji_multibyte_char(char);
static BOOL is_kanji_multibyte_char_1(char);
char *(*_dos_to_unix)(char *, BOOL) = sj_to_sj;
char *(*_unix_to_dos)(char *, BOOL) = sj_to_sj;
size_t (*_skip_multibyte_char)(char) = skip_kanji_multibyte_char;
int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
#endif
BOOL global_is_multibyte_codepage = False;
static char jis_kso = JIS_KSO;
static char jis_ksi = JIS_KSI;
static char hex_tag = HEXTAG;
static char *sj_strtok(char *s1, const char *s2)
{
static char *s = NULL;
char *q;
if (!s1) {
if (!s) {
return NULL;
}
s1 = s;
}
for (q = s1; *s1; ) {
if (is_shift_jis (*s1)) {
s1 += 2;
} else if (is_kana (*s1)) {
s1++;
} else {
char *p = strchr (s2, *s1);
if (p) {
if (s1 != q) {
s = s1 + 1;
*s1 = '\0';
return q;
}
q = s1 + 1;
}
s1++;
}
}
s = NULL;
if (*q) {
return q;
}
return NULL;
}
static const char *sj_strstr(const char *s1, const char *s2)
{
size_t len = strlen (s2);
if (!*s2)
return (const char *) s1;
for (;*s1;) {
if (*s1 == *s2) {
if (strncmp (s1, s2, len) == 0)
return (const char *) s1;
}
if (is_shift_jis (*s1)) {
s1 += 2;
} else {
s1++;
}
}
return NULL;
}
static const char *sj_strchr (const char *s, int c)
{
for (; *s; ) {
if (*s == c)
return (const char *) s;
if (is_shift_jis (*s)) {
s += 2;
} else {
s++;
}
}
return NULL;
}
static const char *sj_strrchr(const char *s, int c)
{
const char *q;
for (q = 0; *s; ) {
if (*s == c) {
q = (const char *) s;
}
if (is_shift_jis (*s)) {
s += 2;
} else {
s++;
}
}
return q;
}
static size_t skip_kanji_multibyte_char(char c)
{
if(is_shift_jis(c)) {
return 2;
} else if (is_kana(c)) {
return 1;
}
return 0;
}
static BOOL is_kanji_multibyte_char_1(char c)
{
return is_shift_jis(c);
}
static BOOL hangul_is_multibyte_char_1(char c)
{
return is_hangul(c);
}
static BOOL big5_is_multibyte_char_1(char c)
{
return is_big5_c1(c);
}
static BOOL simpch_is_multibyte_char_1(char c)
{
return is_simpch_c1(c);
}
static char *generic_multibyte_strtok(char *s1, const char *s2)
{
static char *s = NULL;
char *q;
if (!s1) {
if (!s) {
return NULL;
}
s1 = s;
}
for (q = s1; *s1; ) {
if ((*is_multibyte_char_1)(*s1)) {
s1 += 2;
} else {
char *p = strchr (s2, *s1);
if (p) {
if (s1 != q) {
s = s1 + 1;
*s1 = '\0';
return q;
}
q = s1 + 1;
}
s1++;
}
}
s = NULL;
if (*q) {
return q;
}
return NULL;
}
static const char *generic_multibyte_strstr(const char *s1, const char *s2)
{
size_t len = strlen (s2);
if (!*s2)
return (const char *) s1;
for (;*s1;) {
if (*s1 == *s2) {
if (strncmp (s1, s2, len) == 0)
return (const char *) s1;
}
if ((*is_multibyte_char_1)(*s1)) {
s1 += 2;
} else {
s1++;
}
}
return NULL;
}
static const char *generic_multibyte_strchr(const char *s, int c)
{
for (; *s; ) {
if (*s == c)
return (const char *) s;
if ((*is_multibyte_char_1)(*s)) {
s += 2;
} else {
s++;
}
}
return NULL;
}
static const char *generic_multibyte_strrchr(const char *s, int c)
{
const char *q;
for (q = 0; *s; ) {
if (*s == c) {
q = (const char *) s;
}
if ((*is_multibyte_char_1)(*s)) {
s += 2;
} else {
s++;
}
}
return q;
}
static size_t skip_generic_multibyte_char(char c)
{
if( (*is_multibyte_char_1)(c)) {
return 2;
}
return 0;
}
static char cvtbuf[2*sizeof(pstring)];
#ifdef USES_CFSTRING
static smb_ucs2_t ucs2Str[1024];
#endif
static int euc2sjis (int hi, int lo)
{
int w;
int maxidx = SJISREVTBLSIZ;
int minidx = 0;
int i = 2;
if (hi & 1) {
hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
w = (hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61));
} else {
hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
w = (hi << 8) | (lo - 2);
}
if ( (0x87 < hi ) && (hi < 0xed ) ) {
return w;
}
while ( maxidx >= minidx ) {
if ( sjisrev[i].start > w ) {
maxidx = i-1;
} else if ( w > sjisrev[i].end ) {
minidx = i+1;
} else {
w -= sjisrev[i].start;
w += sjisrev[i].rstart;
break;
}
i = (int)( minidx + (maxidx - minidx) % 2 );
}
return w;
}
static int sjis2euc (int hi, int lo)
{
int minidx = 0;
int maxidx = SJISCONVTBLSIZ -1;
int i = ( 0 + SJISCONVTBLSIZ ) % 2;
int w = (int)((hi << 8) | lo);
if ( (sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end) ) {
while (maxidx >= minidx) {
if ( sjisconv[i].start > w ) {
maxidx = i-1;
} else if (w > sjisconv[i].end) {
minidx = i+1;
} else {
w -= sjisconv[i].start;
w += sjisconv[i].rstart;
break;
}
i = (int)( minidx + (maxidx-minidx)%2 );
}
hi = (int) ((w >> 8) & 0xff);
lo = (int) (w & 0xff);
}
if (hi >= 0xf0) {
hi = GETAHI;
lo = GETALO;
}
if (lo >= 0x9f)
return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
else
return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
(lo + (lo >= 0x7f ? 0x60 : 0x61));
}
static char *sj_to_euc(char *from, BOOL overwrite)
{
char *out;
char *save;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_shift_jis (*from)) {
int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code & 0xff;
from += 2;
} else if (is_kana (*from)) {
*out++ = (char)euc_kana;
*out++ = *from++;
} else {
*out++ = *from++;
}
}
*out = 0;
if (overwrite) {
pstrcpy((char *) save, (char *) cvtbuf);
return (char *) save;
} else {
return cvtbuf;
}
}
static char *euc_to_sj(char *from, BOOL overwrite)
{
char *out;
char *save;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
if (is_euc (*from)) {
int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code & 0xff;
from += 2;
} else if (is_euc_kana (*from)) {
*out++ = from[1];
from += 2;
} else {
*out++ = *from++;
}
}
*out = 0;
if (overwrite) {
pstrcpy(save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static int sjis3euc (int hi, int lo, int *len)
{
int i,w;
int minidx;
int maxidx;
w = (int)((hi << 8) | lo);
if ( ( 0x40 >= lo ) && (lo >= 0xfc) && (lo == 0x7f )) {
w = (GETAHI << 8) | GETALO;
} else if (( w == 0xfa54 )||( w == 0x81ca )) {
*len = 2;
return (0xa2cc);
} else if (( w == 0xfa5b )||( w == 0x81e6)) {
*len = 2;
return (0xa2e8);
} else if (( 0xfa <= hi ) && ( hi <= 0xfc ) ) {
i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
if ( i <= EUC3CONVTBLSIZ ){
*len = 3;
return euc3conv[i];
}
} else if (( 0x8754 <= w ) && ( w <= 0x878a)) {
minidx = 0;
maxidx = EUC3CONV2TBLSIZ;
i = minidx + (maxidx - minidx) % 2;
while ( maxidx >= minidx ) {
if ( euc3conv2[i].sjis > w ) {
maxidx = i-1;
} else if ( w > euc3conv2[i].sjis ) {
minidx = i+1;
} else {
*len = 3;
return (euc3conv2[i].euc);
}
i = (int)( minidx + (maxidx - minidx) % 2 );
}
} else if (( w == 0xeef9 ) || ( w == 0x81ca )) {
*len = 2;
return (0xa2cc);
} else if (( 0xed <= hi ) && ( hi <= 0xef )) {
minidx = 0;
maxidx = SJISREVTBLSIZ;
i = 10;
while ( maxidx >= minidx ) {
if ( sjisrev[i].start > w ) {
maxidx = i-1;
} else if ( w > sjisrev[i].end ) {
minidx = i+1;
} else {
w -= sjisrev[i].start;
w += sjisrev[i].rstart;
break;
}
i = (int)( minidx + (maxidx - minidx) % 2 );
}
if ( w >= 0xfa40 ) {
i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
if ( i <= EUC3CONVTBLSIZ ){
*len = 3;
return euc3conv[i];
} else {
w = (GETAHI << 8) | GETALO;
}
}
} else if ((0xf0 <= hi) && (hi <= 0xf4)) {
*len = 2;
if (lo >= 0x9f) {
return (((hi * 2 - 0xea) << 8) | (lo + 2));
} else {
return (((hi * 2 - 0xeb) << 8) | (lo + (lo >=0x7f ? 0x60: 0x61 )));
}
} else if ((0xf5 <= hi) && (hi <= 0xf9)) {
*len = 3;
if (lo >= 0x9f) {
return (((hi*2 - 0xf4) << 8) | (lo + 2));
} else {
return (((hi*2 - 0xf5) << 8) | (lo + (lo >= 0x7f ? 0x60: 0x61 )));
}
}
*len = 2;
hi = (int) ((w >> 8) & 0xff);
lo = (int) (w & 0xff);
if (hi >= 0xf0) {
hi = GETAHI;
lo = GETALO;
}
if (lo >= 0x9f)
return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
else
return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
(lo + (lo >= 0x7f ? 0x60 : 0x61));
}
static int euc3sjis (int hi, int lo, BOOL is_3byte)
{
int w;
w = (int)((hi << 8) | lo);
if (is_3byte) {
if (( 0xf5 <= hi) && ( hi <= 0xfe)) {
if (hi & 1) {
return (((hi / 2 + 0x7b) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
} else {
return (((hi / 2 + 0x7a) << 8) | (lo - 2));
}
} else {
int minidx = 0;
int maxidx = EUC3REVTBLSIZ;
int i = minidx + (maxidx - minidx) % 2;
while ( maxidx >= minidx ) {
if (euc3rev[i].euc > w) {
maxidx = i-1;
} else if (euc3rev[i].euc < w) {
minidx = i+1;
} else {
return (euc3rev[i].sjis);
}
i = (int)( minidx + ( maxidx - minidx ) % 2);
}
return ((GETAHI << 8 ) | GETALO);
}
} else {
if ((0xf5 <= hi) && (hi <= 0xfe)) {
if (hi & 1) {
return (((hi / 2 + 0x76) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
} else {
return (((hi / 2 + 0x75) << 8) | (lo - 2));
}
} else {
if (hi & 1) {
hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
return ((hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
} else {
hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
return ((hi << 8) | (lo - 2));
}
}
}
}
static char *sj_to_euc3(char *from, BOOL overwrite)
{
char *out;
char *save;
int len;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4);) {
if (is_shift_jis (*from)) {
int code = sjis3euc ((int) from[0] & 0xff, (int) from[1] & 0xff, &len);
if (len == 3) {
*out++ = (char)euc_sup;
}
*out++ = (code >> 8) & 0xff;
*out++ = code & 0xff;
from += 2;
} else if (is_kana (*from)) {
*out++ = (char)euc_kana;
*out++ = *from++;
} else {
*out++ = *from++;
}
}
*out = 0;
if (overwrite) {
pstrcpy((char *) save, (char *) cvtbuf);
return (char *) save;
} else {
return cvtbuf;
}
}
static char *euc3_to_sj(char *from, BOOL overwrite)
{
char *out;
char *save;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
if (is_euc_sup (*from)) {
int code = euc3sjis((int) from[1] & 0xff, (int) from[2] & 0xff, True);
*out++ = (code >> 8) & 0xff;
*out++ = code & 0xff;
from += 3;
} else if (is_euc (*from)) {
int code = euc3sjis ((int) from[0] & 0xff, (int) from[1] & 0xff,False);
*out++ = (code >> 8) & 0xff;
*out++ = code & 0xff;
from += 2;
} else if (is_euc_kana (*from)) {
*out++ = from[1];
from += 2;
} else {
*out++ = *from++;
}
}
*out = 0;
if (overwrite) {
pstrcpy(save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static int sjis2jis(int hi, int lo)
{
int minidx = 0;
int maxidx = SJISCONVTBLSIZ -1;
int i = (0 + SJISCONVTBLSIZ) % 2;
int w = (int)((hi << 8) | lo);
if ((sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end)) {
while (maxidx >= minidx) {
if (sjisconv[i].start > w) {
maxidx = i-1;
} else if (w > sjisconv[i].end) {
minidx = i+1;
} else {
w -= sjisconv[i].start;
w += sjisconv[i].rstart;
break;
}
i = (int)( minidx + (maxidx-minidx) %2 );
}
hi = (int) ((w >> 8) & 0xff);
lo = (int) (w & 0xff);
}
if (hi >= 0xf0) {
hi = GETAHI;
lo = GETALO;
}
if (lo >= 0x9f)
return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
else
return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
(lo - (lo >= 0x7f ? 0x20 : 0x1f));
}
static int jis2sjis(int hi, int lo)
{
int w;
int minidx = 0;
int maxidx = SJISREVTBLSIZ;
int i = 2;
if (hi & 1) {
hi = hi / 2 + (hi < 0x5f ? 0x71 : 0xb1);
w = (hi << 8) | (lo + (lo >= 0x60 ? 0x20 : 0x1f));
} else {
hi = hi / 2 + (hi < 0x5f ? 0x70 : 0xb0);
w = (hi << 8) | (lo + 0x7e);
}
if (( 0x87 < hi ) && ( hi < 0xed )) {
return w;
}
while (maxidx >= minidx) {
if (sjisrev[i].start > w) {
maxidx = i-1;
} else if (w > sjisrev[i].end) {
minidx = i+1;
} else {
w -= sjisrev[i].start;
w += sjisrev[i].rstart;
break;
}
i = (int)( minidx + (maxidx-minidx) %2 );
}
return w;
}
static char *jis8_to_sj(char *from, BOOL overwrite)
{
char *out;
int shifted;
char *save;
shifted = _KJ_ROMAN;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
shifted = _KJ_KANJI;
from += 3;
} else if (is_si1 (from[1]) && is_si2 (from[2])) {
shifted = _KJ_ROMAN;
from += 3;
} else {
goto normal;
}
} else {
normal:
switch (shifted) {
default:
case _KJ_ROMAN:
*out++ = *from++;
break;
case _KJ_KANJI:
{
int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code;
from += 2;
break;
}
}
}
}
*out = 0;
if (overwrite) {
pstrcpy (save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static char *sj_to_jis8(char *from, BOOL overwrite)
{
char *out;
int shifted;
char *save;
shifted = _KJ_ROMAN;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
switch (shifted) {
case _KJ_ROMAN:
*out++ = jis_esc;
*out++ = jis_so1;
*out++ = jis_kso;
shifted = _KJ_KANJI;
break;
}
code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code;
from += 2;
} else {
switch (shifted) {
case _KJ_KANJI:
*out++ = jis_esc;
*out++ = jis_si1;
*out++ = jis_ksi;
shifted = _KJ_ROMAN;
break;
}
*out++ = *from++;
}
}
switch (shifted) {
case _KJ_KANJI:
*out++ = jis_esc;
*out++ = jis_si1;
*out++ = jis_ksi;
shifted = _KJ_ROMAN;
break;
}
*out = 0;
if (overwrite) {
pstrcpy (save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static char *jis7_to_sj(char *from, BOOL overwrite)
{
char *out;
int shifted;
char *save;
shifted = _KJ_ROMAN;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
shifted = _KJ_KANJI;
from += 3;
} else if (is_si1 (from[1]) && is_si2 (from[2])) {
shifted = _KJ_ROMAN;
from += 3;
} else {
goto normal;
}
} else if (is_so (*from)) {
shifted = _KJ_KANA;
from++;
} else if (is_si (*from)) {
shifted = _KJ_ROMAN;
from++;
} else {
normal:
switch (shifted) {
default:
case _KJ_ROMAN:
*out++ = *from++;
break;
case _KJ_KANJI:
{
int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code;
from += 2;
}
break;
case _KJ_KANA:
*out++ = ((int) from[0]) + 0x80;
break;
}
}
}
*out = 0;
if (overwrite) {
pstrcpy (save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static char *sj_to_jis7(char *from, BOOL overwrite)
{
char *out;
int shifted;
char *save;
shifted = _KJ_ROMAN;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
switch (shifted) {
case _KJ_KANA:
*out++ = jis_si;
case _KJ_ROMAN:
*out++ = jis_esc;
*out++ = jis_so1;
*out++ = jis_kso;
shifted = _KJ_KANJI;
break;
}
code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code;
from += 2;
} else if (is_kana (from[0])) {
switch (shifted) {
case _KJ_KANJI:
*out++ = jis_esc;
*out++ = jis_si1;
*out++ = jis_ksi;
case _KJ_ROMAN:
*out++ = jis_so;
shifted = _KJ_KANA;
break;
}
*out++ = ((int) *from++) - 0x80;
} else {
switch (shifted) {
case _KJ_KANA:
*out++ = jis_si;
shifted = _KJ_ROMAN;
break;
case _KJ_KANJI:
*out++ = jis_esc;
*out++ = jis_si1;
*out++ = jis_ksi;
shifted = _KJ_ROMAN;
break;
}
*out++ = *from++;
}
}
switch (shifted) {
case _KJ_KANA:
*out++ = jis_si;
break;
case _KJ_KANJI:
*out++ = jis_esc;
*out++ = jis_si1;
*out++ = jis_ksi;
break;
}
*out = 0;
if (overwrite) {
pstrcpy (save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static char *junet_to_sj(char *from, BOOL overwrite)
{
char *out;
int shifted;
char *save;
shifted = _KJ_ROMAN;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
shifted = _KJ_KANJI;
from += 3;
} else if (is_si1 (from[1]) && is_si2 (from[2])) {
shifted = _KJ_ROMAN;
from += 3;
} else if (is_juk1(from[1]) && is_juk2 (from[2])) {
shifted = _KJ_KANA;
from += 3;
} else {
goto normal;
}
} else {
normal:
switch (shifted) {
default:
case _KJ_ROMAN:
*out++ = *from++;
break;
case _KJ_KANJI:
{
int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code;
from += 2;
}
break;
case _KJ_KANA:
*out++ = ((int) from[0]) + 0x80;
break;
}
}
}
*out = 0;
if (overwrite) {
pstrcpy (save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static char *sj_to_junet(char *from, BOOL overwrite)
{
char *out;
int shifted;
char *save;
shifted = _KJ_ROMAN;
save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
switch (shifted) {
case _KJ_KANA:
case _KJ_ROMAN:
*out++ = jis_esc;
*out++ = jis_so1;
*out++ = jis_so2;
shifted = _KJ_KANJI;
break;
}
code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
*out++ = code;
from += 2;
} else if (is_kana (from[0])) {
switch (shifted) {
case _KJ_KANJI:
case _KJ_ROMAN:
*out++ = jis_esc;
*out++ = junet_kana1;
*out++ = junet_kana2;
shifted = _KJ_KANA;
break;
}
*out++ = ((int) *from++) - 0x80;
} else {
switch (shifted) {
case _KJ_KANA:
case _KJ_KANJI:
*out++ = jis_esc;
*out++ = jis_si1;
*out++ = jis_si2;
shifted = _KJ_ROMAN;
break;
}
*out++ = *from++;
}
}
switch (shifted) {
case _KJ_KANA:
case _KJ_KANJI:
*out++ = jis_esc;
*out++ = jis_si1;
*out++ = jis_si2;
break;
}
*out = 0;
if (overwrite) {
pstrcpy (save, (char *) cvtbuf);
return save;
} else {
return cvtbuf;
}
}
static char *hex_to_sj(char *from, BOOL overwrite)
{
char *sp, *dp;
sp = (char *) from;
dp = cvtbuf;
while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
*dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
sp += 3;
} else
*dp++ = *sp++;
}
*dp = '\0';
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
static char *sj_to_hex(char *from, BOOL overwrite)
{
unsigned char *sp, *dp;
sp = (unsigned char*) from;
dp = (unsigned char*) cvtbuf;
while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
if (is_kana(*sp)) {
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
*dp++ = bin2hex ((*sp)&0x0f);
sp++;
} else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
*dp++ = bin2hex ((*sp)&0x0f);
sp++;
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
*dp++ = bin2hex ((*sp)&0x0f);
sp++;
} else
*dp++ = *sp++;
}
*dp = '\0';
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
static char *cap_to_sj(char *from, BOOL overwrite)
{
char *sp, *dp;
sp = (char *) from;
dp = cvtbuf;
while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit((int)sp[2])) {
*dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
sp += 3;
} else
*dp++ = *sp++;
}
*dp = '\0';
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
static char *sj_to_cap(char *from, BOOL overwrite)
{
unsigned char *sp, *dp;
sp = (unsigned char*) from;
dp = (unsigned char*) cvtbuf;
while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
if (*sp >= 0x80) {
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
*dp++ = bin2hex ((*sp)&0x0f);
sp++;
} else {
*dp++ = *sp++;
}
}
*dp = '\0';
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
static char *sj_to_sj(char *from, BOOL overwrite)
{
if (!overwrite) {
pstrcpy (cvtbuf, (char *) from);
return cvtbuf;
} else {
return (char *) from;
}
}
#ifdef USES_CFSTRING
static char *cp_to_utf8(char *from, BOOL overwrite)
{
unsigned char *dst;
unsigned char *src;
int result = 0;
smb_ucs2_t *ucs2result = NULL;
unsigned int unicodeChars = 0;
unsigned long usedByteLen = 0;
unsigned long usedCharLen = 0;
src = (unsigned char *)from;
dst = (unsigned char *)cvtbuf;
dst[0] = '\0';
if (global_CFString_Encoding != kCFStringEncodingDOSJapanese)
{
if (*src)
{
ucs2result = dos_to_unicode(ucs2Str, src, 2048);
unicodeChars = strlen_w(ucs2Str);
result = CFStringEncodingUnicodeToBytes(kCFStringEncodingUTF8, kCFStringEncodingUseHFSPlusCanonical,(const UniChar *)ucs2Str,unicodeChars,&usedCharLen,(UInt8*)dst,2047,&usedByteLen);
if (result == 0)
dst[usedByteLen] = '\0';
}
}
else
result = ConvertEncodingToUTF8((const char*) src, dst, 2048, global_CFString_Encoding, kCFStringEncodingUseHFSPlusCanonical);
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
static char *utf8_to_cp(char *from, BOOL overwrite)
{
unsigned char *src;
unsigned char *dst;
int srclen;
CFStringRef cfstr = NULL;
src = (unsigned char *)from;
dst = (unsigned char *)cvtbuf;
dst[0] = '\0';
if (global_CFString_Encoding != kCFStringEncodingDOSJapanese)
{
if (*src)
{
cfstr = CFStringCreateWithCString(NULL, src,kCFStringEncodingUTF8);
if (cfstr != NULL) {
if (!CFStringGetCString(cfstr, (char*)dst, 2048, global_CFString_Encoding))
safe_strcpy(dst, src, 2048);
CFRelease( cfstr );
}
}
} else {
srclen = strlen(src);
ConvertUTF8ToEncoding((const char*) src, srclen, dst, 2048, global_CFString_Encoding,kCFStringEncodingUseHFSPlusCanonical);
}
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
#else
static char *cp_to_utf8(char *from, BOOL overwrite)
{
unsigned char *dst;
unsigned char *src;
smb_ucs2_t val;
int w;
size_t len;
src = (unsigned char *)from;
dst = (unsigned char *)cvtbuf;
while (*src && (((char *)dst - cvtbuf) < sizeof(cvtbuf)-4)) {
len = _skip_multibyte_char(*src);
if ( len == 2 ) {
w = (int)(*src++ & 0xff);
w = (int)((w << 8)|(*src++ & 0xff));
} else {
w = (int)(*src++ & 0xff);
}
val = doscp2ucs2(w);
if ( val <= 0x7f ) {
*dst++ = (char)(val & 0xff);
} else if ( val <= 0x7ff ){
*dst++ = (char)( 0xc0 | ((val >> 6) & 0xff));
*dst++ = (char)( 0x80 | ( val & 0x3f ));
} else {
*dst++ = (char)( 0xe0 | ((val >> 12) & 0x0f));
*dst++ = (char)( 0x80 | ((val >> 6) & 0x3f));
*dst++ = (char)( 0x80 | (val & 0x3f));
}
}
*dst++='\0';
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
static char *utf8_to_cp(char *from, BOOL overwrite)
{
unsigned char *src;
unsigned char *dst;
smb_ucs2_t val;
int w;
src = (unsigned char *)from;
dst = (unsigned char *)cvtbuf;
while (*src && ((char *)dst - cvtbuf < sizeof(cvtbuf)-4)) {
val = (*src++ & 0xff);
if (val < 0x80) {
*dst++ = (char)(val & 0x7f);
} else if ((0xc0 <= val) && (val <= 0xdf)
&& (0x80 <= *src) && (*src <= 0xbf)) {
w = ucs2doscp( ((val & 31) << 6) | ((*src++) & 63 ));
*dst++ = (char)((w >> 8) & 0xff);
*dst++ = (char)(w & 0xff);
} else {
val = (val & 0x0f) << 12;
val |= ((*src++ & 0x3f) << 6);
val |= (*src++ & 0x3f);
w = ucs2doscp(val);
*dst++ = (char)((w >> 8) & 0xff);
*dst++ = (char)(w & 0xff);
}
}
*dst++='\0';
if (overwrite) {
pstrcpy ((char *) from, (char *) cvtbuf);
return (char *) from;
} else {
return cvtbuf;
}
}
#endif
static void setup_string_function(int codes)
{
switch (codes) {
default:
_dos_to_unix = dos2unix_format;
_unix_to_dos = unix2dos_format;
break;
case SJIS_CODE:
_dos_to_unix = sj_to_sj;
_unix_to_dos = sj_to_sj;
break;
case EUC_CODE:
_dos_to_unix = sj_to_euc;
_unix_to_dos = euc_to_sj;
break;
case JIS7_CODE:
_dos_to_unix = sj_to_jis7;
_unix_to_dos = jis7_to_sj;
break;
case JIS8_CODE:
_dos_to_unix = sj_to_jis8;
_unix_to_dos = jis8_to_sj;
break;
case JUNET_CODE:
_dos_to_unix = sj_to_junet;
_unix_to_dos = junet_to_sj;
break;
case HEX_CODE:
_dos_to_unix = sj_to_hex;
_unix_to_dos = hex_to_sj;
break;
case CAP_CODE:
_dos_to_unix = sj_to_cap;
_unix_to_dos = cap_to_sj;
break;
case UTF8_CODE:
_dos_to_unix = cp_to_utf8;
_unix_to_dos = utf8_to_cp;
break;
case EUC3_CODE:
_dos_to_unix = sj_to_euc3;
_unix_to_dos = euc3_to_sj;
break;
}
}
void interpret_coding_system(char *str)
{
int codes = UNKNOWN_CODE;
if (strequal (str, "sjis")) {
codes = SJIS_CODE;
} else if (strequal (str, "euc")) {
codes = EUC_CODE;
} else if (strequal (str, "cap")) {
codes = CAP_CODE;
hex_tag = HEXTAG;
} else if (strequal (str, "hex")) {
codes = HEX_CODE;
hex_tag = HEXTAG;
} else if (!strncasecmp (str, "hex", 3)) {
codes = HEX_CODE;
hex_tag = (str[3] ? str[3] : HEXTAG);
} else if (strequal (str, "j8bb")) {
codes = JIS8_CODE;
jis_kso = 'B';
jis_ksi = 'B';
} else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
codes = JIS8_CODE;
jis_kso = 'B';
jis_ksi = 'J';
} else if (strequal (str, "j8bh")) {
codes = JIS8_CODE;
jis_kso = 'B';
jis_ksi = 'H';
} else if (strequal (str, "j8@b")) {
codes = JIS8_CODE;
jis_kso = '@';
jis_ksi = 'B';
} else if (strequal (str, "j8@j")) {
codes = JIS8_CODE;
jis_kso = '@';
jis_ksi = 'J';
} else if (strequal (str, "j8@h")) {
codes = JIS8_CODE;
jis_kso = '@';
jis_ksi = 'H';
} else if (strequal (str, "j7bb")) {
codes = JIS7_CODE;
jis_kso = 'B';
jis_ksi = 'B';
} else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
codes = JIS7_CODE;
jis_kso = 'B';
jis_ksi = 'J';
} else if (strequal (str, "j7bh")) {
codes = JIS7_CODE;
jis_kso = 'B';
jis_ksi = 'H';
} else if (strequal (str, "j7@b")) {
codes = JIS7_CODE;
jis_kso = '@';
jis_ksi = 'B';
} else if (strequal (str, "j7@j")) {
codes = JIS7_CODE;
jis_kso = '@';
jis_ksi = 'J';
} else if (strequal (str, "j7@h")) {
codes = JIS7_CODE;
jis_kso = '@';
jis_ksi = 'H';
} else if (strequal (str, "jubb")) {
codes = JUNET_CODE;
jis_kso = 'B';
jis_ksi = 'B';
} else if (strequal (str, "jubj") || strequal (str, "junet")) {
codes = JUNET_CODE;
jis_kso = 'B';
jis_ksi = 'J';
} else if (strequal (str, "jubh")) {
codes = JUNET_CODE;
jis_kso = 'B';
jis_ksi = 'H';
} else if (strequal (str, "ju@b")) {
codes = JUNET_CODE;
jis_kso = '@';
jis_ksi = 'B';
} else if (strequal (str, "ju@j")) {
codes = JUNET_CODE;
jis_kso = '@';
jis_ksi = 'J';
} else if (strequal (str, "ju@h")) {
codes = JUNET_CODE;
jis_kso = '@';
jis_ksi = 'H';
} else if (strequal (str, "utf8")) {
codes = UTF8_CODE;
} else if (strequal (str, "euc3")) {
codes = EUC3_CODE;
}
setup_string_function (codes);
}
static size_t skip_non_multibyte_char(char c)
{
return 0;
}
static BOOL not_multibyte_char_1(char c)
{
return False;
}
void initialize_multibyte_vectors( int client_codepage)
{
switch( client_codepage )
{
case KANJI_CODEPAGE:
multibyte_strchr = sj_strchr;
multibyte_strrchr = sj_strrchr;
multibyte_strstr = sj_strstr;
multibyte_strtok = sj_strtok;
_skip_multibyte_char = skip_kanji_multibyte_char;
is_multibyte_char_1 = is_kanji_multibyte_char_1;
global_is_multibyte_codepage = True;
break;
case HANGUL_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
multibyte_strrchr = generic_multibyte_strrchr;
multibyte_strstr = generic_multibyte_strstr;
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = hangul_is_multibyte_char_1;
global_is_multibyte_codepage = True;
break;
case BIG5_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
multibyte_strrchr = generic_multibyte_strrchr;
multibyte_strstr = generic_multibyte_strstr;
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = big5_is_multibyte_char_1;
global_is_multibyte_codepage = True;
break;
case SIMPLIFIED_CHINESE_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
multibyte_strrchr = generic_multibyte_strrchr;
multibyte_strstr = generic_multibyte_strstr;
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = simpch_is_multibyte_char_1;
global_is_multibyte_codepage = True;
break;
default:
multibyte_strchr = (const char *(*)(const char *, int )) strchr;
multibyte_strrchr = (const char *(*)(const char *, int )) strrchr;
multibyte_strstr = (const char *(*)(const char *, const char *)) strstr;
multibyte_strtok = (char *(*)(char *, const char *)) strtok;
_skip_multibyte_char = skip_non_multibyte_char;
is_multibyte_char_1 = not_multibyte_char_1;
global_is_multibyte_codepage = False;
break;
}
}
static char *no_conversion(char *str, BOOL bOverwrite)
{
static pstring temp;
if(bOverwrite)
return str;
pstrcpy(temp, str);
return temp;
}
char *(*_dos_to_dos)(char *, BOOL) = no_conversion;
#ifdef USES_CFSTRING
int ConvertEncodingToUTF8(const char* inCStr,
char* outUTF8Buffer,
int outUTF8BufferLength,
unsigned long scriptEncoding,
unsigned long flags)
{
unsigned long unicodeChars;
unsigned long srcCharsUsed;
unsigned long usedByteLen = 0;
UniChar uniStr[512];
unsigned long cfResult;
cfResult = CFStringEncodingBytesToUnicode(
scriptEncoding,
flags,
(char *)inCStr,
strlen(inCStr),
&srcCharsUsed,
uniStr,
512,
&unicodeChars);
if (cfResult == 0) {
cfResult = CFStringEncodingUnicodeToBytes(
kCFStringEncodingUTF8,
flags,
uniStr,
unicodeChars,
&srcCharsUsed,
(char*)outUTF8Buffer,
outUTF8BufferLength - 1,
&usedByteLen);
outUTF8Buffer[usedByteLen] = '\0';
}
return cfResult;
}
int ConvertUTF8ToEncoding(const char* inUTF8Buf,
int inUTF8BufLength,
char* outCStrBuffer,
int outCStrBufferLength,
unsigned long scriptEncoding,
unsigned long flags)
{
unsigned long unicodeChars;
unsigned long srcCharsUsed;
unsigned long usedByteLen = 0;
UniChar uniStr[256];
unsigned long cfResult;
cfResult = CFStringEncodingBytesToUnicode(
kCFStringEncodingUTF8,
flags,
(char*)inUTF8Buf,
inUTF8BufLength,
&srcCharsUsed,
uniStr,
255,
&unicodeChars);
if (cfResult == 0) {
cfResult = CFStringEncodingUnicodeToBytes(
scriptEncoding,
flags,
uniStr,
unicodeChars,
&srcCharsUsed,
(char*)outCStrBuffer,
outCStrBufferLength - 1,
&usedByteLen);
outCStrBuffer[usedByteLen] = '\0';
}
return cfResult;
}
#endif