1 // SoftEther UT-VPN SourceCode
\r
3 // Copyright (C) 2004-2010 SoftEther Corporation.
\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.
\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.
\r
6 // All Rights Reserved.
\r
8 // http://utvpn.tsukuba.ac.jp/
\r
10 // This program is free software; you can redistribute it and/or
\r
11 // modify it under the terms of the GNU General Public License
\r
12 // version 2 as published by the Free Software Foundation.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License version 2
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。
\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の
\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
\r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
\r
34 // および、試験または研究のために利用が行われることを想定して配布
\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
\r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
\r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。
\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
\r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の
\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
\r
58 // 公益保護にご協力いただきますようお願い申し上げます。
\r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
\r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
\r
65 // 日本国内の脆弱性情報届出受付公的機関:
\r
67 // http://www.ipa.go.jp/security/vuln/report/
\r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/
\r
72 // -----------------------------------------------
\r
75 // 新規リリース by SoftEther
\r
76 // -----------------------------------------------
\r
79 // 国際化のための文字列変換ライブラリ
\r
88 #include <Mayaqua/Mayaqua.h>
\r
90 extern LOCK *token_lock;
\r
91 static char charset[MAX_SIZE] = "EUCJP";
\r
92 static LOCK *iconv_lock = NULL;
\r
93 void *iconv_cache_wide_to_str = 0;
\r
94 void *iconv_cache_str_to_wide = 0;
\r
96 // 文字列が含まれているかどうかチェック
\r
97 bool UniInStr(wchar_t *str, wchar_t *keyword)
\r
99 return UniInStrEx(str, keyword, false);
\r
101 bool UniInStrEx(wchar_t *str, wchar_t *keyword, bool case_sensitive)
\r
104 if (UniIsEmptyStr(str) || UniIsEmptyStr(keyword))
\r
109 if (UniSearchStrEx(str, keyword, 0, case_sensitive) == INFINITE)
\r
118 BUF *UniStrToBin(wchar_t *str)
\r
120 char *str_a = CopyUniToStr(str);
\r
123 ret = StrToBin(str_a);
\r
131 wchar_t *UniMakeCharArray(wchar_t c, UINT count)
\r
134 wchar_t *ret = Malloc(sizeof(wchar_t) * (count + 1));
\r
136 for (i = 0;i < count;i++)
\r
147 bool UniIsSafeChar(wchar_t c)
\r
150 wchar_t *check_str =
\r
151 L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
\r
152 L"abcdefghijklmnopqrstuvwxyz"
\r
156 len = UniStrLen(check_str);
\r
157 for (i = 0;i < len;i++)
\r
159 if (c == check_str[i])
\r
167 // トークンリストを文字列リストに変換する
\r
168 LIST *UniTokenListToList(UNI_TOKEN_LIST *t)
\r
178 o = NewListFast(NULL);
\r
179 for (i = 0;i < t->NumTokens;i++)
\r
181 Insert(o, UniCopyStr(t->Token[i]));
\r
187 // 文字列リストをトークンリストに変換する
\r
188 UNI_TOKEN_LIST *UniListToTokenList(LIST *o)
\r
198 t = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
\r
199 t->NumTokens = LIST_NUM(o);
\r
200 t->Token = ZeroMalloc(sizeof(wchar_t *) * t->NumTokens);
\r
201 for (i = 0;i < LIST_NUM(o);i++)
\r
203 t->Token[i] = UniCopyStr(LIST_DATA(o, i));
\r
210 void UniFreeStrList(LIST *o)
\r
219 for (i = 0;i < LIST_NUM(o);i++)
\r
221 wchar_t *s = LIST_DATA(o, i);
\r
229 BUF *UniStrListToStr(LIST *o)
\r
241 for (i = 0;i < LIST_NUM(o);i++)
\r
243 wchar_t *s = LIST_DATA(o, i);
\r
244 WriteBuf(b, s, UniStrSize(s));
\r
248 WriteBuf(b, &c, sizeof(c));
\r
255 // 文字列 (NULL区切り) をリストに変換する
\r
256 LIST *UniStrToStrList(wchar_t *str, UINT size)
\r
268 o = NewListFast(NULL);
\r
282 tmp_size = UniStrSize(str);
\r
283 tmp = ZeroMalloc(tmp_size);
\r
284 UniStrCpy(tmp, tmp_size, str);
\r
286 str += UniStrLen(str) + 1;
\r
294 wchar_t *UniNormalizeCrlf(wchar_t *str)
\r
297 UINT ret_size, i, len, wp;
\r
304 len = UniStrLen(str);
\r
305 ret_size = sizeof(wchar_t) * (len + 32) * 2;
\r
306 ret = Malloc(ret_size);
\r
310 for (i = 0;i < len;i++)
\r
312 wchar_t c = str[i];
\r
317 if (str[i + 1] == L'\n')
\r
341 // str が key で終了するかどうかチェック
\r
342 bool UniEndWith(wchar_t *str, wchar_t *key)
\r
347 if (str == NULL || key == NULL)
\r
353 str_len = UniStrLen(str);
\r
354 key_len = UniStrLen(key);
\r
355 if (str_len < key_len)
\r
360 if (UniStrCmpi(str + (str_len - key_len), key) == 0)
\r
370 // str が key で始まるかどうかチェック
\r
371 bool UniStartWith(wchar_t *str, wchar_t *key)
\r
378 if (str == NULL || key == NULL)
\r
384 str_len = UniStrLen(str);
\r
385 key_len = UniStrLen(key);
\r
386 if (str_len < key_len)
\r
390 if (str_len == 0 || key_len == 0)
\r
394 tmp = CopyUniStr(str);
\r
397 if (UniStrCmpi(tmp, key) == 0)
\r
411 // 整数をカンマ区切り文字列に変換する
\r
412 void UniToStr3(wchar_t *str, UINT size, UINT64 value)
\r
414 char tmp[MAX_SIZE];
\r
421 ToStr3(tmp, sizeof(tmp), value);
\r
423 StrToUni(str, size, tmp);
\r
426 // 文字列のフォーマット (内部関数)
\r
427 wchar_t *InternalFormatArgs(wchar_t *fmt, va_list args, bool ansi_mode)
\r
443 len = UniStrLen(fmt);
\r
444 tmp_size = UniStrSize(fmt);
\r
445 tmp = Malloc(tmp_size);
\r
447 o = NewListFast(NULL);
\r
453 for (i = 0;i < len;i++)
\r
455 wchar_t c = fmt[i];
\r
464 if (fmt[i + 1] == L'%')
\r
466 // 次の文字も % の場合は % を一文字出力するだけ
\r
472 // 次の文字が % でない場合は状態遷移を行う
\r
476 Add(o, CopyUniStr(tmp));
\r
489 char dst[MAX_SIZE];
\r
490 wchar_t *target_str;
\r
491 wchar_t *padding_str;
\r
493 UINT target_str_len;
\r
495 wchar_t *output_str;
\r
511 tag = CopyUniToStr(tmp);
\r
514 ReplaceStrEx(tag, 0, tag, "ll", "I64", false);
\r
516 ReplaceStrEx(tag, 0, tag, "I64", "ll", false);
\r
519 if ((UniStrLen(tmp) >= 5 && tmp[UniStrLen(tmp) - 4] == L'I' &&
\r
520 tmp[UniStrLen(tmp) - 3] == L'6' &&
\r
521 tmp[UniStrLen(tmp) - 2] == L'4') ||
\r
523 UniStrLen(tmp) >= 4 && tmp[UniStrLen(tmp) - 3] == L'l' &&
\r
524 tmp[UniStrLen(tmp) - 2] == L'l'))
\r
527 _snprintf(dst, sizeof(dst), tag, va_arg(args, UINT64));
\r
529 snprintf(dst, sizeof(dst), tag, va_arg(args, UINT64));
\r
535 _snprintf(dst, sizeof(dst), tag, va_arg(args, int));
\r
537 snprintf(dst, sizeof(dst), tag, va_arg(args, int));
\r
542 Add(o, CopyStrToUni(dst));
\r
555 tag = CopyUniToStr(tmp);
\r
558 _snprintf(dst, sizeof(dst), tag, va_arg(args, double));
\r
560 snprintf(dst, sizeof(dst), tag, va_arg(args, double));
\r
564 Add(o, CopyStrToUni(dst));
\r
574 tag = ZeroMalloc(UniStrSize(tmp) + 32);
\r
575 UniToStr(tag, 0, tmp);
\r
578 _snprintf(dst, sizeof(dst), tag, va_arg(args, void *));
\r
580 snprintf(dst, sizeof(dst), tag, va_arg(args, void *));
\r
584 Add(o, CopyStrToUni(dst));
\r
595 if (ansi_mode == false)
\r
609 target_str = CopyStrToUni(va_arg(args, char *));
\r
613 target_str = CopyUniStr(va_arg(args, wchar_t *));
\r
616 if (target_str == NULL)
\r
618 target_str = CopyUniStr(L"(null)");
\r
622 left_padding = false;
\r
623 if (tmp[1] == L'-')
\r
626 if (UniStrLen(tmp) >= 3)
\r
628 padding = UniToInt(&tmp[2]);
\r
630 left_padding = true;
\r
635 if (UniStrLen(tmp) >= 2)
\r
637 padding = UniToInt(&tmp[1]);
\r
641 target_str_len = UniStrWidth(target_str);
\r
643 if (padding > target_str_len)
\r
645 UINT len = padding - target_str_len;
\r
647 padding_str = ZeroMalloc(sizeof(wchar_t) * (len + 1));
\r
648 for (i = 0;i < len;i++)
\r
650 padding_str[i] = L' ';
\r
655 padding_str = ZeroMalloc(sizeof(wchar_t));
\r
658 total_len = sizeof(wchar_t) * (UniStrLen(padding_str) + UniStrLen(target_str) + 1);
\r
659 output_str = ZeroMalloc(total_len);
\r
662 if (left_padding == false)
\r
664 UniStrCat(output_str, total_len, padding_str);
\r
666 UniStrCat(output_str, total_len, target_str);
\r
669 UniStrCat(output_str, total_len, padding_str);
\r
672 Add(o, output_str);
\r
690 if (UniStrLen(tmp) >= 1)
\r
692 Add(o, CopyUniStr(tmp));
\r
695 total_size = sizeof(wchar_t);
\r
696 for (i = 0;i < LIST_NUM(o);i++)
\r
698 wchar_t *s = LIST_DATA(o, i);
\r
699 total_size += UniStrLen(s) * sizeof(wchar_t);
\r
702 ret = ZeroMalloc(total_size);
\r
703 for (i = 0;i < LIST_NUM(o);i++)
\r
705 wchar_t *s = LIST_DATA(o, i);
\r
706 UniStrCat(ret, total_size, s);
\r
718 UINT UniStrWidth(wchar_t *str)
\r
728 len = UniStrLen(str);
\r
729 for (i = 0;i < len;i++)
\r
743 // Unicode 文字列をダンプ表示する
\r
744 void DumpUniStr(wchar_t *str)
\r
754 s = CopyUniToStr(str);
\r
756 Print("DumpUniStr: %s\n ", s);
\r
758 len = UniStrLen(str);
\r
759 for (i = 0;i < len;i++)
\r
761 Print("0x%04X ", str[i]);
\r
769 void DumpStr(char *str)
\r
778 Print("DumpStr: %s\n ", str);
\r
781 for (i = 0;i < len;i++)
\r
783 Print("0x%02X ", str[i]);
\r
788 // 1 文字 2 バイトの文字列を 1 文字 4 場合の wchar_t に変換する
\r
789 wchar_t *Utf16ToWide(USHORT *str)
\r
809 ret = Malloc((len + 1) * sizeof(wchar_t));
\r
810 for (i = 0;i < len + 1;i++)
\r
812 ret[i] = (wchar_t)str[i];
\r
818 // 1 文字 4 バイトの wchar_t 文字列を 1 文字 2 バイトに変換する
\r
819 USHORT *WideToUtf16(wchar_t *str)
\r
831 len = UniStrLen(str);
\r
833 ret_size = (len + 1) * 2;
\r
834 ret = Malloc(ret_size);
\r
836 for (i = 0;i < len + 1;i++)
\r
838 ret[i] = (USHORT)str[i];
\r
845 void InitInternational()
\r
850 if (iconv_lock != NULL)
\r
855 GetCurrentCharSet(charset, sizeof(charset));
\r
856 d = IconvWideToStrInternal();
\r
857 if (d == (void *)-1)
\r
860 StrCpy(charset, sizeof(charset), "utf8");
\r
861 #else // UNIX_MACOS
\r
862 StrCpy(charset, sizeof(charset), "EUCJP");
\r
863 #endif // UNIX_MACOS
\r
864 d = IconvWideToStrInternal();
\r
865 if (d == (void *)-1)
\r
867 StrCpy(charset, sizeof(charset), "US");
\r
871 IconvFreeInternal(d);
\r
876 IconvFreeInternal(d);
\r
879 iconv_lock = NewLockMain();
\r
881 iconv_cache_wide_to_str = IconvWideToStrInternal();
\r
882 iconv_cache_str_to_wide = IconvStrToWideInternal();
\r
887 void FreeInternational()
\r
895 // 文字列を Unicode に変換した場合のサイズを計算する
\r
896 UINT UnixCalcStrToUni(char *str)
\r
899 UINT len, tmp_size;
\r
908 tmp_size = len * 5 + 10;
\r
909 tmp = ZeroMalloc(tmp_size);
\r
910 UnixStrToUni(tmp, tmp_size, str);
\r
911 ret = UniStrLen(tmp);
\r
914 return (ret + 1) * sizeof(wchar_t);
\r
917 // 文字列を Unicode に変換する
\r
918 UINT UnixStrToUni(wchar_t *s, UINT size, char *str)
\r
928 if (s == NULL || str == NULL)
\r
933 d = IconvStrToWide();
\r
934 if (d == (void *)-1)
\r
936 UniStrCpy(s, size, L"");
\r
940 inbuf = (char *)str;
\r
941 insize = StrLen(str) + 1;
\r
942 outsize = insize * 5 + 10;
\r
943 outbuf_orig = outbuf = ZeroMalloc(outsize);
\r
945 if (iconv((iconv_t)d, (char **)&inbuf, (size_t *)&insize, (char **)&outbuf, (size_t *)&outsize) == (size_t)(-1))
\r
948 UniStrCpy(s, size, L"");
\r
953 tmp = Utf16ToWide((USHORT *)outbuf_orig);
\r
956 UniStrCpy(s, size, tmp);
\r
961 return UniStrLen(s);
\r
964 // Unicode を文字列にした場合のサイズを計算する
\r
965 UINT UnixCalcUniToStr(wchar_t *s)
\r
976 tmp_size = UniStrLen(s) * 5 + 10;
\r
977 tmp = ZeroMalloc(tmp_size);
\r
978 UnixUniToStr(tmp, tmp_size, s);
\r
980 ret = StrSize(tmp);
\r
986 // Unicode を文字列に変換する
\r
987 UINT UnixUniToStr(char *str, UINT size, wchar_t *s)
\r
997 if (str == NULL || s == NULL)
\r
1002 // まず wchar_t 文字列を 2 バイトの並びに変換する
\r
1003 tmp = WideToUtf16(s);
\r
1004 inbuf = (char *)tmp;
\r
1005 insize = (UniStrLen(s) + 1) * 2;
\r
1006 outsize = insize * 5 + 10;
\r
1007 outbuf_orig = outbuf = ZeroMalloc(outsize);
\r
1009 d = IconvWideToStr();
\r
1010 if (d == (void *)-1)
\r
1012 StrCpy(str, size, "");
\r
1018 if (iconv((iconv_t)d, (char **)&inbuf, (size_t *)&insize, (char **)&outbuf, (size_t *)&outsize) == (size_t)(-1))
\r
1020 Free(outbuf_orig);
\r
1022 StrCpy(str, size, "");
\r
1027 StrCpy(str, size, outbuf_orig);
\r
1029 Free(outbuf_orig);
\r
1033 return StrLen(str);
\r
1036 // whcar_t を char に変換する
\r
1037 void *IconvWideToStrInternal()
\r
1039 return (void *)iconv_open(charset, IsBigEndian() ? "UTF-16BE" : "UTF-16LE");
\r
1042 // char を wchar_t に変換する
\r
1043 void *IconvStrToWideInternal()
\r
1045 return (void *)iconv_open(IsBigEndian() ? "UTF-16BE" : "UTF-16LE", charset);
\r
1049 int IconvFreeInternal(void *d)
\r
1051 iconv_close((iconv_t)d);
\r
1055 void *IconvWideToStr()
\r
1057 if (iconv_cache_wide_to_str == (void *)-1)
\r
1059 return (void *)-1;
\r
1064 return iconv_cache_wide_to_str;
\r
1067 void *IconvStrToWide()
\r
1069 if (iconv_cache_str_to_wide == (void *)-1)
\r
1071 return (void *)-1;
\r
1076 return iconv_cache_str_to_wide;
\r
1079 int IconvFree(void *d)
\r
1081 Unlock(iconv_lock);
\r
1086 // 現在使用されている文字セットを環境変数から取得する
\r
1087 void GetCurrentCharSet(char *name, UINT size)
\r
1089 char tmp[MAX_SIZE];
\r
1097 if (GetEnv("LANG", tmp, sizeof(tmp)) == false)
\r
1099 if (GetEnv("LOCATION", tmp, sizeof(tmp)) == false)
\r
1101 StrCpy(tmp, sizeof(tmp), "ja_JP.eucJP");
\r
1107 t = ParseToken(tmp, ".");
\r
1108 if (t->NumTokens >= 2)
\r
1110 StrCpy(name, size, t->Token[1]);
\r
1114 if (t->NumTokens == 1)
\r
1116 StrCpy(name, size, t->Token[0]);
\r
1120 StrCpy(name, size, "eucJP");
\r
1130 // 指定された文字列が空白かどうかチェック
\r
1131 bool UniIsEmptyStr(wchar_t *str)
\r
1133 return IsEmptyUniStr(str);
\r
1135 bool IsEmptyUniStr(wchar_t *str)
\r
1145 s = UniCopyStr(str);
\r
1148 if (UniStrLen(s) == 0)
\r
1162 // 指定された文字列が数字かどうかチェック
\r
1163 bool UniIsNum(wchar_t *str)
\r
1165 char tmp[MAX_SIZE];
\r
1173 UniToStr(tmp, sizeof(tmp), str);
\r
1175 return IsNum(tmp);
\r
1179 // 中身が無い Unicode トークンリスト
\r
1180 UNI_TOKEN_LIST *UniNullToken()
\r
1182 UNI_TOKEN_LIST *ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
\r
1183 ret->Token = ZeroMalloc(0);
\r
1188 // 中身が無い Unicode トークンリスト (別名)
\r
1189 UNI_TOKEN_LIST *NullUniToken()
\r
1191 return UniNullToken();
\r
1194 // トークンリストを Unicode トークンリストに変換する
\r
1195 UNI_TOKEN_LIST *TokenListToUniTokenList(TOKEN_LIST *src)
\r
1197 UNI_TOKEN_LIST *ret;
\r
1205 ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
\r
1206 ret->NumTokens = src->NumTokens;
\r
1207 ret->Token = ZeroMalloc(sizeof(wchar_t *) * ret->NumTokens);
\r
1209 for (i = 0;i < ret->NumTokens;i++)
\r
1211 ret->Token[i] = CopyStrToUni(src->Token[i]);
\r
1217 // Unicode トークンリストをトークンリストに変換する
\r
1218 TOKEN_LIST *UniTokenListToTokenList(UNI_TOKEN_LIST *src)
\r
1228 ret = ZeroMalloc(sizeof(TOKEN_LIST));
\r
1229 ret->NumTokens = src->NumTokens;
\r
1230 ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
\r
1232 for (i = 0;i < ret->NumTokens;i++)
\r
1234 ret->Token[i] = CopyUniToStr(src->Token[i]);
\r
1241 wchar_t *UniCopyStr(wchar_t *str)
\r
1243 return CopyUniStr(str);
\r
1247 UNI_TOKEN_LIST *UniCopyToken(UNI_TOKEN_LIST *src)
\r
1249 UNI_TOKEN_LIST *ret;
\r
1257 ret = ZeroMalloc(sizeof(TOKEN_LIST));
\r
1258 ret->NumTokens = src->NumTokens;
\r
1259 ret->Token = ZeroMalloc(sizeof(wchar_t *) * ret->NumTokens);
\r
1260 for (i = 0;i < ret->NumTokens;i++)
\r
1262 ret->Token[i] = CopyUniStr(src->Token[i]);
\r
1268 // コマンドライン文字列をパースする
\r
1269 UNI_TOKEN_LIST *UniParseCmdLine(wchar_t *str)
\r
1271 UNI_TOKEN_LIST *t;
\r
1273 UINT i, len, wp, mode;
\r
1276 bool ignore_space = false;
\r
1281 return UniNullToken();
\r
1284 o = NewListFast(NULL);
\r
1285 tmp = Malloc(UniStrSize(str) + 32);
\r
1290 len = UniStrLen(str);
\r
1291 for (i = 0;i < len;i++)
\r
1299 if (c == L' ' || c == L'\t')
\r
1308 if (str[i + 1] == L'\"')
\r
1310 // 2 重の " は 1 個の " 文字として見なす
\r
1311 tmp[wp++] = L'\"';
\r
1316 // 1 個の " はスペース無視フラグを有効にする
\r
1317 ignore_space = true;
\r
1330 if (ignore_space == false && (c == L' ' || c == L'\t'))
\r
1336 Insert(o, UniCopyStr(tmp));
\r
1343 if (str[i + 1] == L'\"')
\r
1345 // 2 重の " は 1 個の " 文字として見なす
\r
1346 tmp[wp++] = L'\"';
\r
1351 if (ignore_space == false)
\r
1353 // 1 個の " はスペース無視フラグを有効にする
\r
1354 ignore_space = true;
\r
1358 // スペース無視フラグを無効にする
\r
1359 ignore_space = false;
\r
1375 Insert(o, UniCopyStr(tmp));
\r
1380 t = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
\r
1381 t->NumTokens = LIST_NUM(o);
\r
1382 t->Token = ZeroMalloc(sizeof(wchar_t *) * t->NumTokens);
\r
1383 for (i = 0;i < t->NumTokens;i++)
\r
1385 t->Token[i] = LIST_DATA(o, i);
\r
1393 // Unicode 文字列を 64bit 整数に変換する
\r
1394 UINT64 UniToInt64(wchar_t *str)
\r
1396 char tmp[MAX_SIZE];
\r
1403 UniToStr(tmp, sizeof(tmp), str);
\r
1405 return ToInt64(tmp);
\r
1408 // 64bit 整数を Unicode 文字列に変換する
\r
1409 void UniToStr64(wchar_t *str, UINT64 value)
\r
1411 char tmp[MAX_SIZE];
\r
1418 ToStr64(tmp, value);
\r
1420 StrToUni(str, 0, tmp);
\r
1423 // ANSI を UTF に変換する
\r
1424 UINT StrToUtf(char *utfstr, UINT size, char *str)
\r
1428 if (utfstr == NULL || str == NULL)
\r
1430 StrCpy(utfstr, size, "");
\r
1434 tmp = CopyStrToUtf(str);
\r
1436 StrCpy(utfstr, size, tmp);
\r
1440 return StrLen(utfstr);
\r
1443 // UTF を ANSI に変換する
\r
1444 UINT UtfToStr(char *str, UINT size, char *utfstr)
\r
1448 if (str == NULL || utfstr == NULL)
\r
1450 StrCpy(str, size, "");
\r
1454 tmp = CopyUtfToStr(utfstr);
\r
1456 StrCpy(str, size, tmp);
\r
1460 return StrLen(str);
\r
1463 // Unicode を UTF に変換する
\r
1464 UINT UniToUtf(char *utfstr, UINT size, wchar_t *unistr)
\r
1468 if (utfstr == NULL || unistr == NULL)
\r
1470 StrCpy(utfstr, size, "");
\r
1474 tmp = CopyUniToStr(unistr);
\r
1476 StrCpy(utfstr, size, tmp);
\r
1480 return StrLen(utfstr);
\r
1483 // UTF を Unicode に変換する
\r
1484 UINT UtfToUni(wchar_t *unistr, UINT size, char *utfstr)
\r
1488 if (unistr == NULL || utfstr == NULL)
\r
1490 UniStrCpy(unistr, size, L"");
\r
1494 tmp = CopyUtfToUni(utfstr);
\r
1496 UniStrCpy(unistr, size, tmp);
\r
1500 return UniStrLen(unistr);
\r
1503 // UTF8 文字列を Unicode 文字列にコピーする
\r
1504 wchar_t *CopyUtfToUni(char *utfstr)
\r
1510 if (utfstr == NULL)
\r
1515 utfstr_len = StrLen(utfstr);
\r
1517 size = CalcUtf8ToUni((BYTE *)utfstr, utfstr_len);
\r
1518 ret = ZeroMalloc(size + sizeof(wchar_t));
\r
1519 Utf8ToUni(ret, size, (BYTE *)utfstr, utfstr_len);
\r
1524 // UTF8 文字列を ANSI 文字列にコピーする
\r
1525 char *CopyUtfToStr(char *utfstr)
\r
1530 if (utfstr == NULL)
\r
1535 uni = CopyUtfToUni(utfstr);
\r
1538 return CopyStr("");
\r
1541 ret = CopyUniToStr(uni);
\r
1548 // Unicode 文字列を ANSI 文字列にコピーする
\r
1549 char *CopyUniToStr(wchar_t *unistr)
\r
1554 if (unistr == NULL)
\r
1559 str_size = CalcUniToStr(unistr);
\r
1560 if (str_size == 0)
\r
1562 return CopyStr("");
\r
1564 str = Malloc(str_size);
\r
1565 UniToStr(str, str_size, unistr);
\r
1570 // ANSI 文字列を Unicode 文字列にコピーする
\r
1571 wchar_t *CopyStrToUni(char *str)
\r
1581 uni_size = CalcStrToUni(str);
\r
1582 if (uni_size == 0)
\r
1584 return CopyUniStr(L"");
\r
1586 uni = Malloc(uni_size);
\r
1587 StrToUni(uni, uni_size, str);
\r
1592 // Unicode 文字列を UTF8 文字列にコピーする
\r
1593 char *CopyUniToUtf(wchar_t *unistr)
\r
1598 if (unistr == NULL)
\r
1603 size = CalcUniToUtf8(unistr);
\r
1604 ret = ZeroMalloc(size + sizeof(char));
\r
1606 UniToUtf8((char *)ret, size, unistr);
\r
1611 // ANSI 文字列を UTF8 文字列にコピーする
\r
1612 char *CopyStrToUtf(char *str)
\r
1622 unistr = CopyStrToUni(str);
\r
1623 if (unistr == NULL)
\r
1625 return CopyStr("");
\r
1628 ret = CopyUniToUtf(unistr);
\r
1635 // Unicode 文字列をコピーする
\r
1636 wchar_t *CopyUniStr(wchar_t *str)
\r
1646 len = UniStrLen(str);
\r
1647 dst = Malloc((len + 1) * sizeof(wchar_t));
\r
1648 UniStrCpy(dst, 0, str);
\r
1654 bool IsSafeUniStr(wchar_t *str)
\r
1663 len = UniStrLen(str);
\r
1664 for (i = 0;i < len;i++)
\r
1666 if (IsSafeUniChar(str[i]) == false)
\r
1671 if (str[0] == L' ')
\r
1677 if (str[len - 1] == L' ')
\r
1686 bool IsSafeUniChar(wchar_t c)
\r
1689 wchar_t *check_str =
\r
1690 L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
\r
1691 L"abcdefghijklmnopqrstuvwxyz"
\r
1695 len = UniStrLen(check_str);
\r
1696 for (i = 0;i < len;i++)
\r
1698 if (c == check_str[i])
\r
1706 // UTF-8 文字列を ANSI 文字列に変換する
\r
1707 UINT Utf8ToStr(char *str, UINT str_size, BYTE *u, UINT size)
\r
1709 UINT ret, uni_size;
\r
1712 if (u == NULL || str == NULL)
\r
1718 uni_size = CalcUtf8ToUni(u, size);
\r
1719 if (uni_size == 0)
\r
1721 if (str_size >= 1)
\r
1723 StrCpy(str, 0, "");
\r
1727 tmp = Malloc(uni_size);
\r
1728 Utf8ToUni(tmp, uni_size, u, size);
\r
1731 ret = UniToStr(str, str_size, tmp);
\r
1737 // UTF-8 文字列を ANSI 文字列に変換した場合に必要なサイズを取得する
\r
1738 UINT CalcUtf8ToStr(BYTE *u, UINT size)
\r
1740 UINT ret, uni_size;
\r
1749 uni_size = CalcUtf8ToUni(u, size);
\r
1750 if (uni_size == 0)
\r
1754 tmp = Malloc(uni_size);
\r
1755 Utf8ToUni(tmp, uni_size, u, size);
\r
1758 ret = CalcUniToStr(tmp);
\r
1764 // ANSI 文字列を UTF-8 文字列に変換する
\r
1765 UINT StrToUtf8(BYTE *u, UINT size, char *str)
\r
1767 UINT ret, uni_size;
\r
1770 if (u == NULL || str == NULL)
\r
1776 uni_size = CalcStrToUni(str);
\r
1777 if (uni_size == 0)
\r
1781 tmp = Malloc(uni_size);
\r
1782 StrToUni(tmp, uni_size, str);
\r
1785 ret = UniToUtf8(u, size, tmp);
\r
1792 // ANSI 文字列を UTF-8 文字列に変換するために必要なサイズを取得する
\r
1793 UINT CalcStrToUtf8(char *str)
\r
1805 uni_size = CalcStrToUni(str);
\r
1806 if (uni_size == 0)
\r
1810 tmp = Malloc(uni_size);
\r
1811 StrToUni(tmp, uni_size, str);
\r
1813 // UTF-8 に変換した場合のサイズを取得する
\r
1814 ret = CalcUniToUtf8(tmp);
\r
1820 // Unicode 文字列を ANSI 文字列に変換する
\r
1821 UINT UniToStr(char *str, UINT size, wchar_t *s)
\r
1828 if (s == NULL || str == NULL)
\r
1833 new_size = CalcUniToStr(s);
\r
1834 if (new_size == 0)
\r
1838 StrCpy(str, 0, "");
\r
1842 tmp = Malloc(new_size);
\r
1844 wcstombs(tmp, s, new_size);
\r
1845 tmp[new_size - 1] = 0;
\r
1846 ret = StrCpy(str, size, tmp);
\r
1851 return UnixUniToStr(str, size, s);
\r
1852 #endif // OS_WIN32
\r
1855 // Unicode 文字列を ANSI 文字列に変換するための必要なバイト数を取得する
\r
1856 UINT CalcUniToStr(wchar_t *s)
\r
1866 ret = (UINT)wcstombs(NULL, s, UniStrLen(s));
\r
1867 if (ret == (UINT)-1)
\r
1874 return UnixCalcUniToStr(s);
\r
1875 #endif // OS_WIN32
\r
1878 // ANSI 文字列を Unicode 文字列に変換する
\r
1879 UINT StrToUni(wchar_t *s, UINT size, char *str)
\r
1886 if (s == NULL || str == NULL)
\r
1891 new_size = CalcStrToUni(str);
\r
1892 if (new_size == 0)
\r
1896 UniStrCpy(s, 0, L"");
\r
1900 tmp = Malloc(new_size);
\r
1902 mbstowcs(tmp, str, StrLen(str));
\r
1903 tmp[(new_size - 1) / sizeof(wchar_t)] = 0;
\r
1904 ret = UniStrCpy(s, size, tmp);
\r
1909 return UnixStrToUni(s, size, str);
\r
1910 #endif // OS_WIN32
\r
1913 // ANSI 文字列を Unicode 文字列に変換するための必要なバイト数を取得する
\r
1914 UINT CalcStrToUni(char *str)
\r
1924 ret = (UINT)mbstowcs(NULL, str, StrLen(str));
\r
1925 if (ret == (UINT)-1)
\r
1930 return (ret + 1) * sizeof(wchar_t);
\r
1932 return UnixCalcStrToUni(str);
\r
1933 #endif // OS_WIN32
\r
1936 // UTF-8 文字列を Unicode 文字列に変換する
\r
1937 UINT Utf8ToUni(wchar_t *s, UINT size, BYTE *u, UINT u_size)
\r
1941 if (s == NULL || u == NULL)
\r
1947 size = 0x3fffffff;
\r
1951 u_size = StrLen((char *)u);
\r
1963 type = GetUtf8Type(u, u_size, i);
\r
1975 c1 = (((u[i] & 0x1c) >> 2) & 0x07);
\r
1976 c2 = (((u[i] & 0x03) << 6) & 0xc0) | (u[i + 1] & 0x3f);
\r
1979 c1 = ((((u[i] & 0x0f) << 4) & 0xf0)) | (((u[i + 1] & 0x3c) >> 2) & 0x0f);
\r
1980 c2 = (((u[i + 1] & 0x03) << 6) & 0xc0) | (u[i + 2] & 0x3f);
\r
1987 if (IsBigEndian())
\r
1989 if (sizeof(wchar_t) == 2)
\r
1991 ((BYTE *)&c)[0] = c1;
\r
1992 ((BYTE *)&c)[1] = c2;
\r
1996 ((BYTE *)&c)[2] = c1;
\r
1997 ((BYTE *)&c)[3] = c2;
\r
2002 ((BYTE *)&c)[0] = c2;
\r
2003 ((BYTE *)&c)[1] = c1;
\r
2006 if (wp < ((size / sizeof(wchar_t)) - 1))
\r
2017 if (wp < (size / sizeof(wchar_t)))
\r
2025 // UTF-8 を Unicode に変換した場合のバッファサイズを取得する
\r
2026 UINT CalcUtf8ToUni(BYTE *u, UINT u_size)
\r
2035 u_size = StrLen((char *)u);
\r
2038 return (Utf8Len(u, u_size) + 1) * sizeof(wchar_t);
\r
2041 // UTF-8 文字列の文字数を取得する
\r
2042 UINT Utf8Len(BYTE *u, UINT size)
\r
2052 size = StrLen((char *)u);
\r
2060 type = GetUtf8Type(u, size, i);
\r
2072 // Unicode 文字列を UTF-8 文字列に変換する
\r
2073 UINT UniToUtf8(BYTE *u, UINT size, wchar_t *s)
\r
2075 UINT i, len, type, wp;
\r
2077 if (u == NULL || s == NULL)
\r
2083 size = 0x3fffffff;
\r
2086 len = UniStrLen(s);
\r
2088 for (i = 0;i < len;i++)
\r
2093 if (IsBigEndian())
\r
2095 if (sizeof(wchar_t) == 2)
\r
2097 c1 = ((BYTE *)&c)[0];
\r
2098 c2 = ((BYTE *)&c)[1];
\r
2102 c1 = ((BYTE *)&c)[2];
\r
2103 c2 = ((BYTE *)&c)[3];
\r
2108 c1 = ((BYTE *)&c)[1];
\r
2109 c2 = ((BYTE *)&c)[0];
\r
2112 type = GetUniType(s[i]);
\r
2124 u[wp++] = 0xc0 | (((((c1 & 0x07) << 2) & 0x1c)) | (((c2 & 0xc0) >> 6) & 0x03));
\r
2128 u[wp++] = 0x80 | (c2 & 0x3f);
\r
2134 u[wp++] = 0xe0 | (((c1 & 0xf0) >> 4) & 0x0f);
\r
2138 u[wp++] = 0x80 | (((c1 & 0x0f) << 2) & 0x3c) | (((c2 & 0xc0) >> 6) & 0x03);
\r
2142 u[wp++] = 0x80 | (c2 & 0x3f);
\r
2154 // Unicode 文字列を UTF-8 文字列に変換した場合の文字列長を計算する
\r
2155 UINT CalcUniToUtf8(wchar_t *s)
\r
2157 UINT i, len, size;
\r
2165 len = UniStrLen(s);
\r
2166 for (i = 0;i < len;i++)
\r
2168 size += GetUniType(s[i]);
\r
2174 // s で始まる UTF-8 文字列の offset 番地の最初の 1 文字が何バイトで構成されているかを取得
\r
2175 UINT GetUtf8Type(BYTE *s, UINT size, UINT offset)
\r
2182 if ((offset + 1) > size)
\r
2186 if ((s[offset] & 0x80) == 0)
\r
2191 if ((s[offset] & 0x20) == 0)
\r
2194 if ((offset + 2) > size)
\r
2201 if ((offset + 3) > size)
\r
2208 // 文字 c を UTF-8 に変換した場合の種類 (バイト数)
\r
2209 UINT GetUniType(wchar_t c)
\r
2213 if (IsBigEndian())
\r
2215 if (sizeof(wchar_t) == 2)
\r
2217 c1 = ((BYTE *)&c)[0];
\r
2218 c2 = ((BYTE *)&c)[1];
\r
2222 c1 = ((BYTE *)&c)[2];
\r
2223 c2 = ((BYTE *)&c)[3];
\r
2228 c1 = ((BYTE *)&c)[1];
\r
2229 c2 = ((BYTE *)&c)[0];
\r
2245 if ((c1 & 0xf8) == 0)
\r
2254 // 文字列の置換 (大文字小文字を区別しない)
\r
2255 UINT UniReplaceStri(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword)
\r
2257 return UniReplaceStrEx(dst, size, string, old_keyword, new_keyword, false);
\r
2260 // 文字列の置換 (大文字小文字を区別する)
\r
2261 UINT UniReplaceStr(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword)
\r
2263 return UniReplaceStrEx(dst, size, string, old_keyword, new_keyword, true);
\r
2267 UINT UniReplaceStrEx(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword, bool case_sensitive)
\r
2269 UINT i, j, num, len_string, len_old, len_new, len_ret, wp;
\r
2272 if (string == NULL || old_keyword == NULL || new_keyword == NULL)
\r
2278 len_string = UniStrLen(string);
\r
2279 len_old = UniStrLen(old_keyword);
\r
2280 len_new = UniStrLen(new_keyword);
\r
2283 len_ret = UniCalcReplaceStrEx(string, old_keyword, new_keyword, case_sensitive);
\r
2285 ret = Malloc((len_ret + 1) * sizeof(wchar_t));
\r
2289 i = j = num = wp = 0;
\r
2292 i = UniSearchStrEx(string, old_keyword, i, case_sensitive);
\r
2293 if (i == INFINITE)
\r
2295 Copy(&ret[wp], &string[j], (len_string - j) * sizeof(wchar_t));
\r
2296 wp += len_string - j;
\r
2300 Copy(&ret[wp], &string[j], (i - j) * sizeof(wchar_t));
\r
2302 Copy(&ret[wp], new_keyword, len_new * sizeof(wchar_t));
\r
2309 UniStrCpy(dst, size, ret);
\r
2317 // 文字列の置換後の文字列長を計算する
\r
2318 UINT UniCalcReplaceStrEx(wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword, bool case_sensitive)
\r
2321 UINT len_string, len_old, len_new;
\r
2323 if (string == NULL || old_keyword == NULL || new_keyword == NULL)
\r
2329 len_string = UniStrLen(string);
\r
2330 len_old = UniStrLen(old_keyword);
\r
2331 len_new = UniStrLen(new_keyword);
\r
2333 if (len_old == len_new)
\r
2335 return len_string;
\r
2343 i = UniSearchStrEx(string, old_keyword, i, case_sensitive);
\r
2344 if (i == INFINITE)
\r
2353 return len_string + len_new * num - len_old * num;
\r
2356 // 文字列の検索 (大文字 / 小文字を区別する)
\r
2357 UINT UniSearchStr(wchar_t *string, wchar_t *keyword, UINT start)
\r
2359 return UniSearchStrEx(string, keyword, start, true);
\r
2362 // 文字列の検索 (大文字 / 小文字を区別しない)
\r
2363 UINT UniSearchStri(wchar_t *string, wchar_t *keyword, UINT start)
\r
2365 return UniSearchStrEx(string, keyword, start, false);
\r
2368 // 文字列 string から文字列 keyword を検索して最初に見つかった文字の場所を返す
\r
2369 // (1文字目に見つかったら 0, 見つからなかったら INFINITE)
\r
2370 UINT UniSearchStrEx(wchar_t *string, wchar_t *keyword, UINT start, bool case_sensitive)
\r
2372 UINT len_string, len_keyword;
\r
2374 wchar_t *cmp_string, *cmp_keyword;
\r
2377 if (string == NULL || keyword == NULL)
\r
2383 len_string = UniStrLen(string);
\r
2384 if (len_string <= start)
\r
2391 len_keyword = UniStrLen(keyword);
\r
2392 if (len_keyword == 0)
\r
2398 if (len_string < len_keyword)
\r
2403 if (len_string == len_keyword)
\r
2405 if (case_sensitive)
\r
2407 if (UniStrCmp(string, keyword) == 0)
\r
2418 if (UniStrCmpi(string, keyword) == 0)
\r
2429 if (case_sensitive)
\r
2431 cmp_string = string;
\r
2432 cmp_keyword = keyword;
\r
2436 cmp_string = Malloc((len_string + 1) * sizeof(wchar_t));
\r
2437 UniStrCpy(cmp_string, (len_string + 1) * sizeof(wchar_t), string);
\r
2438 cmp_keyword = Malloc((len_keyword + 1) * sizeof(wchar_t));
\r
2439 UniStrCpy(cmp_keyword, (len_keyword + 1) * sizeof(wchar_t), keyword);
\r
2440 UniStrUpper(cmp_string);
\r
2441 UniStrUpper(cmp_keyword);
\r
2446 for (i = start;i < (len_string - len_keyword + 1);i++)
\r
2449 if (!wcsncmp(&cmp_string[i], cmp_keyword, len_keyword))
\r
2457 if (case_sensitive == false)
\r
2460 Free(cmp_keyword);
\r
2464 if (found == false)
\r
2472 void UniFreeToken(UNI_TOKEN_LIST *tokens)
\r
2475 if (tokens == NULL)
\r
2479 for (i = 0;i < tokens->NumTokens;i++)
\r
2481 Free(tokens->Token[i]);
\r
2483 Free(tokens->Token);
\r
2488 UNI_TOKEN_LIST *UnixUniParseToken(wchar_t *src, wchar_t *separator)
\r
2490 UNI_TOKEN_LIST *ret;
\r
2496 if (src == NULL || separator == NULL)
\r
2498 ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
\r
2499 ret->Token = ZeroMalloc(0);
\r
2503 src_s = CopyUniToStr(src);
\r
2504 sep_s = CopyUniToStr(separator);
\r
2506 t = ParseToken(src_s, sep_s);
\r
2508 ret = TokenListToUniTokenList(t);
\r
2518 UNI_TOKEN_LIST *UniParseToken(wchar_t *src, wchar_t *separator)
\r
2521 UNI_TOKEN_LIST *ret;
\r
2523 wchar_t *str1, *str2;
\r
2527 wchar_t *state = NULL;
\r
2533 ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
\r
2534 ret->Token = ZeroMalloc(0);
\r
2537 if (separator == NULL)
\r
2539 separator = L" .\t\r\n";
\r
2541 len = UniStrLen(src);
\r
2542 str1 = Malloc((len + 1) * sizeof(wchar_t));
\r
2543 str2 = Malloc((len + 1) * sizeof(wchar_t));
\r
2544 UniStrCpy(str1, 0, src);
\r
2545 UniStrCpy(str2, 0, src);
\r
2549 tmp = wcstok(str1, separator
\r
2555 while (tmp != NULL)
\r
2558 tmp = wcstok(NULL, separator
\r
2564 ret = Malloc(sizeof(UNI_TOKEN_LIST));
\r
2565 ret->NumTokens = num;
\r
2566 ret->Token = (wchar_t **)Malloc(sizeof(wchar_t *) * num);
\r
2568 tmp = wcstok(str2, separator
\r
2573 while (tmp != NULL)
\r
2575 ret->Token[num] = (wchar_t *)Malloc((UniStrLen(tmp) + 1) * sizeof(wchar_t));
\r
2576 UniStrCpy(ret->Token[num], 0, tmp);
\r
2578 tmp = wcstok(NULL, separator
\r
2585 Unlock(token_lock);
\r
2591 return UnixUniParseToken(src, separator);
\r
2592 #endif // OS_WIN32
\r
2596 bool UniGetLine(wchar_t *str, UINT size)
\r
2599 return UniGetLineWin32(str, size);
\r
2601 return UniGetLineUnix(str, size);
\r
2602 #endif // OS_WIN32
\r
2604 void AnsiGetLineUnix(char *str, UINT size)
\r
2609 char tmp[MAX_SIZE];
\r
2610 fgets(tmp, sizeof(tmp) - 1, stdin);
\r
2619 fgets(str, (int)(size - 1), stdin);
\r
2623 bool UniGetLineUnix(wchar_t *str, UINT size)
\r
2626 UINT str_a_size = size;
\r
2627 if (str == NULL || size < sizeof(wchar_t))
\r
2631 if (str_a_size >= 0x7fffffff)
\r
2633 str_a_size = MAX_SIZE;
\r
2637 str_a = ZeroMalloc(str_a_size);
\r
2639 AnsiGetLineUnix(str_a, str_a_size);
\r
2641 StrToUni(str, size, str_a);
\r
2647 bool UniGetLineWin32(wchar_t *str, UINT size)
\r
2652 ret = Win32InputW(str, size);
\r
2653 #endif // OS_WIN32
\r
2659 void UniTrimCrlf(wchar_t *str)
\r
2667 len = UniStrLen(str);
\r
2673 if (str[len - 1] == L'\n')
\r
2675 if (len >= 2 && str[len - 2] == L'\r')
\r
2681 else if(str[len - 1] == L'\r')
\r
2688 void UniTrim(wchar_t *str)
\r
2697 UniTrimRight(str);
\r
2701 void UniTrimRight(wchar_t *str)
\r
2703 wchar_t *buf, *tmp;
\r
2704 UINT len, i, wp, wp2;
\r
2711 len = UniStrLen(str);
\r
2716 if (str[len - 1] != L' ' && str[len - 1] != L'\t')
\r
2721 buf = Malloc((len + 1) * sizeof(wchar_t));
\r
2722 tmp = Malloc((len + 1) * sizeof(wchar_t));
\r
2725 for (i = 0;i < len;i++)
\r
2727 if (str[i] != L' ' && str[i] != L'\t')
\r
2729 Copy(&buf[wp], tmp, wp2 * sizeof(wchar_t));
\r
2732 buf[wp++] = str[i];
\r
2736 tmp[wp2++] = str[i];
\r
2740 UniStrCpy(str, 0, buf);
\r
2746 void UniTrimLeft(wchar_t *str)
\r
2756 len = UniStrLen(str);
\r
2761 if (str[0] != L' ' && str[0] != L'\t')
\r
2766 buf = Malloc((len + 1) * sizeof(wchar_t));
\r
2769 for (i = 0;i < len;i++)
\r
2771 if (str[i] != L' ' && str[i] != L'\t')
\r
2777 buf[wp++] = str[i];
\r
2781 UniStrCpy(str, 0, buf);
\r
2785 // 整数を 16 進文字列に変換 (8桁固定)
\r
2786 void UniToStrx8(wchar_t *str, UINT i)
\r
2788 UniFormat(str, 0, L"0x%08x", i);
\r
2792 void UniToStrx(wchar_t *str, UINT i)
\r
2794 UniFormat(str, 0, L"0x%02x", i);
\r
2798 void UniToStri(wchar_t *str, int i)
\r
2800 UniFormat(str, 0, L"%i", i);
\r
2804 void UniToStru(wchar_t *str, UINT i)
\r
2806 UniFormat(str, 0, L"%u", i);
\r
2810 int UniToInti(wchar_t *str)
\r
2819 UniToStr(tmp, sizeof(tmp), str);
\r
2821 return ToInt(tmp);
\r
2825 UINT UniToInt(wchar_t *str)
\r
2834 UniToStr(tmp, sizeof(tmp), str);
\r
2836 return ToInti(tmp);
\r
2839 // 64bit 用フォーマット文字列置換
\r
2840 wchar_t *UniReplaceFormatStringFor64(wchar_t *fmt)
\r
2851 tmp_size = UniStrSize(fmt) * 2;
\r
2852 tmp = ZeroMalloc(tmp_size);
\r
2855 UniReplaceStrEx(tmp, tmp_size, fmt, L"%ll", L"%I64", false);
\r
2857 UniReplaceStrEx(tmp, tmp_size, fmt, L"%I64", L"%ll", false);
\r
2863 len = UniStrLen(tmp);
\r
2864 for (i = 0;i < len;i++)
\r
2866 if (tmp[i] == L'%')
\r
2892 if (tmp[i] == L's')
\r
2896 else if (tmp[i] == L'S')
\r
2907 #endif // OS_WIN32
\r
2909 ret = CopyUniStr(tmp);
\r
2916 void UniPrintStr(wchar_t *string)
\r
2919 if (string == NULL)
\r
2927 char *str = CopyUniToStr(string);
\r
2931 fputs(str, stdout);
\r
2935 fputs("", stdout);
\r
2941 Win32PrintW(string);
\r
2946 void UniPrintArgs(wchar_t *fmt, va_list args)
\r
2955 str = InternalFormatArgs(fmt, args, false);
\r
2963 void UniPrint(wchar_t *fmt, ...)
\r
2972 va_start(args, fmt);
\r
2973 UniPrintArgs(fmt, args);
\r
2977 // デバッグ文字列を引数付きで表示する
\r
2978 void UniDebugArgs(wchar_t *fmt, va_list args)
\r
2980 if (g_debug == false)
\r
2985 UniPrintArgs(fmt, args);
\r
2989 void UniDebug(wchar_t *fmt, ...)
\r
2998 va_start(args, fmt);
\r
2999 UniDebugArgs(fmt, args);
\r
3003 // 文字列をフォーマットする (引数リスト)
\r
3004 void UniFormatArgs(wchar_t *buf, UINT size, wchar_t *fmt, va_list args)
\r
3008 if (buf == NULL || fmt == NULL)
\r
3018 KS_INC(KS_FORMAT_COUNT);
\r
3020 ret = InternalFormatArgs(fmt, args, false);
\r
3022 UniStrCpy(buf, size, ret);
\r
3027 // 文字列をフォーマットして結果をコピーする
\r
3028 wchar_t *CopyUniFormat(wchar_t *fmt, ...)
\r
3030 wchar_t *ret, *str;
\r
3039 size = MAX(UniStrSize(fmt) * 10, MAX_SIZE * 10);
\r
3040 str = Malloc(size);
\r
3042 va_start(args, fmt);
\r
3043 UniFormatArgs(str, size, fmt, args);
\r
3045 ret = UniCopyStr(str);
\r
3053 void UniFormat(wchar_t *buf, UINT size, wchar_t *fmt, ...)
\r
3057 if (buf == NULL || fmt == NULL)
\r
3062 va_start(args, fmt);
\r
3063 UniFormatArgs(buf, size, fmt, args);
\r
3068 int UniSoftStrCmp(wchar_t *str1, wchar_t *str2)
\r
3071 wchar_t *tmp1, *tmp2;
\r
3073 if (str1 == NULL && str2 == NULL)
\r
3086 tmp1 = CopyUniStr(str1);
\r
3087 tmp2 = CopyUniStr(str2);
\r
3092 ret = UniStrCmpi(tmp1, tmp2);
\r
3100 // 文字列を大文字・小文字を区別せずに比較する
\r
3101 int UniStrCmpi(wchar_t *str1, wchar_t *str2)
\r
3105 if (str1 == NULL && str2 == NULL)
\r
3123 c1 = UniToUpper(str1[i]);
\r
3124 c2 = UniToUpper(str2[i]);
\r
3133 if (str1[i] == 0 || str2[i] == 0)
\r
3142 int UniStrCmp(wchar_t *str1, wchar_t *str2)
\r
3145 if (str1 == NULL && str2 == NULL)
\r
3158 return wcscmp(str1, str2);
\r
3162 void UniStrLower(wchar_t *str)
\r
3171 len = UniStrLen(str);
\r
3172 for (i = 0;i < len;i++)
\r
3174 str[i] = UniToLower(str[i]);
\r
3179 void UniStrUpper(wchar_t *str)
\r
3188 len = UniStrLen(str);
\r
3189 for (i = 0;i < len;i++)
\r
3191 str[i] = UniToUpper(str[i]);
\r
3196 wchar_t UniToLower(wchar_t c)
\r
3198 if (c >= L'A' && c <= L'Z')
\r
3207 wchar_t UniToUpper(wchar_t c)
\r
3209 if (c >= L'a' && c <= L'z')
\r
3218 UINT UniStrCat(wchar_t *dst, UINT size, wchar_t *src)
\r
3220 UINT len1, len2, len_test;
\r
3222 if (dst == NULL || src == NULL)
\r
3226 if (size != 0 && size < sizeof(wchar_t))
\r
3230 if (size == sizeof(wchar_t))
\r
3238 size = 0x3fffffff;
\r
3241 len1 = UniStrLen(dst);
\r
3242 len2 = UniStrLen(src);
\r
3243 len_test = len1 + len2 + 1;
\r
3244 if (len_test > (size / sizeof(wchar_t)))
\r
3246 if (len2 <= (len_test - (size / sizeof(wchar_t))))
\r
3250 len2 -= len_test - (size / sizeof(wchar_t));
\r
3252 Copy(&dst[len1], src, len2 * sizeof(wchar_t));
\r
3253 dst[len1 + len2] = 0;
\r
3255 return len1 + len2;
\r
3257 UINT UniStrCatLeft(wchar_t *dst, UINT size, wchar_t *src)
\r
3261 if (dst == NULL || src == NULL)
\r
3266 s = UniCopyStr(dst);
\r
3267 UniStrCpy(dst, size, s);
\r
3268 UniStrCat(dst, size, src);
\r
3271 return UniStrLen(dst);
\r
3275 UINT UniStrCpy(wchar_t *dst, UINT size, wchar_t *src)
\r
3279 if (dst == NULL || src == NULL)
\r
3281 if (src == NULL && dst != NULL)
\r
3283 if (size >= sizeof(wchar_t))
\r
3292 return UniStrLen(src);
\r
3294 if (size != 0 && size < sizeof(wchar_t))
\r
3298 if (size == sizeof(wchar_t))
\r
3306 size = 0x3fffffff;
\r
3310 len = UniStrLen(src);
\r
3311 if (len <= (size / sizeof(wchar_t) - 1))
\r
3313 Copy(dst, src, (len + 1) * sizeof(wchar_t));
\r
3317 len = size / 2 - 1;
\r
3318 Copy(dst, src, len * sizeof(wchar_t));
\r
3325 // 文字が指定されたバッファサイズ以内かどうかチェック
\r
3326 bool UniCheckStrSize(wchar_t *str, UINT size)
\r
3329 if (str == NULL || size <= 1)
\r
3334 return UniCheckStrLen(str, size / sizeof(wchar_t) - 1);
\r
3337 // 文字数が指定された長さ以内かどうかチェック
\r
3338 bool UniCheckStrLen(wchar_t *str, UINT len)
\r
3362 // 文字列の格納に必要なバッファサイズの取得
\r
3363 UINT UniStrSize(wchar_t *str)
\r
3371 return (UniStrLen(str) + 1) * sizeof(wchar_t);
\r
3375 UINT UniStrLen(wchar_t *str)
\r