• R/O
  • SSH
  • HTTPS

ttssh2: Commit


Commit MetaInfo

Revision9471 (tree)
Time2021-10-14 23:52:23
Authorzmatsuo

Log Message

TTProxyのログをログフォルダへ出力

- ファイル保存(コモンダイアログ)をUnicode版に変更

- GetSaveFileNameW()

- logger

- logger::open() を Unicodeファイル名に変更
- ログフォルダ設定を追加
- logger::set_folder()

- IniFile

- IniFile::getStringW() を追加
- Unicode文字列を取得
- Unicode版エスケープ文字展開が必要になった
- StringUtil::escapeW(), unescapeW()

- StringUtil

- StringUtil::escapeW() unescapeW() 追加
- WStringBuffer クラスが必要になった

- WStringBuffer

- 追加
- StringBufferのwchar_t版

- YCL/Windows.h

- GetWindowTextLengthW(),SetWindowTextLengthW() を追加
- Unicode文字列の設定,取得

- ttlib_static.cpp

- IsRelativePathW() を追加

Change Summary

Incremental Difference

--- trunk/TTProxy/CMakeLists.txt (revision 9470)
+++ trunk/TTProxy/CMakeLists.txt (revision 9471)
@@ -70,7 +70,6 @@
7070 PRIVATE
7171 YCL/include/YCL/Array.h
7272 YCL/include/YCL/ComboBoxCtrl.h
73- YCL/include/YCL/common.h
7473 YCL/include/YCL/Dialog.h
7574 YCL/include/YCL/DynamicLinkLibrary.h
7675 YCL/include/YCL/EditBoxCtrl.h
@@ -88,8 +87,10 @@
8887 YCL/include/YCL/StringUtil.h
8988 YCL/include/YCL/ValueCtrl.h
9089 YCL/include/YCL/Vector.h
90+ YCL/include/YCL/WString.h
91+ YCL/include/YCL/WStringBuffer.h
9192 YCL/include/YCL/Window.h
92- YCL/include/YCL/wstring.h
93+ YCL/include/YCL/common.h
9394 )
9495
9596 source_group(
--- trunk/TTProxy/Logger.h (revision 9470)
+++ trunk/TTProxy/Logger.h (revision 9471)
@@ -7,6 +7,7 @@
77 class Logger {
88 private:
99 HANDLE logfile;
10+ WString folder_;
1011 Logger():logfile(INVALID_HANDLE_VALUE) {
1112 }
1213 public:
@@ -78,15 +79,26 @@
7879 }
7980
8081 public:
81- static void open(String filename) {
82+ static void open(WString filename) {
8283 close();
83- if (filename != NULL) {
84- HANDLE logfile = ::CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
85- if (logfile != INVALID_HANDLE_VALUE) {
86- ::SetFilePointer(logfile, 0, NULL, FILE_END);
87- instance().logfile = logfile;
88- }
84+
85+ if (filename == NULL) {
86+ return;
8987 }
88+
89+ WString full_filename;
90+ if (IsRelativePathW(filename)) {
91+ full_filename = instance().folder_ + L"\\" + filename;
92+ }
93+ else {
94+ full_filename = filename;
95+ }
96+
97+ HANDLE logfile = ::CreateFileW(full_filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
98+ if (logfile != INVALID_HANDLE_VALUE) {
99+ ::SetFilePointer(logfile, 0, NULL, FILE_END);
100+ instance().logfile = logfile;
101+ }
90102 }
91103 static void close() {
92104 if (instance().logfile != INVALID_HANDLE_VALUE) {
@@ -100,6 +112,9 @@
100112 static void log(const char* label, const unsigned char* data, int size) {
101113 instance().debuglog_binary(label, data, size);
102114 }
115+ static void set_folder(const WString &folder) {
116+ instance().folder_ = folder;
117+ }
103118 };
104119
105120 #endif//_YEBISOCKS_LOGGER_H_
--- trunk/TTProxy/ProxyWSockHook.h (revision 9470)
+++ trunk/TTProxy/ProxyWSockHook.h (revision 9471)
@@ -726,30 +726,29 @@
726726 protected:
727727 virtual bool dispatch(UINT message, WPARAM wParam, LPARAM lParam) {
728728 if (message == WM_COMMAND && wParam == MAKEWPARAM(IDC_REFER, BN_CLICKED)) {
729- char buffer[1024];
730- char uimsg[MAX_UIMSG];
731- OPENFILENAME ofn = {
732- sizeof ofn,
733- *this,
734- };
729+ wchar_t buffer[1024];
730+ wchar_t uimsg[MAX_UIMSG];
731+ OPENFILENAMEW ofn = {};
732+ ofn.lStructSize = get_OPENFILENAME_SIZEW();
733+ ofn.hwndOwner = *this;
735734 ofn.lpstrFile = buffer;
736- ofn.nMaxFile = countof(buffer);
735+ ofn.nMaxFile = _countof(buffer);
737736 ofn.Flags = OFN_LONGNAMES | OFN_NONETWORKBUTTON | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN | OFN_HIDEREADONLY;
738- UTIL_get_lang_msg("MSG_LOGFILE_SELECT", uimsg, sizeof(uimsg),
739- "Select Logfile");
737+ UTIL_get_lang_msgW("MSG_LOGFILE_SELECT", uimsg, _countof(uimsg),
738+ L"Select Logfile");
740739 ofn.lpstrTitle = uimsg;
741740 if (logfile != NULL) {
742- strcpy_s(buffer, sizeof buffer, logfile);
741+ wcscpy_s(buffer, _countof(buffer), logfile);
743742 }else{
744743 buffer[0] = '\0';
745744 }
746- if (::GetSaveFileName(&ofn)) {
745+ if (::GetSaveFileNameW(&ofn)) {
747746 if (buffer[0] != '\0') {
748747 logfile = buffer;
749748 }else{
750749 logfile = NULL;
751750 }
752- log.SetWindowText(buffer);
751+ log.SetWindowTextW(buffer);
753752 }
754753 return true;
755754 }
@@ -806,7 +805,7 @@
806805 erro.SetWindowText(ErrorMessage);
807806
808807 if (logfile != NULL)
809- log.SetWindowText(logfile);
808+ log.SetWindowTextW(logfile);
810809
811810 CenterWindow((HWND)*this, GetParent());
812811
@@ -835,7 +834,7 @@
835834 ConnectedMessage = conn.GetWindowText();
836835 ErrorMessage = erro.GetWindowText();
837836
838- logfile = log.GetWindowTextLength() > 0 ? log.GetWindowText() : NULL;
837+ logfile = log.GetWindowTextLengthW() > 0 ? log.GetWindowTextW() : NULL;
839838
840839 Dialog::onOK();
841840 }
@@ -843,7 +842,7 @@
843842 Dialog::onCancel();
844843 }
845844 public:
846- String logfile;
845+ WString logfile;
847846 int timeout;
848847 int resolve;
849848
@@ -1089,11 +1088,11 @@
10891088 };
10901089 SetI18nDlgStrsW(hWnd, "TTProxy", text_info, _countof(text_info), UILanguageFileW);
10911090
1092- UTIL_get_lang_msgW("DLG_ABOUT_EXTENSION", uimsg, sizeof(uimsg),
1091+ UTIL_get_lang_msgW("DLG_ABOUT_EXTENSION", uimsg, _countof(uimsg),
10931092 L"Tera Term proxy extension");
1094- UTIL_get_lang_msgW("DLG_ABOUT_YEBISUYA", uimsg2, sizeof(uimsg2),
1093+ UTIL_get_lang_msgW("DLG_ABOUT_YEBISUYA", uimsg2, _countof(uimsg2),
10951094 L"YebisuyaHompo");
1096- UTIL_get_lang_msgW("DLG_ABOUT_HOMEPAGE", uimsg3, sizeof(uimsg3),
1095+ UTIL_get_lang_msgW("DLG_ABOUT_HOMEPAGE", uimsg3, _countof(uimsg3),
10971096 L"TTProxy home page");
10981097 GetDlgItemTextW(hWnd, IDC_VERSION, buf, _countof(buf));
10991098 len = wcslen(buf) + 50;
@@ -2146,7 +2145,7 @@
21462145 return ORIG_closesocket(s);
21472146 }
21482147
2149- String logfile;
2148+ WString logfile;
21502149 int timeout;
21512150 enum SocksResolve {
21522151 RESOLVE_AUTO,
@@ -2218,7 +2217,7 @@
22182217 prompt_table[3] = ini.getString("TelnetConnectedMessage", "-- Connected to ");
22192218 prompt_table[4] = ini.getString("TelnetErrorMessage", "!!!!!!!!");
22202219
2221- logfile = ini.getString("DebugLog");
2220+ logfile = ini.getStringW(L"DebugLog");
22222221 Logger::open(logfile);
22232222 }
22242223 void _save(IniFile& ini) {
@@ -2269,7 +2268,7 @@
22692268 ini.setString("TelnetConnectedMessage", prompt_table[3]);
22702269 ini.setString("TelnetErrorMessage", prompt_table[4]);
22712270
2272- ini.setString("DebugLog", logfile);
2271+ ini.setString(L"DebugLog", logfile);
22732272 }
22742273 public:
22752274 static void setOwner(HWND owner) {
@@ -2348,7 +2347,7 @@
23482347 static String generateURL() {
23492348 return instance().defaultProxy.generateURL();
23502349 }
2351- static String parseURL(const char* url, BOOL prefix) {
2350+ static String parseURL(const char* url, BOOL prefix) {
23522351 ProxyInfo proxy;
23532352 String realhost = ProxyInfo::parse(url, proxy);
23542353 if (realhost != NULL) {
--- trunk/TTProxy/TTProxy.h (revision 9470)
+++ trunk/TTProxy/TTProxy.h (revision 9471)
@@ -206,6 +206,7 @@
206206 static void PASCAL TTXInit(PTTSet ts, PComVar cv) {
207207 getInstance().ts = ts;
208208 getInstance().cv = cv;
209+ Logger::set_folder(ts->LogDirW);
209210
210211 ProxyWSockHook::setMessageShower(&getInstance().shower);
211212 }
--- trunk/TTProxy/YCL/include/YCL/wstring.h (revision 9470)
+++ trunk/TTProxy/YCL/include/YCL/wstring.h (nonexistent)
@@ -1,684 +0,0 @@
1-/*
2- * Copyright (C) 2021- TeraTerm Project
3- * All rights reserved.
4- *
5- * Redistribution and use in source and binary forms, with or without
6- * modification, are permitted provided that the following conditions
7- * are met:
8- *
9- * 1. Redistributions of source code must retain the above copyright
10- * notice, this list of conditions and the following disclaimer.
11- * 2. Redistributions in binary form must reproduce the above copyright
12- * notice, this list of conditions and the following disclaimer in the
13- * documentation and/or other materials provided with the distribution.
14- * 3. The name of the author may not be used to endorse or promote products
15- * derived from this software without specific prior written permission.
16- *
17- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27- */
28-
29-#ifndef _YCL_WSTRING_H_
30-#define _YCL_WSTRING_H_
31-
32-#pragma once
33-
34-#include <YCL/common.h>
35-
36-#include <string.h>
37-#include <wchar.h>
38-
39-namespace yebisuya {
40-
41-// 文字列の管理・操作を行うクラス。
42-class WString {
43-private:
44- // 文字列を格納するバッファ。
45- // 文字列の前には参照カウンタを持ち、
46- // 代入や破棄の際にはそこを変更する。
47- const wchar_t* string;
48-
49- // utilities
50- // 文字列を格納するバッファを作成する。
51- // 文字列と参照カウンタの分の領域を確保する。
52- // 参照カウンタは0になっている。
53- // 引数:
54- // length 文字列の長さ。
55- // 返値:
56- // 作成したバッファの文字列部のアドレス。
57- static wchar_t* createBuffer(size_t length) {
58- size_t* count = (size_t*) new unsigned char[sizeof (size_t) + sizeof (wchar_t) * (length + 1)];
59- *count = 0;
60- return (wchar_t*) (count + 1);
61- }
62- // 文字列を格納したバッファを作成する。
63- // 引数:
64- // source 格納する文字列。
65- // 返値:
66- // 作成したバッファの文字列部のアドレス。
67- static const wchar_t* create(const wchar_t* source) {
68- return source != NULL ? create(source, wcslen(source)) : NULL;
69- }
70- // 文字列を格納したバッファを作成する。
71- // 引数:
72- // source 格納する文字列。
73- // length 文字列の長さ。
74- // 返値:
75- // 作成したバッファの文字列部のアドレス。
76- static const wchar_t* create(const wchar_t* source, size_t length) {
77- if (source != NULL) {
78- wchar_t* buffer = createBuffer(length);
79- wmemcpy(buffer, source, length);
80- buffer[length] = '\0';
81- return buffer;
82- }
83- return NULL;
84- }
85- // 二つの文字列を連結し格納したバッファを作成する。
86- // 引数:
87- // str1 連結する文字列(前)。
88- // str2 連結する文字列(後)。
89- // 返値:
90- // 作成したバッファの文字列部のアドレス。
91- static const wchar_t* concat(const wchar_t* str1, const wchar_t* str2) {
92- size_t len1 = wcslen(str1);
93- size_t len2 = wcslen(str2);
94- wchar_t* buffer = createBuffer(len1 + len2);
95- wmemcpy(buffer, str1, len1);
96- wmemcpy(buffer + len1, str2, len2);
97- buffer[len1 + len2] = '\0';
98- return buffer;
99- }
100- // private methods
101- // 参照カウンタを減らし、0になったらバッファを破棄する。
102- void release() {
103- if (string != NULL) {
104- size_t* count = (size_t*) string - 1;
105- if (--*count == 0)
106- delete[] (unsigned char*) count;
107- }
108- }
109- // 参照カウンタを増やす。
110- void add() {
111- if (string != NULL) {
112- size_t* count = (size_t*) string - 1;
113- ++*count;
114- }
115- }
116- // 別のバッファと置き換える。
117- // 元のバッファの参照カウンタを減らし、
118- // 新しいバッファの参照カウンタを増やす。
119- // 引数:
120- // source 置き換える新しいバッファ。
121- void set(const wchar_t* source) {
122- if (string != source) {
123- release();
124- string = source;
125- add();
126- }
127- }
128-public:
129- // constructor
130- // デフォルトコンストラクタ。
131- // NULLが入っているので、このままで文字列操作するとアクセス違反になるので注意。
132- WString():string(NULL) {
133- }
134- // 元の文字列を指定するコンストラクタ。
135- // 引数:
136- // source 元の文字列。
137- WString(const wchar_t* source):string(NULL) {
138- set(create(source));
139- }
140- // 元の文字列を長さ付きで指定するコンストラクタ。
141- // 引数:
142- // source 元の文字列。
143- // length 文字列の長さ。
144- WString(const wchar_t* source, size_t length):string(NULL) {
145- set(create(source, length));
146- }
147- // コピーコンストラクタ。
148- // 引数:
149- // source 元の文字列。
150- WString(const WString& source):string(NULL) {
151- set(source.string);
152- }
153- // 二つの文字列を連結するコンストラクタ。
154- // 引数:
155- // str1 前になる文字列。
156- // str2 後になる文字列。
157- WString(const wchar_t* str1, const wchar_t* str2):string(NULL) {
158- set(concat(str1, str2));
159- }
160- // 二つの文字列を連結するコンストラクタ。
161- // 引数:
162- // str1 前になる文字列。
163- // str2 後になる文字列。
164- WString(const WString& str1, const wchar_t* str2):string(NULL) {
165- set(*str2 != '\0' ? concat(str1.string, str2) : str1.string);
166- }
167- // destructor
168- // デストラクタ。
169- // 派生することは考えていないので仮想関数にはしない。
170- ~WString() {
171- release();
172- }
173- // public methods
174- // この文字列の後に指定の文字列を連結する。
175- // 引数:
176- // source 連結する文字列。
177- // 返値:
178- // 連結された文字列。
179- WString concat(const wchar_t* source)const {
180- return WString(*this, source);
181- }
182- // 文字列との比較を行う。
183- // NULLとも比較できる。
184- // 引数:
185- // str 比較する文字列。
186- // 返値:
187- // 等しければ0、strの方が大きければ負、小さければ正。
188- int compareTo(const wchar_t* str)const {
189- if (str == NULL)
190- return string == NULL ? 0 : 1;
191- else if (string == NULL)
192- return -1;
193- return wcscmp(string, str);
194- }
195- // 文字列との比較を大文字小文字の区別なしで行う。
196- // NULLとも比較できる。
197- // 引数:
198- // str 比較する文字列。
199- // 返値:
200- // 等しければ0、strの方が大きければ負、小さければ正。
201- int compareToIgnoreCase(const wchar_t* str)const {
202- if (str == NULL)
203- return string == NULL ? 0 : 1;
204- else if (string == NULL)
205- return -1;
206- return _wcsicmp(string, str);
207- }
208- // 文字列との比較を行う。
209- // NULLとも比較できる。
210- // 引数:
211- // str 比較する文字列。
212- // 返値:
213- // 等しければ真。
214- bool equals(const wchar_t* str)const {
215- return compareTo(str) == 0;
216- }
217- // 文字列との比較を大文字小文字の区別なしで行う。
218- // NULLとも比較できる。
219- // 引数:
220- // str 比較する文字列。
221- // 返値:
222- // 等しければ真。
223- bool equalsIgnoreCase(const wchar_t* str)const {
224- return compareToIgnoreCase(str) == 0;
225- }
226- // 指定された文字列で始まっているかどうかを判定する。
227- // 引数:
228- // str 比較する文字列。
229- // 返値:
230- // 指定された文字列で始まっていれば真。
231- bool startsWith(const wchar_t* str)const {
232- return startsWith(str, 0);
233- }
234- // 指定の位置から指定された文字列で始まっているかどうかを判定する。
235- // 引数:
236- // str 比較する文字列。
237- // 返値:
238- // 指定された文字列で始まっていれば真。
239- bool startsWith(const wchar_t* str, int offset)const {
240- return wcsncmp(string, str, wcslen(str)) == 0;
241- }
242- // 指定された文字列で終わっているかどうかを判定する。
243- // 引数:
244- // str 比較する文字列。
245- // 返値:
246- // 指定された文字列で終わっていれば真。
247- //
248- bool endsWith(const wchar_t* str)const {
249- size_t str_length = wcslen(str);
250- size_t string_length = length();
251- if (string_length < str_length)
252- return false;
253- return wcscmp(string + string_length - str_length, str) == 0;
254- }
255- // 指定の文字がどの位置にあるかを探す。
256- // 引数:
257- // chr 探す文字。
258- // 返値:
259- // 文字の見つかったインデックス。見つからなければ-1。
260- int indexOf(char chr)const {
261- return indexOf(chr, 0);
262- }
263- // 指定の文字がどの位置にあるかを指定の位置から探す。
264- // 引数:
265- // chr 探す文字。
266- // from 探し始める位置。
267- // 返値:
268- // 文字の見つかったインデックス。見つからなければ-1。
269- int indexOf(wchar_t chr, size_t from)const {
270- if (from >= length())
271- return -1;
272- const wchar_t* found = wcschr(string + from, chr);
273- if (found == NULL)
274- return -1;
275- return found - string;
276- }
277- // 指定の文字列がどの位置にあるかを探す。
278- // 引数:
279- // str 探す文字列。
280- // 返値:
281- // 文字列の見つかったインデックス。見つからなければ-1。
282- int indexOf(const wchar_t* str)const {
283- return indexOf(str, 0);
284- }
285- // 指定の文字列がどの位置にあるかを指定の位置から探す。
286- // 引数:
287- // str 探す文字列。
288- // from 探し始める位置。
289- // 返値:
290- // 文字列の見つかったインデックス。見つからなければ-1。
291- //
292- int indexOf(const wchar_t* str, size_t from)const {
293- if (from >= length())
294- return -1;
295- const wchar_t* found = wcsstr(string + from, str);
296- if (found == NULL)
297- return -1;
298- return found - string;
299- }
300- // 文字列の長さを返す。
301- size_t length()const {
302- return wcslen(string);
303- }
304- // 指定の文字が最後に見つかる位置を取得する。
305- // 引数:
306- // chr 探す文字。
307- // 返値:
308- // 文字の見つかったインデックス。見つからなければ-1。
309- int lastIndexOf(char chr)const {
310- return lastIndexOf(chr, (size_t) -1);
311- }
312- // 指定の文字が指定の位置よりも前で最後に見つかる位置を取得する。
313- // 引数:
314- // chr 探す文字。
315- // from 探し始める位置。
316- // 返値:
317- // 文字の見つかったインデックス。見つからなければ-1。
318- int lastIndexOf(wchar_t chr, size_t from)const {
319- size_t len = length();
320- if (from > len - 1)
321- from = len - 1;
322- const wchar_t* s = string;
323- const wchar_t* end = string + from;
324- const wchar_t* found = NULL;
325- while (*s != '0' && s <= end) {
326- if (*s == chr)
327- found = s;
328- s++;
329- }
330- return found != NULL ? found - string : -1;
331- }
332- // 指定の文字列が最後に見つかる位置を取得する。
333- // 引数:
334- // str 探す文字列。
335- // 返値:
336- // 文字列の見つかったインデックス。見つからなければ-1。
337- int lastIndexOf(const wchar_t* str)const {
338- return lastIndexOf(str, (size_t) -1);
339- }
340- // 指定の文字列が指定の位置よりも前で最後に見つかる位置を取得する。
341- // 引数:
342- // str 探す文字列。
343- // from 探し始める位置。
344- // 返値:
345- // 文字列の見つかったインデックス。見つからなければ-1。
346- int lastIndexOf(const wchar_t* str, size_t from)const {
347- size_t len = length();
348- size_t str_len = wcslen(str);
349- if (from > len - str_len)
350- from = len - str_len;
351- const wchar_t* s = string + from;
352- while (s >= string) {
353- if (wcsncmp(s, str, str_len) == 0)
354- return s - string;
355- s--;
356- }
357- return -1;
358- }
359- // 文字列の一部を取り出す。
360- // 引数:
361- // start 取り出す文字列の先頭の位置。
362- // 返値:
363- // 文字列の一部。
364- WString substring(int start)const {
365- return WString(string + start);
366- }
367- // 文字列の一部を取り出す。
368- // 引数:
369- // start 取り出す文字列の先頭の位置。
370- // end 取り出す文字列の後の位置。
371- // 返値:
372- // 文字列の一部。
373- WString substring(int start, int end)const {
374- return WString(string + start, end - start);
375- }
376- // 指定の位置にある文字を取り出す。
377- // 引数:
378- // index 取り出す文字の位置。
379- // 返値:
380- // 指定の位置にある文字。
381- char charAt(size_t index)const {
382- return index < length() ? string[index] : '\0';
383- }
384- // 指定の文字を指定の文字に置き換えます。
385- // 引数:
386- // oldChr 元の文字。
387- // newChr 置き換える文字。
388- // 返値:
389- // 置換後の文字列。
390- WString replace(char oldChr, char newChr)const {
391- WString result(string);
392- char* s = (char*) result.string;
393- while (*s != '\0'){
394- if (WString::isLeadByte(*s))
395- s++;
396- else if (*s == oldChr)
397- *s = newChr;
398- s++;
399- }
400- return result;
401- }
402- // 文字列中の大文字を小文字に変換する。
403- // 返値:
404- // 変換後の文字列。
405- WString toLowerCase()const {
406- WString result(string);
407- char* s = (char*) result.string;
408- while (*s != '\0'){
409- if (WString::isLeadByte(*s))
410- s++;
411- else if ('A' <= *s && *s <= 'Z')
412- *s += 'a' - 'A';
413- s++;
414- }
415- return result;
416- }
417- // 文字列中の小文字を大文字に変換する。
418- // 返値:
419- // 変換後の文字列。
420- WString toUpperCase()const {
421- WString result(string);
422- char* s = (char*) result.string;
423- while (*s != '\0'){
424- if (WString::isLeadByte(*s))
425- s++;
426- else if ('a' <= *s && *s <= 'z')
427- *s += 'A' - 'a';
428- s++;
429- }
430- return result;
431- }
432- // 文字列の前後の空白文字を削除する。
433- // 返値:
434- // 削除後の文字列。
435- WString trim()const {
436- const wchar_t* s = string;
437- while (*s != '\0' && (unsigned char) *s <= ' ')
438- s++;
439- const wchar_t* start = s;
440- s = string + length();
441- while (s > start && (*s != '\0' && (unsigned char) *s <= ' '))
442- s--;
443- return WString(start, s - start);
444- }
445-
446- // operators
447-
448- // const char*へのキャスト演算子
449- // 返値:
450- // 文字列へのアドレス。
451- operator const wchar_t*()const {
452- return string;
453- }
454- // char配列のように扱うための[]演算子。
455- // 引数:
456- // index 取得する文字のインデックス。
457- // 返値:
458- // 指定のインデックスにある文字。
459- char operator[](size_t index)const {
460- return charAt(index);
461- }
462- // 文字列を連結するための+演算子。
463- // 引数:
464- // source 連結する文字列。
465- // 返値:
466- // 連結した文字列。
467- WString operator+(const wchar_t* source)const {
468- return WString(string, source);
469- }
470- // 文字列を連結するための+演算子。
471- // 引数:
472- // source 連結する文字列。
473- // 返値:
474- // 連結した文字列。
475- WString operator+(const WString& source)const {
476- return *string != '\0' ? WString(string, source.string) : source;
477- }
478- // 文字列を連結するための+演算子。
479- // 引数:
480- // str1 連結する文字列(前)。
481- // str2 連結する文字列(後)。
482- // 返値:
483- // 連結した文字列。
484- friend WString operator+(const wchar_t* str1, const WString& str2) {
485- return *str1 != '\0' ? WString(str1, str2.string) : str2;
486- }
487- // 代入演算子。
488- // 引数:
489- // source 代入する文字列。
490- // 返値:
491- // 代入結果。
492- WString& operator=(const wchar_t* source) {
493- set(create(source));
494- return *this;
495- }
496- // 代入演算子。
497- // 引数:
498- // source 代入する文字列。
499- // 返値:
500- // 代入結果。
501- WString& operator=(const WString& source) {
502- set(source.string);
503- return *this;
504- }
505- // 連結した結果を代入する演算子。
506- // 引数:
507- // source 連結する文字列。
508- // 返値:
509- // 連結結果。
510- WString& operator+=(const wchar_t* source) {
511- if (*source != '\0')
512- set(concat(string, source));
513- return *this;
514- }
515- // 比較演算子。
516- // 引数:
517- // str 比較対象の文字列。
518- // 返値:
519- // strの方が等しければ真。
520- bool operator==(const WString& str)const {
521- return compareTo(str.string) == 0;
522- }
523- // 比較演算子。
524- // 引数:
525- // str 比較対象の文字列。
526- // 返値:
527- // strの方が等しければ真。
528- bool operator==(const wchar_t* str)const {
529- return compareTo(str) == 0;
530- }
531- // 比較演算子。
532- // 引数:
533- // str1 比較する文字列。
534- // str2 比較する文字列。
535- // 返値:
536- // str1よりstr2の方が等しければ真。
537- friend bool operator==(const wchar_t* str1, const WString& str2) {
538- return str2.compareTo(str1) == 0;
539- }
540- // 比較演算子。
541- // 引数:
542- // str 比較対象の文字列。
543- // 返値:
544- // strの方が等しくなければ真。
545- bool operator!=(const WString& str)const {
546- return compareTo(str) != 0;
547- }
548- // 比較演算子。
549- // 引数:
550- // str 比較対象の文字列。
551- // 返値:
552- // strの方が等しくなければ真。
553- bool operator!=(const wchar_t* str)const {
554- return compareTo(str) != 0;
555- }
556- // 比較演算子。
557- // 引数:
558- // str1 比較する文字列。
559- // str2 比較する文字列。
560- // 返値:
561- // str1よりstr2の方が等しくなければ真。
562- friend bool operator!=(const wchar_t* str1, const WString& str2) {
563- return str2.compareTo(str1) != 0;
564- }
565- // 比較演算子。
566- // 引数:
567- // str 比較対象の文字列。
568- // 返値:
569- // strの方が大きければ真。
570- bool operator<(const WString& str)const {
571- return compareTo(str) < 0;
572- }
573- // 比較演算子。
574- // 引数:
575- // str 比較対象の文字列。
576- // 返値:
577- // strの方が大きければ真。
578- bool operator<(const wchar_t* str)const {
579- return compareTo(str) < 0;
580- }
581- // 比較演算子。
582- // 引数:
583- // str1 比較する文字列。
584- // str2 比較する文字列。
585- // 返値:
586- // str1よりstr2の方が大きければ真。
587- friend bool operator<(const wchar_t* str1, const WString& str2) {
588- return str2.compareTo(str1) > 0;
589- }
590- // 比較演算子。
591- // 引数:
592- // str 比較対象の文字列。
593- // 返値:
594- // strの方が大きいか等しければ真。
595- bool operator<=(const WString& str)const {
596- return compareTo(str) <= 0;
597- }
598- // 比較演算子。
599- // 引数:
600- // str 比較対象の文字列。
601- // 返値:
602- // strの方が大きいか等しければ真。
603- bool operator<=(const wchar_t* str)const {
604- return compareTo(str) <= 0;
605- }
606- // 比較演算子。
607- // 引数:
608- // str1 比較する文字列。
609- // str2 比較する文字列。
610- // 返値:
611- // str1よりstr2の方が大きいか等しければ真。
612- friend bool operator<=(const wchar_t* str1, const WString& str2) {
613- return str2.compareTo(str1) >= 0;
614- }
615- // 比較演算子。
616- // 引数:
617- // str 比較対象の文字列。
618- // 返値:
619- // strの方が小さければ真。
620- bool operator>(const WString& str)const {
621- return compareTo(str) > 0;
622- }
623- // 比較演算子。
624- // 引数:
625- // str 比較対象の文字列。
626- // 返値:
627- // strの方が小さければ真。
628- bool operator>(const wchar_t* str)const {
629- return compareTo(str) > 0;
630- }
631- // 比較演算子。
632- // 引数:
633- // str1 比較する文字列。
634- // str2 比較する文字列。
635- // 返値:
636- // str1よりstr2の方が小さければ真。
637- friend bool operator>(const wchar_t* str1, const WString& str2) {
638- return str2.compareTo(str1) < 0;
639- }
640- // 比較演算子。
641- // 引数:
642- // str 比較対象の文字列。
643- // 返値:
644- // strの方が小さいか等しければ真。
645- bool operator>=(const WString& str)const {
646- return compareTo(str) >= 0;
647- }
648- // 比較演算子。
649- // 引数:
650- // str 比較対象の文字列。
651- // 返値:
652- // strの方が小さいか等しければ真。
653- bool operator>=(const wchar_t* str)const {
654- return compareTo(str) >= 0;
655- }
656- // 比較演算子。
657- // 引数:
658- // str1 比較する文字列。
659- // str2 比較する文字列。
660- // 返値:
661- // str1よりstr2の方が小さいか等しければ真。
662- friend bool operator>=(const wchar_t* str1, const WString& str2) {
663- return str2.compareTo(str1) <= 0;
664- }
665-
666- // public utilities
667-
668- // 2バイト文字の最初の1バイトかどうかを判定する。
669- // 引数:
670- // 判定するバイト。
671- // 返値:
672- // 2バイト文字の最初の1バイトであれば真。
673- static bool isLeadByte(char ch) {
674- #ifdef _INC_WINDOWS
675- return ::IsDBCSLeadByte(ch) != 0;
676- #else
677- return (ch & 0x80) != 0;
678- #endif
679- }
680-};
681-
682-}
683-
684-#endif//_YCL_WSTRING_H_
--- trunk/TTProxy/YCL/include/YCL/IniFile.h (revision 9470)
+++ trunk/TTProxy/YCL/include/YCL/IniFile.h (revision 9471)
@@ -16,9 +16,11 @@
1616 #include <YCL/Enumeration.h>
1717 #include <YCL/Vector.h>
1818 #include <YCL/Hashtable.h>
19-#include <YCL/wstring.h>
19+#include <YCL/WString.h>
2020
2121 #include "inifile_com.h"
22+#include "asprintf.h"
23+#include "codeconv.h"
2224
2325 namespace yebisuya {
2426
@@ -171,6 +173,23 @@
171173 exists = true;
172174 return NULL;
173175 }
176+ static WString getStringW(const wchar_t* filename, const char* section, const wchar_t* name, bool& exists, size_t size) {
177+ wchar_t* buffer = (wchar_t*) alloca(sizeof(wchar_t) * size);
178+ wchar_t* sectionW = ToWcharA(section);
179+ size_t len = GetPrivateProfileStringW(sectionW, name, L"\n:", buffer, size, filename);
180+ free(sectionW);
181+ if (len < size - 2) {
182+ // 改行を含んだ文字列はiniファイルからは取得できないので取得失敗したことが分かる
183+ if (buffer[0] == '\n') {
184+ exists = false;
185+ return NULL;
186+ }
187+ // エスケープ文字を展開
188+ return StringUtil::unescapeW(buffer);
189+ }
190+ exists = true;
191+ return NULL;
192+ }
174193 static String generateSectionName(const char* parentSection, const char* subkeyName) {
175194 StringBuffer buffer = parentSection;
176195 buffer.append('\\');
@@ -234,6 +253,21 @@
234253 }
235254 return defaultValue;
236255 }
256+ WString getStringW(const wchar_t* name)const {
257+ return getStringW(name, NULL);
258+ }
259+ WString getStringW(const wchar_t* name, WString defaultValue)const {
260+ if (filename != NULL && section != NULL && name != NULL) {
261+ size_t size = 256;
262+ WString string;
263+ bool exists;
264+ while ((string = getStringW(filename, section, name, exists, size)) == NULL && exists)
265+ size += 256;
266+ if (string != NULL)
267+ return string;
268+ }
269+ return defaultValue;
270+ }
237271 bool getBoolean(const char* name, bool defaultValue = false)const {
238272 String string = getString(name);
239273 if (string != NULL) {
@@ -263,6 +297,25 @@
263297 }
264298 return false;
265299 }
300+ bool setString(const wchar_t* name, WString value) {
301+ if (filename == NULL || section == NULL || name == NULL) {
302+ return false;
303+ }
304+
305+ // NULLでなければエスケープしてから""で括る
306+ if (value != NULL) {
307+ WStringBuffer buffer;
308+ buffer.append('"');
309+ if (!StringUtil::escapeW(buffer, value))
310+ buffer.append(value);
311+ buffer.append('"');
312+ value = buffer.toString();
313+ }
314+ wchar_t *sectionW = ToWcharA(section);
315+ BOOL r = ::WritePrivateProfileStringW(sectionW, name, value, filename);
316+ free(sectionW);
317+ return r != FALSE;
318+ }
266319 bool setBoolean(const char* name, bool value) {
267320 return setString(name, value ? YES() : NO());
268321 }
--- trunk/TTProxy/YCL/include/YCL/StringUtil.h (revision 9470)
+++ trunk/TTProxy/YCL/include/YCL/StringUtil.h (revision 9471)
@@ -11,12 +11,13 @@
1111
1212 #include <YCL/String.h>
1313 #include <YCL/StringBuffer.h>
14+#include <YCL/wStringBuffer.h>
1415
1516 namespace yebisuya {
1617
1718 class StringUtil {
1819 private:
19- static int hexadecimal(char c) {
20+ static int hexadecimal(wchar_t c) {
2021 if ('0' <= c && c <= '9') {
2122 return c - '0';
2223 }else if ('A' <= c && c <= 'F') {
@@ -27,9 +28,15 @@
2728 return -1;
2829 }
2930 }
30- static int octet(char c) {
31+ static int hexadecimal(char c) {
32+ return hexadecimal((wchar_t)c);
33+ }
34+ static int octet(wchar_t c) {
3135 return '0' <= c && c <= '7' ? c - '0' : -1;
3236 }
37+ static int octet(char c) {
38+ return octet((wchar_t)c);
39+ }
3340 static const char* ESCAPE_CHARS() {
3441 static const char string[] = "abfnrtv";
3542 return string;
@@ -44,7 +51,7 @@
4451 return NULL;
4552 return escape(string, 0, string.length());
4653 }
47- static String escape(String string, int offset, int length) {
54+ static String escape(String string, int offset, size_t length) {
4855 if (string == NULL)
4956 return NULL;
5057 StringBuffer buffer;
@@ -55,7 +62,7 @@
5562 return false;
5663 return escape(buffer, string, 0, string.length());
5764 }
58- static bool escape(StringBuffer& buffer, String string, int offset, int length) {
65+ static bool escape(StringBuffer& buffer, String string, size_t offset, size_t length) {
5966 if (string == NULL)
6067 return false;
6168 const char* start = string;
@@ -64,7 +71,7 @@
6471 const char* end = start + length;
6572 while (p < end && *p != '\0') {
6673 char ch = *p;
67- if ('\0' < ch && ch < ' ' || ch == '\'' || ch == '"' || ch == '?' || ch == '\\') {
74+ if (('\0' < ch && ch < ' ') || ch == '\'' || ch == '"' || ch == '?' || ch == '\\') {
6875 bool useOctet;
6976 if (ch < ' ') {
7077 useOctet = true;
@@ -105,6 +112,70 @@
105112 return true;
106113 }
107114
115+ static WString escapeW(WString string) {
116+ if (string == NULL)
117+ return NULL;
118+ return escapeW(string, 0, string.length());
119+ }
120+ static WString escapeW(WString string, size_t offset, size_t length) {
121+ if (string == NULL)
122+ return NULL;
123+ WStringBuffer buffer;
124+ return escapeW(buffer, string, offset, length) ? buffer.toString() : string;
125+ }
126+ static bool escapeW(WStringBuffer& buffer, WString string) {
127+ if (string == NULL)
128+ return false;
129+ return escapeW(buffer, string, 0, string.length());
130+ }
131+ static bool escapeW(WStringBuffer& buffer, WString string, size_t offset, size_t length) {
132+ if (string == NULL)
133+ return false;
134+ const wchar_t* start = string;
135+ start += offset;
136+ const wchar_t* p = start;
137+ const wchar_t* end = start + length;
138+ while (p < end && *p != '\0') {
139+ wchar_t ch = *p;
140+ if (('\0' < ch && ch < ' ') || ch == '\'' || ch == '"' || ch == '?' || ch == '\\') {
141+ bool useOctet;
142+ if (ch < ' ') {
143+ useOctet = true;
144+ for (int index = 0; CONTROL_CHARS()[index] != '\0'; index++) {
145+ if (ch == CONTROL_CHARS()[index]) {
146+ ch = ESCAPE_CHARS()[index];
147+ useOctet = false;
148+ break;
149+ }
150+ }
151+ }else{
152+ useOctet = false;
153+ }
154+ if (p > start) {
155+ buffer.append(start, p - start);
156+ }
157+ buffer.append('\\');
158+ if (useOctet) {
159+ int octet = 6;
160+ while (octet >= 0) {
161+ buffer.append((char) ('0' + ((ch >> octet) & 0x07)));
162+ octet -= 3;
163+ }
164+ }else{
165+ buffer.append(ch);
166+ }
167+ start = ++p;
168+ }else{
169+ p++;
170+ }
171+ }
172+ if (start == (const wchar_t*) string) {
173+ return false;
174+ }
175+ buffer.append(start);
176+ return true;
177+ }
178+
108179 static String unescape(String string) {
109180 if (string == NULL)
110181 return NULL;
@@ -198,6 +269,97 @@
198269 buffer.append(start);
199270 return true;
200271 }
272+
273+ static WString unescapeW(WString string) {
274+ if (string == NULL)
275+ return NULL;
276+ return unescapeW(string, 0, string.length());
277+ }
278+ static WString unescapeW(WString string, int offset, int length) {
279+ if (string == NULL)
280+ return NULL;
281+ WStringBuffer buffer;
282+ return unescapeW(buffer, string) ? buffer.toString() : string;
283+ }
284+ static bool unescapeW(WStringBuffer& buffer, WString string) {
285+ if (string == NULL)
286+ return false;
287+ return unescapeW(buffer, string, 0, string.length());
288+ }
289+ static bool unescapeW(WStringBuffer& buffer, WString string, size_t offset, size_t length) {
290+ if (string == NULL)
291+ return false;
292+ const wchar_t* start = string;
293+ start += offset;
294+ const wchar_t* p = start;
295+ const wchar_t* end = start + length;
296+ while (p < end && *p != '\0') {
297+ if (*p == '\\') {
298+ if (p > start) {
299+ buffer.append(start, p - start);
300+ start = p;
301+ }
302+ wchar_t ch = '\0';
303+ switch (*++p) {
304+ case '\'':
305+ case '"':
306+ case '\\':
307+ case '?':
308+ ch = *p++;
309+ break;
310+ case 'x':
311+ case 'X':
312+ {
313+ int ch1 = hexadecimal(*++p);
314+ if (ch1 != -1) {
315+ int ch2 = hexadecimal(*++p);
316+ if (ch2 != -1) {
317+ p++;
318+ ch = (char) (ch1 << 4 | ch2);
319+ }else{
320+ ch = (char) ch1;
321+ }
322+ }
323+ }
324+ break;
325+ case '0': case '1': case '2': case '3':
326+ case '4': case '5': case '6': case '7':
327+ {
328+ ch = octet(*p);
329+ int d = octet(*++p);
330+ if (d != -1) {
331+ ch = (ch << 3 | d);
332+ d = octet(*++p);
333+ if (d != -1) {
334+ ch = (ch << 3 | d);
335+ p++;
336+ }
337+ }
338+ }
339+ break;
340+ default:
341+ for (int index = 0; ESCAPE_CHARS()[index] != '\0'; index++) {
342+ if (*p == ESCAPE_CHARS()[index]) {
343+ ch = CONTROL_CHARS()[index];
344+ p++;
345+ break;
346+ }
347+ }
348+ }
349+ if (ch != '\0') {
350+ buffer.append(ch);
351+ start = p;
352+ }
353+ }else{
354+ p++;
355+ }
356+ }
357+ if (start == (const wchar_t*) string) {
358+ return false;
359+ }
360+ buffer.append(start);
361+ return true;
362+ }
201363 };
202364
203365 }
--- trunk/TTProxy/YCL/include/YCL/WString.h (nonexistent)
+++ trunk/TTProxy/YCL/include/YCL/WString.h (revision 9471)
@@ -0,0 +1,686 @@
1+/*
2+ * Copyright (C) 2021- TeraTerm Project
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions
7+ * are met:
8+ *
9+ * 1. Redistributions of source code must retain the above copyright
10+ * notice, this list of conditions and the following disclaimer.
11+ * 2. Redistributions in binary form must reproduce the above copyright
12+ * notice, this list of conditions and the following disclaimer in the
13+ * documentation and/or other materials provided with the distribution.
14+ * 3. The name of the author may not be used to endorse or promote products
15+ * derived from this software without specific prior written permission.
16+ *
17+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+ */
28+
29+/* String.h を基に作成 */
30+
31+#ifndef _YCL_WSTRING_H_
32+#define _YCL_WSTRING_H_
33+
34+#pragma once
35+
36+#include <YCL/common.h>
37+
38+#include <string.h>
39+#include <wchar.h>
40+
41+namespace yebisuya {
42+
43+// 文字列の管理・操作を行うクラス。
44+class WString {
45+private:
46+ // 文字列を格納するバッファ。
47+ // 文字列の前には参照カウンタを持ち、
48+ // 代入や破棄の際にはそこを変更する。
49+ const wchar_t* string;
50+
51+ // utilities
52+ // 文字列を格納するバッファを作成する。
53+ // 文字列と参照カウンタの分の領域を確保する。
54+ // 参照カウンタは0になっている。
55+ // 引数:
56+ // length 文字列の長さ。
57+ // 返値:
58+ // 作成したバッファの文字列部のアドレス。
59+ static wchar_t* createBuffer(size_t length) {
60+ size_t* count = (size_t*) new unsigned char[sizeof (size_t) + sizeof (wchar_t) * (length + 1)];
61+ *count = 0;
62+ return (wchar_t*) (count + 1);
63+ }
64+ // 文字列を格納したバッファを作成する。
65+ // 引数:
66+ // source 格納する文字列。
67+ // 返値:
68+ // 作成したバッファの文字列部のアドレス。
69+ static const wchar_t* create(const wchar_t* source) {
70+ return source != NULL ? create(source, wcslen(source)) : NULL;
71+ }
72+ // 文字列を格納したバッファを作成する。
73+ // 引数:
74+ // source 格納する文字列。
75+ // length 文字列の長さ。
76+ // 返値:
77+ // 作成したバッファの文字列部のアドレス。
78+ static const wchar_t* create(const wchar_t* source, size_t length) {
79+ if (source != NULL) {
80+ wchar_t* buffer = createBuffer(length);
81+ wmemcpy(buffer, source, length);
82+ buffer[length] = '\0';
83+ return buffer;
84+ }
85+ return NULL;
86+ }
87+ // 二つの文字列を連結し格納したバッファを作成する。
88+ // 引数:
89+ // str1 連結する文字列(前)。
90+ // str2 連結する文字列(後)。
91+ // 返値:
92+ // 作成したバッファの文字列部のアドレス。
93+ static const wchar_t* concat(const wchar_t* str1, const wchar_t* str2) {
94+ size_t len1 = wcslen(str1);
95+ size_t len2 = wcslen(str2);
96+ wchar_t* buffer = createBuffer(len1 + len2);
97+ wmemcpy(buffer, str1, len1);
98+ wmemcpy(buffer + len1, str2, len2);
99+ buffer[len1 + len2] = '\0';
100+ return buffer;
101+ }
102+ // private methods
103+ // 参照カウンタを減らし、0になったらバッファを破棄する。
104+ void release() {
105+ if (string != NULL) {
106+ size_t* count = (size_t*) string - 1;
107+ if (--*count == 0)
108+ delete[] (unsigned char*) count;
109+ }
110+ }
111+ // 参照カウンタを増やす。
112+ void add() {
113+ if (string != NULL) {
114+ size_t* count = (size_t*) string - 1;
115+ ++*count;
116+ }
117+ }
118+ // 別のバッファと置き換える。
119+ // 元のバッファの参照カウンタを減らし、
120+ // 新しいバッファの参照カウンタを増やす。
121+ // 引数:
122+ // source 置き換える新しいバッファ。
123+ void set(const wchar_t* source) {
124+ if (string != source) {
125+ release();
126+ string = source;
127+ add();
128+ }
129+ }
130+public:
131+ // constructor
132+ // デフォルトコンストラクタ。
133+ // NULLが入っているので、このままで文字列操作するとアクセス違反になるので注意。
134+ WString():string(NULL) {
135+ }
136+ // 元の文字列を指定するコンストラクタ。
137+ // 引数:
138+ // source 元の文字列。
139+ WString(const wchar_t* source):string(NULL) {
140+ set(create(source));
141+ }
142+ // 元の文字列を長さ付きで指定するコンストラクタ。
143+ // 引数:
144+ // source 元の文字列。
145+ // length 文字列の長さ。
146+ WString(const wchar_t* source, size_t length):string(NULL) {
147+ set(create(source, length));
148+ }
149+ // コピーコンストラクタ。
150+ // 引数:
151+ // source 元の文字列。
152+ WString(const WString& source):string(NULL) {
153+ set(source.string);
154+ }
155+ // 二つの文字列を連結するコンストラクタ。
156+ // 引数:
157+ // str1 前になる文字列。
158+ // str2 後になる文字列。
159+ WString(const wchar_t* str1, const wchar_t* str2):string(NULL) {
160+ set(concat(str1, str2));
161+ }
162+ // 二つの文字列を連結するコンストラクタ。
163+ // 引数:
164+ // str1 前になる文字列。
165+ // str2 後になる文字列。
166+ WString(const WString& str1, const wchar_t* str2):string(NULL) {
167+ set(*str2 != '\0' ? concat(str1.string, str2) : str1.string);
168+ }
169+ // destructor
170+ // デストラクタ。
171+ // 派生することは考えていないので仮想関数にはしない。
172+ ~WString() {
173+ release();
174+ }
175+ // public methods
176+ // この文字列の後に指定の文字列を連結する。
177+ // 引数:
178+ // source 連結する文字列。
179+ // 返値:
180+ // 連結された文字列。
181+ WString concat(const wchar_t* source)const {
182+ return WString(*this, source);
183+ }
184+ // 文字列との比較を行う。
185+ // NULLとも比較できる。
186+ // 引数:
187+ // str 比較する文字列。
188+ // 返値:
189+ // 等しければ0、strの方が大きければ負、小さければ正。
190+ int compareTo(const wchar_t* str)const {
191+ if (str == NULL)
192+ return string == NULL ? 0 : 1;
193+ else if (string == NULL)
194+ return -1;
195+ return wcscmp(string, str);
196+ }
197+ // 文字列との比較を大文字小文字の区別なしで行う。
198+ // NULLとも比較できる。
199+ // 引数:
200+ // str 比較する文字列。
201+ // 返値:
202+ // 等しければ0、strの方が大きければ負、小さければ正。
203+ int compareToIgnoreCase(const wchar_t* str)const {
204+ if (str == NULL)
205+ return string == NULL ? 0 : 1;
206+ else if (string == NULL)
207+ return -1;
208+ return _wcsicmp(string, str);
209+ }
210+ // 文字列との比較を行う。
211+ // NULLとも比較できる。
212+ // 引数:
213+ // str 比較する文字列。
214+ // 返値:
215+ // 等しければ真。
216+ bool equals(const wchar_t* str)const {
217+ return compareTo(str) == 0;
218+ }
219+ // 文字列との比較を大文字小文字の区別なしで行う。
220+ // NULLとも比較できる。
221+ // 引数:
222+ // str 比較する文字列。
223+ // 返値:
224+ // 等しければ真。
225+ bool equalsIgnoreCase(const wchar_t* str)const {
226+ return compareToIgnoreCase(str) == 0;
227+ }
228+ // 指定された文字列で始まっているかどうかを判定する。
229+ // 引数:
230+ // str 比較する文字列。
231+ // 返値:
232+ // 指定された文字列で始まっていれば真。
233+ bool startsWith(const wchar_t* str)const {
234+ return startsWith(str, 0);
235+ }
236+ // 指定の位置から指定された文字列で始まっているかどうかを判定する。
237+ // 引数:
238+ // str 比較する文字列。
239+ // 返値:
240+ // 指定された文字列で始まっていれば真。
241+ bool startsWith(const wchar_t* str, int offset)const {
242+ return wcsncmp(string, str, wcslen(str)) == 0;
243+ }
244+ // 指定された文字列で終わっているかどうかを判定する。
245+ // 引数:
246+ // str 比較する文字列。
247+ // 返値:
248+ // 指定された文字列で終わっていれば真。
249+ //
250+ bool endsWith(const wchar_t* str)const {
251+ size_t str_length = wcslen(str);
252+ size_t string_length = length();
253+ if (string_length < str_length)
254+ return false;
255+ return wcscmp(string + string_length - str_length, str) == 0;
256+ }
257+ // 指定の文字がどの位置にあるかを探す。
258+ // 引数:
259+ // chr 探す文字。
260+ // 返値:
261+ // 文字の見つかったインデックス。見つからなければ-1。
262+ int indexOf(char chr)const {
263+ return indexOf(chr, 0);
264+ }
265+ // 指定の文字がどの位置にあるかを指定の位置から探す。
266+ // 引数:
267+ // chr 探す文字。
268+ // from 探し始める位置。
269+ // 返値:
270+ // 文字の見つかったインデックス。見つからなければ-1。
271+ int indexOf(wchar_t chr, size_t from)const {
272+ if (from >= length())
273+ return -1;
274+ const wchar_t* found = wcschr(string + from, chr);
275+ if (found == NULL)
276+ return -1;
277+ return found - string;
278+ }
279+ // 指定の文字列がどの位置にあるかを探す。
280+ // 引数:
281+ // str 探す文字列。
282+ // 返値:
283+ // 文字列の見つかったインデックス。見つからなければ-1。
284+ int indexOf(const wchar_t* str)const {
285+ return indexOf(str, 0);
286+ }
287+ // 指定の文字列がどの位置にあるかを指定の位置から探す。
288+ // 引数:
289+ // str 探す文字列。
290+ // from 探し始める位置。
291+ // 返値:
292+ // 文字列の見つかったインデックス。見つからなければ-1。
293+ //
294+ int indexOf(const wchar_t* str, size_t from)const {
295+ if (from >= length())
296+ return -1;
297+ const wchar_t* found = wcsstr(string + from, str);
298+ if (found == NULL)
299+ return -1;
300+ return found - string;
301+ }
302+ // 文字列の長さを返す。
303+ size_t length()const {
304+ return wcslen(string);
305+ }
306+ // 指定の文字が最後に見つかる位置を取得する。
307+ // 引数:
308+ // chr 探す文字。
309+ // 返値:
310+ // 文字の見つかったインデックス。見つからなければ-1。
311+ int lastIndexOf(char chr)const {
312+ return lastIndexOf(chr, (size_t) -1);
313+ }
314+ // 指定の文字が指定の位置よりも前で最後に見つかる位置を取得する。
315+ // 引数:
316+ // chr 探す文字。
317+ // from 探し始める位置。
318+ // 返値:
319+ // 文字の見つかったインデックス。見つからなければ-1。
320+ int lastIndexOf(wchar_t chr, size_t from)const {
321+ size_t len = length();
322+ if (from > len - 1)
323+ from = len - 1;
324+ const wchar_t* s = string;
325+ const wchar_t* end = string + from;
326+ const wchar_t* found = NULL;
327+ while (*s != '0' && s <= end) {
328+ if (*s == chr)
329+ found = s;
330+ s++;
331+ }
332+ return found != NULL ? found - string : -1;
333+ }
334+ // 指定の文字列が最後に見つかる位置を取得する。
335+ // 引数:
336+ // str 探す文字列。
337+ // 返値:
338+ // 文字列の見つかったインデックス。見つからなければ-1。
339+ int lastIndexOf(const wchar_t* str)const {
340+ return lastIndexOf(str, (size_t) -1);
341+ }
342+ // 指定の文字列が指定の位置よりも前で最後に見つかる位置を取得する。
343+ // 引数:
344+ // str 探す文字列。
345+ // from 探し始める位置。
346+ // 返値:
347+ // 文字列の見つかったインデックス。見つからなければ-1。
348+ int lastIndexOf(const wchar_t* str, size_t from)const {
349+ size_t len = length();
350+ size_t str_len = wcslen(str);
351+ if (from > len - str_len)
352+ from = len - str_len;
353+ const wchar_t* s = string + from;
354+ while (s >= string) {
355+ if (wcsncmp(s, str, str_len) == 0)
356+ return s - string;
357+ s--;
358+ }
359+ return -1;
360+ }
361+ // 文字列の一部を取り出す。
362+ // 引数:
363+ // start 取り出す文字列の先頭の位置。
364+ // 返値:
365+ // 文字列の一部。
366+ WString substring(int start)const {
367+ return WString(string + start);
368+ }
369+ // 文字列の一部を取り出す。
370+ // 引数:
371+ // start 取り出す文字列の先頭の位置。
372+ // end 取り出す文字列の後の位置。
373+ // 返値:
374+ // 文字列の一部。
375+ WString substring(int start, int end)const {
376+ return WString(string + start, end - start);
377+ }
378+ // 指定の位置にある文字を取り出す。
379+ // 引数:
380+ // index 取り出す文字の位置。
381+ // 返値:
382+ // 指定の位置にある文字。
383+ char charAt(size_t index)const {
384+ return index < length() ? string[index] : '\0';
385+ }
386+ // 指定の文字を指定の文字に置き換えます。
387+ // 引数:
388+ // oldChr 元の文字。
389+ // newChr 置き換える文字。
390+ // 返値:
391+ // 置換後の文字列。
392+ WString replace(char oldChr, char newChr)const {
393+ WString result(string);
394+ char* s = (char*) result.string;
395+ while (*s != '\0'){
396+ if (WString::isLeadByte(*s))
397+ s++;
398+ else if (*s == oldChr)
399+ *s = newChr;
400+ s++;
401+ }
402+ return result;
403+ }
404+ // 文字列中の大文字を小文字に変換する。
405+ // 返値:
406+ // 変換後の文字列。
407+ WString toLowerCase()const {
408+ WString result(string);
409+ char* s = (char*) result.string;
410+ while (*s != '\0'){
411+ if (WString::isLeadByte(*s))
412+ s++;
413+ else if ('A' <= *s && *s <= 'Z')
414+ *s += 'a' - 'A';
415+ s++;
416+ }
417+ return result;
418+ }
419+ // 文字列中の小文字を大文字に変換する。
420+ // 返値:
421+ // 変換後の文字列。
422+ WString toUpperCase()const {
423+ WString result(string);
424+ char* s = (char*) result.string;
425+ while (*s != '\0'){
426+ if (WString::isLeadByte(*s))
427+ s++;
428+ else if ('a' <= *s && *s <= 'z')
429+ *s += 'A' - 'a';
430+ s++;
431+ }
432+ return result;
433+ }
434+ // 文字列の前後の空白文字を削除する。
435+ // 返値:
436+ // 削除後の文字列。
437+ WString trim()const {
438+ const wchar_t* s = string;
439+ while (*s != '\0' && (unsigned char) *s <= ' ')
440+ s++;
441+ const wchar_t* start = s;
442+ s = string + length();
443+ while (s > start && (*s != '\0' && (unsigned char) *s <= ' '))
444+ s--;
445+ return WString(start, s - start);
446+ }
447+
448+ // operators
449+
450+ // const char*へのキャスト演算子
451+ // 返値:
452+ // 文字列へのアドレス。
453+ operator const wchar_t*()const {
454+ return string;
455+ }
456+ // char配列のように扱うための[]演算子。
457+ // 引数:
458+ // index 取得する文字のインデックス。
459+ // 返値:
460+ // 指定のインデックスにある文字。
461+ char operator[](size_t index)const {
462+ return charAt(index);
463+ }
464+ // 文字列を連結するための+演算子。
465+ // 引数:
466+ // source 連結する文字列。
467+ // 返値:
468+ // 連結した文字列。
469+ WString operator+(const wchar_t* source)const {
470+ return WString(string, source);
471+ }
472+ // 文字列を連結するための+演算子。
473+ // 引数:
474+ // source 連結する文字列。
475+ // 返値:
476+ // 連結した文字列。
477+ WString operator+(const WString& source)const {
478+ return *string != '\0' ? WString(string, source.string) : source;
479+ }
480+ // 文字列を連結するための+演算子。
481+ // 引数:
482+ // str1 連結する文字列(前)。
483+ // str2 連結する文字列(後)。
484+ // 返値:
485+ // 連結した文字列。
486+ friend WString operator+(const wchar_t* str1, const WString& str2) {
487+ return *str1 != '\0' ? WString(str1, str2.string) : str2;
488+ }
489+ // 代入演算子。
490+ // 引数:
491+ // source 代入する文字列。
492+ // 返値:
493+ // 代入結果。
494+ WString& operator=(const wchar_t* source) {
495+ set(create(source));
496+ return *this;
497+ }
498+ // 代入演算子。
499+ // 引数:
500+ // source 代入する文字列。
501+ // 返値:
502+ // 代入結果。
503+ WString& operator=(const WString& source) {
504+ set(source.string);
505+ return *this;
506+ }
507+ // 連結した結果を代入する演算子。
508+ // 引数:
509+ // source 連結する文字列。
510+ // 返値:
511+ // 連結結果。
512+ WString& operator+=(const wchar_t* source) {
513+ if (*source != '\0')
514+ set(concat(string, source));
515+ return *this;
516+ }
517+ // 比較演算子。
518+ // 引数:
519+ // str 比較対象の文字列。
520+ // 返値:
521+ // strの方が等しければ真。
522+ bool operator==(const WString& str)const {
523+ return compareTo(str.string) == 0;
524+ }
525+ // 比較演算子。
526+ // 引数:
527+ // str 比較対象の文字列。
528+ // 返値:
529+ // strの方が等しければ真。
530+ bool operator==(const wchar_t* str)const {
531+ return compareTo(str) == 0;
532+ }
533+ // 比較演算子。
534+ // 引数:
535+ // str1 比較する文字列。
536+ // str2 比較する文字列。
537+ // 返値:
538+ // str1よりstr2の方が等しければ真。
539+ friend bool operator==(const wchar_t* str1, const WString& str2) {
540+ return str2.compareTo(str1) == 0;
541+ }
542+ // 比較演算子。
543+ // 引数:
544+ // str 比較対象の文字列。
545+ // 返値:
546+ // strの方が等しくなければ真。
547+ bool operator!=(const WString& str)const {
548+ return compareTo(str) != 0;
549+ }
550+ // 比較演算子。
551+ // 引数:
552+ // str 比較対象の文字列。
553+ // 返値:
554+ // strの方が等しくなければ真。
555+ bool operator!=(const wchar_t* str)const {
556+ return compareTo(str) != 0;
557+ }
558+ // 比較演算子。
559+ // 引数:
560+ // str1 比較する文字列。
561+ // str2 比較する文字列。
562+ // 返値:
563+ // str1よりstr2の方が等しくなければ真。
564+ friend bool operator!=(const wchar_t* str1, const WString& str2) {
565+ return str2.compareTo(str1) != 0;
566+ }
567+ // 比較演算子。
568+ // 引数:
569+ // str 比較対象の文字列。
570+ // 返値:
571+ // strの方が大きければ真。
572+ bool operator<(const WString& str)const {
573+ return compareTo(str) < 0;
574+ }
575+ // 比較演算子。
576+ // 引数:
577+ // str 比較対象の文字列。
578+ // 返値:
579+ // strの方が大きければ真。
580+ bool operator<(const wchar_t* str)const {
581+ return compareTo(str) < 0;
582+ }
583+ // 比較演算子。
584+ // 引数:
585+ // str1 比較する文字列。
586+ // str2 比較する文字列。
587+ // 返値:
588+ // str1よりstr2の方が大きければ真。
589+ friend bool operator<(const wchar_t* str1, const WString& str2) {
590+ return str2.compareTo(str1) > 0;
591+ }
592+ // 比較演算子。
593+ // 引数:
594+ // str 比較対象の文字列。
595+ // 返値:
596+ // strの方が大きいか等しければ真。
597+ bool operator<=(const WString& str)const {
598+ return compareTo(str) <= 0;
599+ }
600+ // 比較演算子。
601+ // 引数:
602+ // str 比較対象の文字列。
603+ // 返値:
604+ // strの方が大きいか等しければ真。
605+ bool operator<=(const wchar_t* str)const {
606+ return compareTo(str) <= 0;
607+ }
608+ // 比較演算子。
609+ // 引数:
610+ // str1 比較する文字列。
611+ // str2 比較する文字列。
612+ // 返値:
613+ // str1よりstr2の方が大きいか等しければ真。
614+ friend bool operator<=(const wchar_t* str1, const WString& str2) {
615+ return str2.compareTo(str1) >= 0;
616+ }
617+ // 比較演算子。
618+ // 引数:
619+ // str 比較対象の文字列。
620+ // 返値:
621+ // strの方が小さければ真。
622+ bool operator>(const WString& str)const {
623+ return compareTo(str) > 0;
624+ }
625+ // 比較演算子。
626+ // 引数:
627+ // str 比較対象の文字列。
628+ // 返値:
629+ // strの方が小さければ真。
630+ bool operator>(const wchar_t* str)const {
631+ return compareTo(str) > 0;
632+ }
633+ // 比較演算子。
634+ // 引数:
635+ // str1 比較する文字列。
636+ // str2 比較する文字列。
637+ // 返値:
638+ // str1よりstr2の方が小さければ真。
639+ friend bool operator>(const wchar_t* str1, const WString& str2) {
640+ return str2.compareTo(str1) < 0;
641+ }
642+ // 比較演算子。
643+ // 引数:
644+ // str 比較対象の文字列。
645+ // 返値:
646+ // strの方が小さいか等しければ真。
647+ bool operator>=(const WString& str)const {
648+ return compareTo(str) >= 0;
649+ }
650+ // 比較演算子。
651+ // 引数:
652+ // str 比較対象の文字列。
653+ // 返値:
654+ // strの方が小さいか等しければ真。
655+ bool operator>=(const wchar_t* str)const {
656+ return compareTo(str) >= 0;
657+ }
658+ // 比較演算子。
659+ // 引数:
660+ // str1 比較する文字列。
661+ // str2 比較する文字列。
662+ // 返値:
663+ // str1よりstr2の方が小さいか等しければ真。
664+ friend bool operator>=(const wchar_t* str1, const WString& str2) {
665+ return str2.compareTo(str1) <= 0;
666+ }
667+
668+ // public utilities
669+
670+ // 2バイト文字の最初の1バイトかどうかを判定する。
671+ // 引数:
672+ // 判定するバイト。
673+ // 返値:
674+ // 2バイト文字の最初の1バイトであれば真。
675+ static bool isLeadByte(char ch) {
676+ #ifdef _INC_WINDOWS
677+ return ::IsDBCSLeadByte(ch) != 0;
678+ #else
679+ return (ch & 0x80) != 0;
680+ #endif
681+ }
682+};
683+
684+}
685+
686+#endif//_YCL_WSTRING_H_
--- trunk/TTProxy/YCL/include/YCL/WStringBuffer.h (nonexistent)
+++ trunk/TTProxy/YCL/include/YCL/WStringBuffer.h (revision 9471)
@@ -0,0 +1,397 @@
1+/*
2+ * Copyright (C) 2021- TeraTerm Project
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions
7+ * are met:
8+ *
9+ * 1. Redistributions of source code must retain the above copyright
10+ * notice, this list of conditions and the following disclaimer.
11+ * 2. Redistributions in binary form must reproduce the above copyright
12+ * notice, this list of conditions and the following disclaimer in the
13+ * documentation and/or other materials provided with the distribution.
14+ * 3. The name of the author may not be used to endorse or promote products
15+ * derived from this software without specific prior written permission.
16+ *
17+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+ */
28+
29+/* StringBuffer.h を基に作成 */
30+
31+#ifndef _YCL_WSTRINGBUFFER_H_
32+#define _YCL_WSTRINGBUFFER_H_
33+
34+#pragma once
35+
36+#include <YCL/common.h>
37+
38+#include <YCL/WString.h>
39+
40+#include <malloc.h>
41+
42+namespace yebisuya {
43+
44+// 可変長の文字列を扱うためのクラス。
45+class WStringBuffer {
46+private:
47+ // 文字列を格納するバッファ。
48+ wchar_t* buffer;
49+ // 現在有効な文字列の長さ。
50+ size_t validLength;
51+ // バッファの大きさ。
52+ size_t bufferSize;
53+ enum {
54+ // バッファを広げる際に使用するサイズ。
55+ INIT_CAPACITY = 16,
56+ };
57+ // バッファを初期化する。
58+ // 引数:
59+ // source 初期文字列。
60+ // length 初期文字列の長さ。
61+ // capacity バッファの初期サイズ。
62+ void init(const wchar_t* source, size_t length, size_t capacity) {
63+ if ((capacity != 0 || length != 0) && capacity < length + INIT_CAPACITY)
64+ capacity = length + INIT_CAPACITY;
65+ validLength = length;
66+ bufferSize = capacity;
67+ if (bufferSize == 0) {
68+ buffer = NULL;
69+ }else{
70+ buffer = new wchar_t[bufferSize];
71+ }
72+ if (source != NULL) {
73+ memcpy(buffer, source, validLength);
74+ }
75+ memset(buffer + validLength, '\0', bufferSize - validLength);
76+ }
77+public:
78+ // デフォルトコンストラクタ。
79+ WStringBuffer() {
80+ init(NULL, 0, 0);
81+ }
82+ // バッファの初期サイズを指定するコンストラクタ。
83+ // 引数:
84+ // capacity バッファの初期サイズ。
85+ WStringBuffer(size_t capacity) {
86+ init(NULL, 0, capacity);
87+ }
88+ // バッファの初期文字列を指定するコンストラクタ。
89+ // 引数:
90+ // source 初期文字列。
91+ WStringBuffer(const wchar_t* source) {
92+ init(source, wcslen(source), 0);
93+ }
94+ // コピーコンストラクタ。
95+ // 引数:
96+ // source 初期文字列。
97+ WStringBuffer(const WStringBuffer& source) {
98+ init(source.buffer, source.validLength, source.bufferSize);
99+ }
100+ // デストラクタ。
101+ ~WStringBuffer() {
102+ delete[] buffer;
103+ }
104+
105+ // 現在有効な文字列の長さを取得する。
106+ // 返値:
107+ // 有効な文字列の長さ。
108+ size_t length()const {
109+ return validLength;
110+ }
111+ // バッファのサイズを取得する。
112+ // 返値:
113+ // バッファのサイズ。
114+ size_t capacity()const {
115+ return bufferSize;
116+ }
117+ // バッファのサイズを指定の長さが収まるように調節する。
118+ // 引数:
119+ // newLength 調節する長さ。
120+ void ensureCapacity(size_t newLength) {
121+ if (bufferSize < newLength) {
122+ wchar_t* oldBuffer = buffer;
123+ init(oldBuffer, validLength, newLength + INIT_CAPACITY);
124+ delete[] oldBuffer;
125+ }
126+ }
127+ // 有効な文字列長を変更する。
128+ // 引数:
129+ // newLength 新しい文字列長。
130+ void setLength(size_t newLength) {
131+ if (validLength < newLength)
132+ ensureCapacity(newLength);
133+ validLength = newLength;
134+ }
135+ // 指定の位置の文字を取得する。
136+ // 引数:
137+ // index 文字の位置。
138+ // 返値:
139+ // 指定の位置の文字。
140+ char charAt(size_t index)const {
141+ return index < validLength ? buffer[index] : '\0';
142+ }
143+ // 指定の位置の文字を取得する。
144+ // 引数:
145+ // index 文字の位置。
146+ // 返値:
147+ // 指定の位置の文字の参照。
148+ wchar_t& charAt(size_t index) {
149+ if (index >= validLength) {
150+ ensureCapacity(validLength + 1);
151+ index = validLength++;
152+ }
153+ return buffer[index];
154+ }
155+ // 指定の位置の文字を変更する。
156+ // 引数:
157+ // index 変更する文字の位置。
158+ // chr 変更する文字。
159+ void setCharAt(int index, char chr) {
160+ charAt(index) = chr;
161+ }
162+ // 文字を追加する。
163+ // 引数:
164+ // chr 追加する文字。
165+ // 返値:
166+ // 追加結果。
167+ WStringBuffer& append(wchar_t chr) {
168+ charAt(validLength) = chr;
169+ return *this;
170+ }
171+ // 文字列を追加する。
172+ // 引数:
173+ // source 追加する文字列。
174+ // 返値:
175+ // 追加結果。
176+ WStringBuffer& append(const wchar_t* source) {
177+ return append(source, wcslen(source));
178+ }
179+ // 文字列を追加する。
180+ // 引数:
181+ // source 追加する文字列。
182+ // length 追加する文字列の長さ。
183+ // 返値:
184+ // 追加結果。
185+ WStringBuffer& append(const wchar_t* source, size_t length) {
186+ size_t oldLength = validLength;
187+ ensureCapacity(validLength + length);
188+ memcpy(buffer + oldLength, source, length);
189+ validLength += length;
190+ return *this;
191+ }
192+ // 指定の位置の文字を削除する。
193+ // 引数:
194+ // start 削除する位置。
195+ // 返値:
196+ // 削除結果。
197+ WStringBuffer& remove(size_t index) {
198+ return remove(index, index + 1);
199+ }
200+ // 指定の位置の文字列を削除する。
201+ // 引数:
202+ // start 削除する先頭位置。
203+ // end 削除する終わりの位置。
204+ // 返値:
205+ // 削除結果。
206+ WStringBuffer& remove(size_t start, size_t end) {
207+ if (start < end) {
208+ if (end < validLength){
209+ memcpy(buffer + start, buffer + end, validLength - end);
210+ validLength -= end - start;
211+ }else{
212+ validLength = start;
213+ }
214+ }
215+ return *this;
216+ }
217+ // 指定の位置の文字列を置換する。
218+ // 引数:
219+ // start 置換する先頭位置。
220+ // end 置換する終わりの位置。
221+ // source 置換する文字列。
222+ // 返値:
223+ // 置換結果。
224+ WStringBuffer& replace(size_t start, size_t end, const char* source) {
225+ if (end > validLength)
226+ end = validLength;
227+ if (start < end) {
228+ size_t length = strlen(source);
229+ size_t oldLength = validLength;
230+ ensureCapacity(validLength += length - (end - start));
231+ memcpy(buffer + start + length, buffer + end, oldLength - end);
232+ memcpy(buffer + start, source, length);
233+ }
234+ return *this;
235+ }
236+ // 指定の位置の文字列を取得する。
237+ // 引数:
238+ // start 取得する文字列の先頭位置。
239+ // 返値:
240+ // 指定の位置の文字列。
241+ WString substring(size_t index)const {
242+ return WString(buffer + index, validLength - index);
243+ }
244+ // 指定の位置の文字列を取得する。
245+ // 引数:
246+ // start 取得する文字列の先頭位置。
247+ // end 取得する文字列の終わりの位置。
248+ // 返値:
249+ // 指定の位置の文字列。
250+ WString substring(size_t start, size_t end)const {
251+ if (end > validLength)
252+ end = validLength;
253+ return WString(buffer + start, end - start);
254+ }
255+ // 指定の位置に文字を挿入する。
256+ // 引数:
257+ // index 挿入する位置。
258+ // source 挿入する文字。
259+ // 返値:
260+ // 挿入結果。
261+ WStringBuffer& insert(size_t index, char chr) {
262+ return insert(index, &chr, 1);
263+ }
264+ // 指定の位置に文字列を挿入する。
265+ // 引数:
266+ // index 挿入する位置。
267+ // source 挿入する文字列。
268+ // 返値:
269+ // 挿入結果。
270+ WStringBuffer& insert(size_t index, const char* source) {
271+ return insert(index, source, strlen(source));
272+ }
273+ // 指定の位置に文字列を挿入する。
274+ // 引数:
275+ // index 挿入する位置。
276+ // source 挿入する文字列。
277+ // length 文字列の長さ。
278+ // 返値:
279+ // 挿入結果。
280+ WStringBuffer& insert(size_t index, const char* source, size_t length) {
281+ if (index >= validLength)
282+ index = validLength;
283+ size_t oldLength = validLength;
284+ ensureCapacity(validLength + length);
285+ char* temp = (char*) alloca(oldLength - index);
286+ memcpy(temp, buffer + index, oldLength - index);
287+ memcpy(buffer + index, source, length);
288+ memcpy(buffer + index + length, temp, oldLength - index);
289+ validLength += length;
290+ return *this;
291+ }
292+#if 0
293+ // 文字列を反転する。
294+ // 返値:
295+ // 反転結果。
296+ WStringBuffer& reverse() {
297+ char* temporary = (char*) alloca(sizeof (char) * validLength);
298+ char* dst = temporary + validLength;
299+ wchar_t* src = buffer;
300+ while (temporary < dst) {
301+ if (String::isLeadByte(*src)) {
302+ char pre = *src++;
303+ *--dst = *src++;
304+ *--dst = pre;
305+ }else{
306+ *--dst = *src++;
307+ }
308+ }
309+ memcpy(buffer, temporary, validLength);
310+ return *this;
311+ }
312+#endif
313+ // 文字列を取得する。
314+ // 返値:
315+ // 現在設定されている文字列。
316+ WString toString()const {
317+ return WString(buffer, validLength);
318+ }
319+
320+ // 一文字だけの文字列に変更する。
321+ // 引数:
322+ // 変更する一文字。
323+ // 返値:
324+ // 変更結果。
325+ WStringBuffer& set(char chr) {
326+ ensureCapacity(1);
327+ buffer[0] = chr;
328+ validLength = 1;
329+ return *this;
330+ }
331+ // 指定の文字列に変更する。
332+ // 引数:
333+ // source 変更する文字列。
334+ // 返値:
335+ // 変更結果。
336+ WStringBuffer& set(const char* source) {
337+ size_t length = strlen(source);
338+ ensureCapacity(validLength = length);
339+ memcpy(buffer, source, length);
340+ return *this;
341+ }
342+
343+ // char*に変換するキャスト演算子。
344+ // バッファのアドレスを取得する。
345+ // 返値:
346+ // バッファのアドレス。
347+ operator wchar_t*() {
348+ return buffer;
349+ }
350+ // Stringに変換するキャスト演算子。
351+ // 文字列を取得する。
352+ // 返値:
353+ // 現在設定されている文字列。
354+ operator WString()const {
355+ return toString();
356+ }
357+ // 代入演算子。
358+ // 一文字だけの文字列に変更する。
359+ // 引数:
360+ // ch 変更する一文字。
361+ // 返値:
362+ // 代入結果。
363+ WStringBuffer& operator=(char ch) {
364+ return set(ch);
365+ }
366+ // 代入演算子。
367+ // 指定の文字列に変更する。
368+ // 引数:
369+ // source 変更する文字列。
370+ // 返値:
371+ // 代入結果。
372+ WStringBuffer& operator=(const char* source) {
373+ return set(source);
374+ }
375+ // 連結代入演算子。
376+ // 文字を追加する。
377+ // 引数:
378+ // ch 追加する文字。
379+ // 返値:
380+ // 代入結果。
381+ WStringBuffer& operator+=(char ch) {
382+ return append(ch);
383+ }
384+ // 連結代入演算子。
385+ // 文字列を追加する。
386+ // 引数:
387+ // source 追加する文字列。
388+ // 返値:
389+ // 代入結果。
390+ WStringBuffer& operator+=(const wchar_t* source) {
391+ return append(source);
392+ }
393+};
394+
395+}
396+
397+#endif//_YCL_WSTRINGBUFFER_H_
--- trunk/TTProxy/YCL/include/YCL/Window.h (revision 9470)
+++ trunk/TTProxy/YCL/include/YCL/Window.h (revision 9471)
@@ -10,6 +10,7 @@
1010 #include <YCL/common.h>
1111
1212 #include <YCL/String.h>
13+#include <YCL/WString.h>
1314
1415 namespace yebisuya {
1516
@@ -37,9 +38,15 @@
3738 int GetWindowTextLength()const {
3839 return ::GetWindowTextLength(window);
3940 }
41+ int GetWindowTextLengthW()const {
42+ return ::GetWindowTextLengthW(window);
43+ }
4044 int GetWindowText(char* buffer, int size)const {
4145 return ::GetWindowText(window, buffer, size);
4246 }
47+ int GetWindowTextW(wchar_t* buffer, int size)const {
48+ return ::GetWindowTextW(window, buffer, size);
49+ }
4350 String GetWindowText()const {
4451 int length = GetWindowTextLength();
4552 char* buffer = (char*) alloca(length + 1);
@@ -46,9 +53,18 @@
4653 GetWindowText(buffer, length + 1);
4754 return buffer;
4855 }
56+ WString GetWindowTextW()const {
57+ int length = GetWindowTextLengthW();
58+ wchar_t* buffer = (wchar_t*) alloca(sizeof(wchar_t) * (length + 1));
59+ GetWindowTextW(buffer, length + 1);
60+ return buffer;
61+ }
4962 bool SetWindowText(const char* text) {
5063 return ::SetWindowText(window, text) != FALSE;
5164 }
65+ bool SetWindowTextW(const wchar_t* text) {
66+ return ::SetWindowTextW(window, text) != FALSE;
67+ }
5268 LRESULT SendMessage(UINT message, WPARAM wparam = 0, LPARAM lparam = 0)const {
5369 return ::SendMessage(window, message, wparam, lparam);
5470 }
--- trunk/teraterm/common/ttlib.h (revision 9470)
+++ trunk/teraterm/common/ttlib.h (revision 9471)
@@ -189,6 +189,8 @@
189189 BOOL IsTextW(const wchar_t *str, size_t len);
190190 wchar_t *NormalizeLineBreakCR(const wchar_t *src, size_t *len);
191191 wchar_t *NormalizeLineBreakCRLF(const wchar_t *src_);
192+BOOL IsRelativePathA(const char *path);
193+BOOL IsRelativePathW(const wchar_t *path);
192194
193195 #ifdef __cplusplus
194196 }
--- trunk/teraterm/common/ttlib_static_cpp.cpp (revision 9470)
+++ trunk/teraterm/common/ttlib_static_cpp.cpp (revision 9471)
@@ -1106,7 +1106,7 @@
11061106 PWSTR pPath;
11071107 hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pPath);
11081108 if (SUCCEEDED(hr)) {
1109- *folder = wcsdup(pPath);
1109+ *folder = _wcsdup(pPath);
11101110 CoTaskMemFree(pPath);
11111111 result = TRUE;
11121112 }
@@ -1246,3 +1246,23 @@
12461246 }
12471247 wcsncat_s(FName,destlen,Temp,_TRUNCATE);
12481248 }
1249+
1250+/**
1251+ * pathが相対パスかどうかを返す
1252+ * TODO "\path\path" は 相対パスではないのではないか?
1253+ */
1254+BOOL IsRelativePathW(const wchar_t *path)
1255+{
1256+ if (path[0] == '\\' || path[0] == '/' || path[0] != '\0' && path[1] == ':') {
1257+ return FALSE;
1258+ }
1259+ return TRUE;
1260+}
1261+
1262+BOOL IsRelativePathA(const char *path)
1263+{
1264+ if (path[0] == '\\' || path[0] == '/' || path[0] != '\0' && path[1] == ':') {
1265+ return FALSE;
1266+ }
1267+ return TRUE;
1268+}
Show on old repository browser