Add support for hosts that reply (a.b.c.d.e.f) on PASV.
Fix bugs of UTF-8 to UTF-16 API bridge.
\r
#define LIST_MASKFLG 0xFF\r
\r
+// UTF-8対応\r
+#define LIST_RAW_NAME 0x80000000\r
+\r
/* ファイル一覧情報例 ---------------\r
\r
*LIST_UNIX_10\r
int Assume1900or2000(int Year);\r
void SetFilter(int *CancelCheckWork);\r
void doDeleteRemoteFile(void);\r
+// UTF-8対応\r
+int AnalyzeNameKanjiCode(int Num);\r
\r
\r
/*===== toolmenu.c =====*/\r
static SOCKET CmdCtrlSocket = INVALID_SOCKET;\r
static SOCKET TrnCtrlSocket = INVALID_SOCKET;\r
static HOSTDATA CurHost;\r
+// UTF-8対応\r
+static int TmpNameKanjiCode;\r
\r
/* 接続中の接続先、SOCKSサーバのアドレス情報を保存しておく */\r
/* この情報はlistenソケットを取得する際に用いる */\r
\r
InitPWDcommand();\r
CopyHostFromList(AskCurrentHost(), &CurHost);\r
+ // UTF-8対応\r
+ TmpNameKanjiCode = CurHost.NameKanjiCode;\r
\r
if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS)\r
{\r
CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security, &CancelFlg);\r
TrnCtrlSocket = CmdCtrlSocket;\r
\r
+ // UTF-8対応\r
+ if(TmpNameKanjiCode == KANJI_AUTO)\r
+ {\r
+ if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+ {\r
+ SetCache(999, "");\r
+ TmpNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+ }\r
+ }\r
+\r
if(CmdCtrlSocket != INVALID_SOCKET)\r
{\r
strcpy(TitleHostName, CurHost.HostName);\r
\r
InitPWDcommand();\r
CopyDefaultHost(&CurHost);\r
+ // UTF-8対応\r
+ TmpNameKanjiCode = CurHost.NameKanjiCode;\r
if(SplitUNCpath(Tmp, CurHost.HostAdrs, CurHost.RemoteInitDir, File, CurHost.UserName, CurHost.PassWord, &CurHost.Port) == FFFTP_SUCCESS)\r
{\r
if(strlen(CurHost.UserName) == 0)\r
CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
TrnCtrlSocket = CmdCtrlSocket;\r
\r
+ // UTF-8対応\r
+ if(TmpNameKanjiCode == KANJI_AUTO)\r
+ {\r
+ if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+ {\r
+ SetCache(999, "");\r
+ TmpNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+ }\r
+ }\r
+\r
if(CmdCtrlSocket != INVALID_SOCKET)\r
{\r
strcpy(TitleHostName, CurHost.HostAdrs);\r
CurHost.KanaCnv = Kana;\r
CurHost.NameKanjiCode = Fkanji;\r
CurHost.KanaCnv = YES; /* とりあえず */\r
+ // UTF-8対応\r
+ TmpNameKanjiCode = CurHost.NameKanjiCode;\r
\r
SetHostKanaCnvImm(CurHost.KanaCnv);\r
SetHostKanjiCodeImm(CurHost.KanjiCode);\r
CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
TrnCtrlSocket = CmdCtrlSocket;\r
\r
+ // UTF-8対応\r
+ if(TmpNameKanjiCode == KANJI_AUTO)\r
+ {\r
+ if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+ {\r
+ SetCache(999, "");\r
+ TmpNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+ }\r
+ }\r
+\r
if(CmdCtrlSocket != INVALID_SOCKET)\r
{\r
strcpy(TitleHostName, CurHost.HostAdrs);\r
\r
InitPWDcommand();\r
CopyHistoryToHost(&Hist, &CurHost);\r
+ // UTF-8対応\r
+ TmpNameKanjiCode = CurHost.NameKanjiCode;\r
\r
if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS)\r
{\r
CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
TrnCtrlSocket = CmdCtrlSocket;\r
\r
+ // UTF-8対応\r
+ if(TmpNameKanjiCode == KANJI_AUTO)\r
+ {\r
+ if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+ {\r
+ SetCache(999, "");\r
+ TmpNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+ }\r
+ }\r
+\r
if(CmdCtrlSocket != INVALID_SOCKET)\r
{\r
strcpy(TitleHostName, CurHost.HostAdrs);\r
\r
int AskHostNameKanji(void)\r
{\r
- if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
- CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
-\r
- return(CurHost.NameKanjiCode);\r
+ // UTF-8対応\r
+// if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+// CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+//\r
+// return(CurHost.NameKanjiCode);\r
+ return(TmpNameKanjiCode);\r
}\r
\r
\r
HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV;\r
}\r
// UTF-8対応\r
- if(HostData->NameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8))\r
+ if(TmpNameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8))\r
{\r
if((Sts = command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON")) == 200)\r
- {\r
- }\r
+ TmpNameKanjiCode = KANJI_UTF8N;\r
}\r
}\r
}\r
break;\r
}\r
\r
- if((Ret != NODE_NONE) && (strlen(Fname) > 0))\r
+ // UTF-8対応\r
+// if((Ret != NODE_NONE) && (strlen(Fname) > 0))\r
+ if(!(OrgListType & LIST_RAW_NAME) && (Ret != NODE_NONE) && (strlen(Fname) > 0))\r
{\r
if(CheckSpecialDirName(Fname) == YES)\r
Ret = NODE_NONE;\r
\r
\r
\r
+// UTF-8対応\r
+// ファイル一覧から漢字コードを推測\r
+// 優先度はUTF-8、Shift_JIS、EUC、JISの順\r
+int AnalyzeNameKanjiCode(int Num)\r
+{\r
+ char Str[FMAX_PATH+1];\r
+ char Name[FMAX_PATH+1];\r
+ LONGLONG Size;\r
+ FILETIME Time;\r
+ int Attr;\r
+ FILE *fd;\r
+ int Node;\r
+ int ListType;\r
+ char Owner[OWNER_NAME_LEN+1];\r
+ int Link;\r
+ int InfoExist;\r
+ int NameKanjiCode;\r
+ int Point;\r
+ int PointSJIS;\r
+ int PointJIS;\r
+ int PointEUC;\r
+ int PointUTF8N;\r
+ char* p;\r
+\r
+ NameKanjiCode = KANJI_AUTO;\r
+ Point = 1;\r
+ PointSJIS = 0;\r
+ PointJIS = 0;\r
+ PointEUC = 0;\r
+ PointUTF8N = 0;\r
+ MakeCacheFileName(Num, Str);\r
+ if((fd = fopen(Str, "rb")) != NULL)\r
+ {\r
+ while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
+ {\r
+ if((ListType = AnalizeFileInfo(Str)) != LIST_UNKNOWN)\r
+ {\r
+ Node = ResolvFileInfo(Str, ListType | LIST_RAW_NAME, Name, &Size, &Time, &Attr, Owner, &Link, &InfoExist);\r
+ p = Name;\r
+ while(*p != '\0')\r
+ {\r
+ if(*p & 0x80)\r
+ {\r
+ p = NULL;\r
+ break;\r
+ }\r
+ p++;\r
+ }\r
+ if(!p)\r
+ {\r
+ if(!CheckStringM(Name))\r
+ PointUTF8N++;\r
+ else\r
+ {\r
+ switch(CheckKanjiCode(Name, strlen(Name), KANJI_SJIS))\r
+ {\r
+ case KANJI_SJIS:\r
+ PointSJIS++;\r
+ break;\r
+ case KANJI_JIS:\r
+ PointJIS++;\r
+ break;\r
+ case KANJI_EUC:\r
+ PointEUC++;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ fclose(fd);\r
+ }\r
+ if(PointJIS >= Point)\r
+ {\r
+ NameKanjiCode = KANJI_JIS;\r
+ Point = PointJIS;\r
+ }\r
+ if(PointEUC >= Point)\r
+ {\r
+ NameKanjiCode = KANJI_EUC;\r
+ Point = PointEUC;\r
+ }\r
+ if(PointSJIS >= Point)\r
+ {\r
+ NameKanjiCode = KANJI_SJIS;\r
+ Point = PointSJIS;\r
+ }\r
+ if(PointUTF8N >= Point)\r
+ {\r
+ NameKanjiCode = KANJI_UTF8N;\r
+ Point = PointUTF8N;\r
+ }\r
+ return NameKanjiCode;\r
+}\r
+\r
{\r
Pos++;\r
Btm = strchr(Pos, ',');\r
+ // コンマではなくドットを返すホストがあるため\r
+ if(Btm == NULL)\r
+ Btm = strchr(Pos, '.');\r
if(Btm != NULL)\r
{\r
Btm++;\r
Btm = strchr(Btm, ',');\r
+ // コンマではなくドットを返すホストがあるため\r
+ if(Btm == NULL)\r
+ Btm = strchr(Btm, '.');\r
if(Btm != NULL)\r
{\r
Btm++;\r
Btm = strchr(Btm, ',');\r
+ // コンマではなくドットを返すホストがあるため\r
+ if(Btm == NULL)\r
+ Btm = strchr(Btm, '.');\r
if(Btm != NULL)\r
{\r
Btm++;\r
Btm = strchr(Btm, ',');\r
+ // コンマではなくドットを返すホストがあるため\r
+ if(Btm == NULL)\r
+ Btm = strchr(Btm, '.');\r
if(Btm != NULL)\r
{\r
if((Btm - Pos) <= Max)\r
\r
Pos = Btm + 1;\r
Btm = strchr(Pos, ',');\r
+ // コンマではなくドットを返すホストがあるため\r
+ if(Btm == NULL)\r
+ Btm = strchr(Pos, '.');\r
if(Btm != NULL)\r
{\r
Btm++;\r
return p;\r
}\r
\r
+// マルチバイト文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
+{\r
+ DWORD Code;\r
+ int i;\r
+ Code = 0;\r
+ if((*lpString & 0xfe) == 0xfc)\r
+ {\r
+ i = 5;\r
+ Code |= (DWORD)*lpString & 0x01;\r
+ }\r
+ else if((*lpString & 0xfc) == 0xf8)\r
+ {\r
+ i = 4;\r
+ Code |= (DWORD)*lpString & 0x03;\r
+ }\r
+ else if((*lpString & 0xf8) == 0xf0)\r
+ {\r
+ i = 3;\r
+ Code |= (DWORD)*lpString & 0x07;\r
+ }\r
+ else if((*lpString & 0xf0) == 0xe0)\r
+ {\r
+ i = 2;\r
+ Code |= (DWORD)*lpString & 0x0f;\r
+ }\r
+ else if((*lpString & 0xe0) == 0xc0)\r
+ {\r
+ i = 1;\r
+ Code |= (DWORD)*lpString & 0x1f;\r
+ }\r
+ else if((*lpString & 0x80) == 0x00)\r
+ {\r
+ i = 0;\r
+ Code |= (DWORD)*lpString & 0x7f;\r
+ }\r
+ else\r
+ i = -1;\r
+ lpString++;\r
+ while((*lpString & 0xc0) == 0x80)\r
+ {\r
+ i--;\r
+ Code = Code << 6;\r
+ Code |= (DWORD)*lpString & 0x3f;\r
+ lpString++;\r
+ }\r
+ if(i != 0)\r
+ Code = 0x80000000;\r
+ if(ppNext)\r
+ *ppNext = lpString;\r
+ return Code;\r
+}\r
+\r
// マルチバイト文字列の冗長表現を修正\r
// 修正があればTRUEを返す\r
// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
p = (char*)pSrc;\r
while(*pSrc != '\0')\r
{\r
- Code = 0;\r
- if((*pSrc & 0xfe) == 0xfc)\r
- {\r
- i = 5;\r
- Code |= (DWORD)*pSrc & 0x01;\r
- }\r
- else if((*pSrc & 0xfc) == 0xf8)\r
- {\r
- i = 4;\r
- Code |= (DWORD)*pSrc & 0x03;\r
- }\r
- else if((*pSrc & 0xf8) == 0xf0)\r
- {\r
- i = 3;\r
- Code |= (DWORD)*pSrc & 0x07;\r
- }\r
- else if((*pSrc & 0xf0) == 0xe0)\r
- {\r
- i = 2;\r
- Code |= (DWORD)*pSrc & 0x0f;\r
- }\r
- else if((*pSrc & 0xe0) == 0xc0)\r
- {\r
- i = 1;\r
- Code |= (DWORD)*pSrc & 0x1f;\r
- }\r
- else if((*pSrc & 0x80) == 0x00)\r
- {\r
- i = 0;\r
- Code |= (DWORD)*pSrc & 0x7f;\r
- }\r
- else\r
- i = -1;\r
- pSrc++;\r
- while((*pSrc & 0xc0) == 0x80)\r
- {\r
- i--;\r
- Code = Code << 6;\r
- Code |= (DWORD)*pSrc & 0x3f;\r
- pSrc++;\r
- }\r
- if(i != 0)\r
+ Code = GetNextCharM(pSrc, &pSrc);\r
+ if(Code & 0x80000000)\r
continue;\r
else if(Code & 0x7c000000)\r
{\r
size_t _mbslenM(const unsigned char * _Str)\r
{\r
size_t r = 0;\r
- wchar_t* pw0 = NULL;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str, -1);\r
- r = wcslen(pw0);\r
+ while(GetNextCharM(_Str, &_Str) > 0)\r
+ {\r
+ r++;\r
+ }\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
return r;\r
}\r
\r
unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
{\r
unsigned char* r = NULL;\r
- wchar_t* pw0 = NULL;\r
- wchar_t* wr;\r
+ unsigned int c;\r
+ unsigned char* p;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str, -1);\r
- // TODO: 非ASCII文字の対応\r
- wr = wcschr(pw0, _Ch);\r
- if(wr)\r
+ while((c = GetNextCharM(_Str, &p)) > 0)\r
{\r
- *wr = L'\0';\r
- r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
+ if(c == _Ch)\r
+ {\r
+ r = (unsigned char*)_Str;\r
+ break;\r
+ }\r
+ _Str = p;\r
}\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
return r;\r
}\r
\r
unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
{\r
unsigned char* r = NULL;\r
- wchar_t* pw0 = NULL;\r
- wchar_t* wr;\r
+ unsigned int c;\r
+ unsigned char* p;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str, -1);\r
- // TODO: 非ASCII文字の対応\r
- wr = wcsrchr(pw0, _Ch);\r
- if(wr)\r
+ while((c = GetNextCharM(_Str, &p)) > 0)\r
{\r
- *wr = L'\0';\r
- r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
+ if(c == _Ch)\r
+ r = (unsigned char*)_Str;\r
+ _Str = p;\r
}\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
return r;\r
}\r
\r
unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
{\r
unsigned char* r = NULL;\r
- wchar_t* pw0 = NULL;\r
- wchar_t* pw1 = NULL;\r
- wchar_t* wr;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str, -1);\r
- pw1 = DuplicateMtoW(_Substr, -1);\r
- wr = wcsstr(pw0, pw1);\r
- if(wr)\r
- {\r
- *wr = L'\0';\r
- r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
- }\r
+ r = strstr(_Str, _Substr);\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
- FreeDuplicatedString(pw1);\r
return r;\r
}\r
\r
int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
{\r
int r = 0;\r
- wchar_t* pw0 = NULL;\r
- wchar_t* pw1 = NULL;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str1, -1);\r
- pw1 = DuplicateMtoW(_Str2, -1);\r
- r = wcscmp(pw0, pw1);\r
+ r = strcmp(_Str1, _Str2);\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
- FreeDuplicatedString(pw1);\r
return r;\r
}\r
\r
int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
{\r
int r = 0;\r
- wchar_t* pw0 = NULL;\r
- wchar_t* pw1 = NULL;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str1, -1);\r
- pw1 = DuplicateMtoW(_Str2, -1);\r
- r = _wcsicmp(pw0, pw1);\r
+ r = _stricmp(_Str1, _Str2);\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
- FreeDuplicatedString(pw1);\r
return r;\r
}\r
\r
int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)\r
{\r
int r = 0;\r
- wchar_t* pw0 = NULL;\r
- wchar_t* pw1 = NULL;\r
+ DWORD c1;\r
+ DWORD c2;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str1, -1);\r
- pw1 = DuplicateMtoW(_Str2, -1);\r
- r = wcsncmp(pw0, pw1, _MaxCount);\r
+ c1 = 0;\r
+ c2 = 0;\r
+ while(_MaxCount > 0)\r
+ {\r
+ c1 = GetNextCharM(_Str1, &_Str1);\r
+ c2 = GetNextCharM(_Str2, &_Str2);\r
+ if(c1 != c2)\r
+ break;\r
+ _MaxCount--;\r
+ if(c1 == 0 || c2 == 0)\r
+ break;\r
+ }\r
+ r = c1 - c2;\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
- FreeDuplicatedString(pw1);\r
return r;\r
}\r
\r
unsigned char * _mbslwrM(unsigned char * _String)\r
{\r
unsigned char* r = NULL;\r
- wchar_t* pw0 = NULL;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_String, -1);\r
- _wcslwr(pw0);\r
- r = _String;\r
- WtoM(_String, strlen(_String) + 1, pw0, -1);\r
+ r = _strlwr(_String);\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
return r;\r
}\r
\r
unsigned char * _mbsuprM(unsigned char * _String)\r
{\r
unsigned char* r = NULL;\r
- wchar_t* pw0 = NULL;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_String, -1);\r
- _wcsupr(pw0);\r
- r = _String;\r
- WtoM(_String, strlen(_String) + 1, pw0, -1);\r
+ r = _strupr(_String);\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
return r;\r
}\r
\r
unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
{\r
unsigned char* r = NULL;\r
- wchar_t* pw0 = NULL;\r
- wchar_t* wr;\r
START_ROUTINE\r
- pw0 = DuplicateMtoW(_Str, -1);\r
- wr = _wcsninc(pw0, _Count);\r
- if(wr)\r
+ while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
{\r
- *wr = L'\0';\r
- r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
+ _Count--;\r
}\r
+ r = (unsigned char*)_Str;\r
END_ROUTINE\r
- FreeDuplicatedString(pw0);\r
return r;\r
}\r
\r
char* DuplicateWtoM(LPCWSTR lpString, int c);\r
wchar_t* DuplicateAtoW(LPCSTR lpString, int c);\r
char* DuplicateWtoA(LPCWSTR lpString, int c);\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext);\r
BOOL FixStringM(LPSTR pDst, LPCSTR pSrc);\r
BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc);\r
BOOL CheckStringM(LPCSTR lpString);\r
Length = 0;\r
while(*InputString != '\0')\r
{\r
- *p = 0;\r
- if((*InputString & 0x80) == 0x00)\r
- *p |= (punycode_uint)*InputString & 0x7f;\r
- else if((*InputString & 0xe0) == 0xc0)\r
- *p |= (punycode_uint)*InputString & 0x1f;\r
- else if((*InputString & 0xf0) == 0xe0)\r
- *p |= (punycode_uint)*InputString & 0x0f;\r
- else if((*InputString & 0xf8) == 0xf0)\r
- *p |= (punycode_uint)*InputString & 0x07;\r
- else if((*InputString & 0xfc) == 0xf8)\r
- *p |= (punycode_uint)*InputString & 0x03;\r
- else if((*InputString & 0xfe) == 0xfc)\r
- *p |= (punycode_uint)*InputString & 0x01;\r
- InputString++;\r
- while((*InputString & 0xc0) == 0x80)\r
- {\r
- *p = *p << 6;\r
- *p |= (punycode_uint)*InputString & 0x3f;\r
- InputString++;\r
- }\r
+ *p = (punycode_uint)GetNextCharM(InputString, &InputString);\r
if(*p >= 0x80)\r
bNeeded = TRUE;\r
p++;\r