Revision: 9471 https://osdn.net/projects/ttssh2/scm/svn/commits/9471 Author: zmatsuo Date: 2021-10-14 23:52:23 +0900 (Thu, 14 Oct 2021) 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() を追加 Modified Paths: -------------- trunk/TTProxy/CMakeLists.txt trunk/TTProxy/Logger.h trunk/TTProxy/ProxyWSockHook.h trunk/TTProxy/TTProxy.h trunk/TTProxy/YCL/include/YCL/IniFile.h trunk/TTProxy/YCL/include/YCL/StringUtil.h trunk/TTProxy/YCL/include/YCL/Window.h trunk/teraterm/common/ttlib.h trunk/teraterm/common/ttlib_static_cpp.cpp Added Paths: ----------- trunk/TTProxy/YCL/include/YCL/WString.h trunk/TTProxy/YCL/include/YCL/WStringBuffer.h Removed Paths: ------------- trunk/TTProxy/YCL/include/YCL/wstring.h -------------- next part -------------- Modified: trunk/TTProxy/CMakeLists.txt =================================================================== --- trunk/TTProxy/CMakeLists.txt 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/CMakeLists.txt 2021-10-14 14:52:23 UTC (rev 9471) @@ -70,7 +70,6 @@ PRIVATE YCL/include/YCL/Array.h YCL/include/YCL/ComboBoxCtrl.h - YCL/include/YCL/common.h YCL/include/YCL/Dialog.h YCL/include/YCL/DynamicLinkLibrary.h YCL/include/YCL/EditBoxCtrl.h @@ -88,8 +87,10 @@ YCL/include/YCL/StringUtil.h YCL/include/YCL/ValueCtrl.h YCL/include/YCL/Vector.h + YCL/include/YCL/WString.h + YCL/include/YCL/WStringBuffer.h YCL/include/YCL/Window.h - YCL/include/YCL/wstring.h + YCL/include/YCL/common.h ) source_group( Modified: trunk/TTProxy/Logger.h =================================================================== --- trunk/TTProxy/Logger.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/Logger.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -7,6 +7,7 @@ class Logger { private: HANDLE logfile; + WString folder_; Logger():logfile(INVALID_HANDLE_VALUE) { } public: @@ -78,15 +79,26 @@ } public: - static void open(String filename) { + static void open(WString filename) { close(); - if (filename != NULL) { - HANDLE logfile = ::CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (logfile != INVALID_HANDLE_VALUE) { - ::SetFilePointer(logfile, 0, NULL, FILE_END); - instance().logfile = logfile; - } + + if (filename == NULL) { + return; } + + WString full_filename; + if (IsRelativePathW(filename)) { + full_filename = instance().folder_ + L"\\" + filename; + } + else { + full_filename = filename; + } + + HANDLE logfile = ::CreateFileW(full_filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (logfile != INVALID_HANDLE_VALUE) { + ::SetFilePointer(logfile, 0, NULL, FILE_END); + instance().logfile = logfile; + } } static void close() { if (instance().logfile != INVALID_HANDLE_VALUE) { @@ -100,6 +112,9 @@ static void log(const char* label, const unsigned char* data, int size) { instance().debuglog_binary(label, data, size); } + static void set_folder(const WString &folder) { + instance().folder_ = folder; + } }; #endif//_YEBISOCKS_LOGGER_H_ Modified: trunk/TTProxy/ProxyWSockHook.h =================================================================== --- trunk/TTProxy/ProxyWSockHook.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/ProxyWSockHook.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -726,30 +726,29 @@ protected: virtual bool dispatch(UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_COMMAND && wParam == MAKEWPARAM(IDC_REFER, BN_CLICKED)) { - char buffer[1024]; - char uimsg[MAX_UIMSG]; - OPENFILENAME ofn = { - sizeof ofn, - *this, - }; + wchar_t buffer[1024]; + wchar_t uimsg[MAX_UIMSG]; + OPENFILENAMEW ofn = {}; + ofn.lStructSize = get_OPENFILENAME_SIZEW(); + ofn.hwndOwner = *this; ofn.lpstrFile = buffer; - ofn.nMaxFile = countof(buffer); + ofn.nMaxFile = _countof(buffer); ofn.Flags = OFN_LONGNAMES | OFN_NONETWORKBUTTON | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN | OFN_HIDEREADONLY; - UTIL_get_lang_msg("MSG_LOGFILE_SELECT", uimsg, sizeof(uimsg), - "Select Logfile"); + UTIL_get_lang_msgW("MSG_LOGFILE_SELECT", uimsg, _countof(uimsg), + L"Select Logfile"); ofn.lpstrTitle = uimsg; if (logfile != NULL) { - strcpy_s(buffer, sizeof buffer, logfile); + wcscpy_s(buffer, _countof(buffer), logfile); }else{ buffer[0] = '\0'; } - if (::GetSaveFileName(&ofn)) { + if (::GetSaveFileNameW(&ofn)) { if (buffer[0] != '\0') { logfile = buffer; }else{ logfile = NULL; } - log.SetWindowText(buffer); + log.SetWindowTextW(buffer); } return true; } @@ -806,7 +805,7 @@ erro.SetWindowText(ErrorMessage); if (logfile != NULL) - log.SetWindowText(logfile); + log.SetWindowTextW(logfile); CenterWindow((HWND)*this, GetParent()); @@ -835,7 +834,7 @@ ConnectedMessage = conn.GetWindowText(); ErrorMessage = erro.GetWindowText(); - logfile = log.GetWindowTextLength() > 0 ? log.GetWindowText() : NULL; + logfile = log.GetWindowTextLengthW() > 0 ? log.GetWindowTextW() : NULL; Dialog::onOK(); } @@ -843,7 +842,7 @@ Dialog::onCancel(); } public: - String logfile; + WString logfile; int timeout; int resolve; @@ -1089,11 +1088,11 @@ }; SetI18nDlgStrsW(hWnd, "TTProxy", text_info, _countof(text_info), UILanguageFileW); - UTIL_get_lang_msgW("DLG_ABOUT_EXTENSION", uimsg, sizeof(uimsg), + UTIL_get_lang_msgW("DLG_ABOUT_EXTENSION", uimsg, _countof(uimsg), L"Tera Term proxy extension"); - UTIL_get_lang_msgW("DLG_ABOUT_YEBISUYA", uimsg2, sizeof(uimsg2), + UTIL_get_lang_msgW("DLG_ABOUT_YEBISUYA", uimsg2, _countof(uimsg2), L"YebisuyaHompo"); - UTIL_get_lang_msgW("DLG_ABOUT_HOMEPAGE", uimsg3, sizeof(uimsg3), + UTIL_get_lang_msgW("DLG_ABOUT_HOMEPAGE", uimsg3, _countof(uimsg3), L"TTProxy home page"); GetDlgItemTextW(hWnd, IDC_VERSION, buf, _countof(buf)); len = wcslen(buf) + 50; @@ -2146,7 +2145,7 @@ return ORIG_closesocket(s); } - String logfile; + WString logfile; int timeout; enum SocksResolve { RESOLVE_AUTO, @@ -2218,7 +2217,7 @@ prompt_table[3] = ini.getString("TelnetConnectedMessage", "-- Connected to "); prompt_table[4] = ini.getString("TelnetErrorMessage", "!!!!!!!!"); - logfile = ini.getString("DebugLog"); + logfile = ini.getStringW(L"DebugLog"); Logger::open(logfile); } void _save(IniFile& ini) { @@ -2269,7 +2268,7 @@ ini.setString("TelnetConnectedMessage", prompt_table[3]); ini.setString("TelnetErrorMessage", prompt_table[4]); - ini.setString("DebugLog", logfile); + ini.setString(L"DebugLog", logfile); } public: static void setOwner(HWND owner) { @@ -2348,7 +2347,7 @@ static String generateURL() { return instance().defaultProxy.generateURL(); } - static String parseURL(const char* url, BOOL prefix) { + static String parseURL(const char* url, BOOL prefix) { ProxyInfo proxy; String realhost = ProxyInfo::parse(url, proxy); if (realhost != NULL) { Modified: trunk/TTProxy/TTProxy.h =================================================================== --- trunk/TTProxy/TTProxy.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/TTProxy.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -206,6 +206,7 @@ static void PASCAL TTXInit(PTTSet ts, PComVar cv) { getInstance().ts = ts; getInstance().cv = cv; + Logger::set_folder(ts->LogDirW); ProxyWSockHook::setMessageShower(&getInstance().shower); } Modified: trunk/TTProxy/YCL/include/YCL/IniFile.h =================================================================== --- trunk/TTProxy/YCL/include/YCL/IniFile.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/YCL/include/YCL/IniFile.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -16,9 +16,11 @@ #include <YCL/Enumeration.h> #include <YCL/Vector.h> #include <YCL/Hashtable.h> -#include <YCL/wstring.h> +#include <YCL/WString.h> #include "inifile_com.h" +#include "asprintf.h" +#include "codeconv.h" namespace yebisuya { @@ -171,6 +173,23 @@ exists = true; return NULL; } + static WString getStringW(const wchar_t* filename, const char* section, const wchar_t* name, bool& exists, size_t size) { + wchar_t* buffer = (wchar_t*) alloca(sizeof(wchar_t) * size); + wchar_t* sectionW = ToWcharA(section); + size_t len = GetPrivateProfileStringW(sectionW, name, L"\n:", buffer, size, filename); + free(sectionW); + if (len < size - 2) { + // \x89\xFC\x8Ds\x82\xF0\x8A܂\xB6\x8E\x9A\x97\xF1\x82\xCDini\x83t\x83@\x83C\x83\x8B\x82\xA9\x82\xE7\x82͎擾\x82ł\xAB\x82Ȃ\xA2\x82̂Ŏ擾\x8E\xB8\x94s\x82\xB5\x82\xBD\x82\xB1\x82Ƃ\xAA\x95\xAA\x82\xA9\x82\xE9 + if (buffer[0] == '\n') { + exists = false; + return NULL; + } + // \x83G\x83X\x83P\x81[\x83v\x95\xB6\x8E\x9A\x82\xF0\x93W\x8AJ + return StringUtil::unescapeW(buffer); + } + exists = true; + return NULL; + } static String generateSectionName(const char* parentSection, const char* subkeyName) { StringBuffer buffer = parentSection; buffer.append('\\'); @@ -234,6 +253,21 @@ } return defaultValue; } + WString getStringW(const wchar_t* name)const { + return getStringW(name, NULL); + } + WString getStringW(const wchar_t* name, WString defaultValue)const { + if (filename != NULL && section != NULL && name != NULL) { + size_t size = 256; + WString string; + bool exists; + while ((string = getStringW(filename, section, name, exists, size)) == NULL && exists) + size += 256; + if (string != NULL) + return string; + } + return defaultValue; + } bool getBoolean(const char* name, bool defaultValue = false)const { String string = getString(name); if (string != NULL) { @@ -263,6 +297,25 @@ } return false; } + bool setString(const wchar_t* name, WString value) { + if (filename == NULL || section == NULL || name == NULL) { + return false; + } + + // NULL\x82łȂ\xAF\x82\xEA\x82G\x83X\x83P\x81[\x83v\x82\xB5\x82Ă\xA9\x82\xE7""\x82Ŋ\x87\x82\xE9 + if (value != NULL) { + WStringBuffer buffer; + buffer.append('"'); + if (!StringUtil::escapeW(buffer, value)) + buffer.append(value); + buffer.append('"'); + value = buffer.toString(); + } + wchar_t *sectionW = ToWcharA(section); + BOOL r = ::WritePrivateProfileStringW(sectionW, name, value, filename); + free(sectionW); + return r != FALSE; + } bool setBoolean(const char* name, bool value) { return setString(name, value ? YES() : NO()); } Modified: trunk/TTProxy/YCL/include/YCL/StringUtil.h =================================================================== --- trunk/TTProxy/YCL/include/YCL/StringUtil.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/YCL/include/YCL/StringUtil.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -11,12 +11,13 @@ #include <YCL/String.h> #include <YCL/StringBuffer.h> +#include <YCL/wStringBuffer.h> namespace yebisuya { class StringUtil { private: - static int hexadecimal(char c) { + static int hexadecimal(wchar_t c) { if ('0' <= c && c <= '9') { return c - '0'; }else if ('A' <= c && c <= 'F') { @@ -27,9 +28,15 @@ return -1; } } - static int octet(char c) { + static int hexadecimal(char c) { + return hexadecimal((wchar_t)c); + } + static int octet(wchar_t c) { return '0' <= c && c <= '7' ? c - '0' : -1; } + static int octet(char c) { + return octet((wchar_t)c); + } static const char* ESCAPE_CHARS() { static const char string[] = "abfnrtv"; return string; @@ -44,7 +51,7 @@ return NULL; return escape(string, 0, string.length()); } - static String escape(String string, int offset, int length) { + static String escape(String string, int offset, size_t length) { if (string == NULL) return NULL; StringBuffer buffer; @@ -55,7 +62,7 @@ return false; return escape(buffer, string, 0, string.length()); } - static bool escape(StringBuffer& buffer, String string, int offset, int length) { + static bool escape(StringBuffer& buffer, String string, size_t offset, size_t length) { if (string == NULL) return false; const char* start = string; @@ -64,7 +71,7 @@ const char* end = start + length; while (p < end && *p != '\0') { char ch = *p; - if ('\0' < ch && ch < ' ' || ch == '\'' || ch == '"' || ch == '?' || ch == '\\') { + if (('\0' < ch && ch < ' ') || ch == '\'' || ch == '"' || ch == '?' || ch == '\\') { bool useOctet; if (ch < ' ') { useOctet = true; @@ -105,6 +112,70 @@ return true; } + static WString escapeW(WString string) { + if (string == NULL) + return NULL; + return escapeW(string, 0, string.length()); + } + static WString escapeW(WString string, size_t offset, size_t length) { + if (string == NULL) + return NULL; + WStringBuffer buffer; + return escapeW(buffer, string, offset, length) ? buffer.toString() : string; + } + static bool escapeW(WStringBuffer& buffer, WString string) { + if (string == NULL) + return false; + return escapeW(buffer, string, 0, string.length()); + } + static bool escapeW(WStringBuffer& buffer, WString string, size_t offset, size_t length) { + if (string == NULL) + return false; + const wchar_t* start = string; + start += offset; + const wchar_t* p = start; + const wchar_t* end = start + length; + while (p < end && *p != '\0') { + wchar_t ch = *p; + if (('\0' < ch && ch < ' ') || ch == '\'' || ch == '"' || ch == '?' || ch == '\\') { + bool useOctet; + if (ch < ' ') { + useOctet = true; + for (int index = 0; CONTROL_CHARS()[index] != '\0'; index++) { + if (ch == CONTROL_CHARS()[index]) { + ch = ESCAPE_CHARS()[index]; + useOctet = false; + break; + } + } + }else{ + useOctet = false; + } + if (p > start) { + buffer.append(start, p - start); + } + buffer.append('\\'); + if (useOctet) { + int octet = 6; + while (octet >= 0) { + buffer.append((char) ('0' + ((ch >> octet) & 0x07))); + octet -= 3; + } + }else{ + buffer.append(ch); + } + start = ++p; + }else{ + p++; + } + } + if (start == (const wchar_t*) string) { + return false; + } + buffer.append(start); + return true; + } + static String unescape(String string) { if (string == NULL) return NULL; @@ -198,6 +269,97 @@ buffer.append(start); return true; } + + static WString unescapeW(WString string) { + if (string == NULL) + return NULL; + return unescapeW(string, 0, string.length()); + } + static WString unescapeW(WString string, int offset, int length) { + if (string == NULL) + return NULL; + WStringBuffer buffer; + return unescapeW(buffer, string) ? buffer.toString() : string; + } + static bool unescapeW(WStringBuffer& buffer, WString string) { + if (string == NULL) + return false; + return unescapeW(buffer, string, 0, string.length()); + } + static bool unescapeW(WStringBuffer& buffer, WString string, size_t offset, size_t length) { + if (string == NULL) + return false; + const wchar_t* start = string; + start += offset; + const wchar_t* p = start; + const wchar_t* end = start + length; + while (p < end && *p != '\0') { + if (*p == '\\') { + if (p > start) { + buffer.append(start, p - start); + start = p; + } + wchar_t ch = '\0'; + switch (*++p) { + case '\'': + case '"': + case '\\': + case '?': + ch = *p++; + break; + case 'x': + case 'X': + { + int ch1 = hexadecimal(*++p); + if (ch1 != -1) { + int ch2 = hexadecimal(*++p); + if (ch2 != -1) { + p++; + ch = (char) (ch1 << 4 | ch2); + }else{ + ch = (char) ch1; + } + } + } + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + ch = octet(*p); + int d = octet(*++p); + if (d != -1) { + ch = (ch << 3 | d); + d = octet(*++p); + if (d != -1) { + ch = (ch << 3 | d); + p++; + } + } + } + break; + default: + for (int index = 0; ESCAPE_CHARS()[index] != '\0'; index++) { + if (*p == ESCAPE_CHARS()[index]) { + ch = CONTROL_CHARS()[index]; + p++; + break; + } + } + } + if (ch != '\0') { + buffer.append(ch); + start = p; + } + }else{ + p++; + } + } + if (start == (const wchar_t*) string) { + return false; + } + buffer.append(start); + return true; + } }; } Copied: trunk/TTProxy/YCL/include/YCL/WString.h (from rev 9470, trunk/TTProxy/YCL/include/YCL/wstring.h) =================================================================== --- trunk/TTProxy/YCL/include/YCL/WString.h (rev 0) +++ trunk/TTProxy/YCL/include/YCL/WString.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -0,0 +1,686 @@ +/* + * Copyright (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* String.h \x82\xF0\x8A\xEE\x82ɍ쐬 */ + +#ifndef _YCL_WSTRING_H_ +#define _YCL_WSTRING_H_ + +#pragma once + +#include <YCL/common.h> + +#include <string.h> +#include <wchar.h> + +namespace yebisuya { + +// \x95\xB6\x8E\x9A\x97\xF1\x82̊Ǘ\x9D\x81E\x91\x80\x8D\xEC\x82\xF0\x8Ds\x82\xA4\x83N\x83\x89\x83X\x81B +class WString { +private: + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x83o\x83b\x83t\x83@\x81B + // \x95\xB6\x8E\x9A\x97\xF1\x82̑O\x82ɂ͎Q\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8E\x9D\x82\xBF\x81A + // \x91\xE3\x93\xFC\x82\xE2\x94j\x8A\xFC\x82̍ۂɂ͂\xBB\x82\xB1\x82\xF0\x95ύX\x82\xB7\x82\xE9\x81B + const wchar_t* string; + + // utilities + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B + // \x95\xB6\x8E\x9A\x97\xF1\x82ƎQ\x8FƃJ\x83E\x83\x93\x83^\x82̕\xAA\x82̗̈\xE6\x82\xF0\x8Am\x95ۂ\xB7\x82\xE9\x81B + // \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82\xCD0\x82ɂȂ\xC1\x82Ă\xA2\x82\xE9\x81B + // \x88\xF8\x90\x94: + // length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B + // \x95Ԓl: + // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B + static wchar_t* createBuffer(size_t length) { + size_t* count = (size_t*) new unsigned char[sizeof (size_t) + sizeof (wchar_t) * (length + 1)]; + *count = 0; + return (wchar_t*) (count + 1); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x8Ai\x94[\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B + static const wchar_t* create(const wchar_t* source) { + return source != NULL ? create(source, wcslen(source)) : NULL; + } + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x8Ai\x94[\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B + // \x95Ԓl: + // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B + static const wchar_t* create(const wchar_t* source, size_t length) { + if (source != NULL) { + wchar_t* buffer = createBuffer(length); + wmemcpy(buffer, source, length); + buffer[length] = '\0'; + return buffer; + } + return NULL; + } + // \x93\xF1\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB5\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str1 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x91O)\x81B + // str2 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x8C\xE3)\x81B + // \x95Ԓl: + // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B + static const wchar_t* concat(const wchar_t* str1, const wchar_t* str2) { + size_t len1 = wcslen(str1); + size_t len2 = wcslen(str2); + wchar_t* buffer = createBuffer(len1 + len2); + wmemcpy(buffer, str1, len1); + wmemcpy(buffer + len1, str2, len2); + buffer[len1 + len2] = '\0'; + return buffer; + } + // private methods + // \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8C\xB8\x82炵\x81A0\x82ɂȂ\xC1\x82\xBD\x82\xE7\x83o\x83b\x83t\x83@\x82\xF0\x94j\x8A\xFC\x82\xB7\x82\xE9\x81B + void release() { + if (string != NULL) { + size_t* count = (size_t*) string - 1; + if (--*count == 0) + delete[] (unsigned char*) count; + } + } + // \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82𑝂₷\x81B + void add() { + if (string != NULL) { + size_t* count = (size_t*) string - 1; + ++*count; + } + } + // \x95ʂ̃o\x83b\x83t\x83@\x82ƒu\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B + // \x8C\xB3\x82̃o\x83b\x83t\x83@\x82̎Q\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8C\xB8\x82炵\x81A + // \x90V\x82\xB5\x82\xA2\x83o\x83b\x83t\x83@\x82̎Q\x8FƃJ\x83E\x83\x93\x83^\x82𑝂₷\x81B + // \x88\xF8\x90\x94: + // source \x92u\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x90V\x82\xB5\x82\xA2\x83o\x83b\x83t\x83@\x81B + void set(const wchar_t* source) { + if (string != source) { + release(); + string = source; + add(); + } + } +public: + // constructor + // \x83f\x83t\x83H\x83\x8B\x83g\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // NULL\x82\xAA\x93\xFC\x82\xC1\x82Ă\xA2\x82\xE9\x82̂ŁA\x82\xB1\x82̂܂܂ŕ\xB6\x8E\x9A\x97삷\x82\xE9\x82ƃA\x83N\x83Z\x83X\x88ᔽ\x82ɂȂ\xE9\x82̂Œ\x8D\x88ӁB + WString():string(NULL) { + } + // \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ew\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString(const wchar_t* source):string(NULL) { + set(create(source)); + } + // \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x82\xB3\x95t\x82\xAB\x82Ŏw\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B + // length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B + WString(const wchar_t* source, size_t length):string(NULL) { + set(create(source, length)); + } + // \x83R\x83s\x81[\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString(const WString& source):string(NULL) { + set(source.string); + } + // \x93\xF1\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // str1 \x91O\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B + // str2 \x8C\xE3\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B + WString(const wchar_t* str1, const wchar_t* str2):string(NULL) { + set(concat(str1, str2)); + } + // \x93\xF1\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // str1 \x91O\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B + // str2 \x8C\xE3\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B + WString(const WString& str1, const wchar_t* str2):string(NULL) { + set(*str2 != '\0' ? concat(str1.string, str2) : str1.string); + } + // destructor + // \x83f\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x94h\x90\xB6\x82\xB7\x82邱\x82Ƃ͍l\x82\xA6\x82Ă\xA2\x82Ȃ\xA2\x82̂ʼn\xBC\x91z\x8A\x94\x82ɂ͂\xB5\x82Ȃ\xA2\x81B + ~WString() { + release(); + } + // public methods + // \x82\xB1\x82̕\xB6\x8E\x9A\x97\xF1\x82̌\xE3\x82Ɏw\x92\xE8\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x98A\x8C\x8B\x82\xB3\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x81B + WString concat(const wchar_t* source)const { + return WString(*this, source); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x8Ds\x82\xA4\x81B + // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82\xCE0\x81Astr\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82Ε\x89\x81A\x8F\xAC\x82\xB3\x82\xAF\x82\xEA\x82ΐ\xB3\x81B + int compareTo(const wchar_t* str)const { + if (str == NULL) + return string == NULL ? 0 : 1; + else if (string == NULL) + return -1; + return wcscmp(string, str); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x91啶\x8E\x9A\x8F\xAC\x95\xB6\x8E\x9A\x82̋\xE6\x95ʂȂ\xB5\x82ōs\x82\xA4\x81B + // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82\xCE0\x81Astr\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82Ε\x89\x81A\x8F\xAC\x82\xB3\x82\xAF\x82\xEA\x82ΐ\xB3\x81B + int compareToIgnoreCase(const wchar_t* str)const { + if (str == NULL) + return string == NULL ? 0 : 1; + else if (string == NULL) + return -1; + return _wcsicmp(string, str); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x8Ds\x82\xA4\x81B + // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool equals(const wchar_t* str)const { + return compareTo(str) == 0; + } + // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x91啶\x8E\x9A\x8F\xAC\x95\xB6\x8E\x9A\x82̋\xE6\x95ʂȂ\xB5\x82ōs\x82\xA4\x81B + // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool equalsIgnoreCase(const wchar_t* str)const { + return compareToIgnoreCase(str) == 0; + } + // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B + bool startsWith(const wchar_t* str)const { + return startsWith(str, 0); + } + // \x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B + bool startsWith(const wchar_t* str, int offset)const { + return wcsncmp(string, str, wcslen(str)) == 0; + } + // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82ŏI\x82\xED\x82\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82ŏI\x82\xED\x82\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B + // + bool endsWith(const wchar_t* str)const { + size_t str_length = wcslen(str); + size_t string_length = length(); + if (string_length < str_length) + return false; + return wcscmp(string + string_length - str_length, str) == 0; + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x82ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x92T\x82\xB7\x81B + // \x88\xF8\x90\x94: + // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + int indexOf(char chr)const { + return indexOf(chr, 0); + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x82ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B + // \x88\xF8\x90\x94: + // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B + // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + int indexOf(wchar_t chr, size_t from)const { + if (from >= length()) + return -1; + const wchar_t* found = wcschr(string + from, chr); + if (found == NULL) + return -1; + return found - string; + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x92T\x82\xB7\x81B + // \x88\xF8\x90\x94: + // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + int indexOf(const wchar_t* str)const { + return indexOf(str, 0); + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B + // \x88\xF8\x90\x94: + // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B + // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + // + int indexOf(const wchar_t* str, size_t from)const { + if (from >= length()) + return -1; + const wchar_t* found = wcsstr(string + from, str); + if (found == NULL) + return -1; + return found - string; + } + // \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x82\xF0\x95Ԃ\xB7\x81B + size_t length()const { + return wcslen(string); + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x8DŌ\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + int lastIndexOf(char chr)const { + return lastIndexOf(chr, (size_t) -1); + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x8Ew\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B + // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + int lastIndexOf(wchar_t chr, size_t from)const { + size_t len = length(); + if (from > len - 1) + from = len - 1; + const wchar_t* s = string; + const wchar_t* end = string + from; + const wchar_t* found = NULL; + while (*s != '0' && s <= end) { + if (*s == chr) + found = s; + s++; + } + return found != NULL ? found - string : -1; + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97Ō\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + int lastIndexOf(const wchar_t* str)const { + return lastIndexOf(str, (size_t) -1); + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97w\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B + // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B + int lastIndexOf(const wchar_t* str, size_t from)const { + size_t len = length(); + size_t str_len = wcslen(str); + if (from > len - str_len) + from = len - str_len; + const wchar_t* s = string + from; + while (s >= string) { + if (wcsncmp(s, str, str_len) == 0) + return s - string; + s--; + } + return -1; + } + // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B + // \x88\xF8\x90\x94: + // start \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̐擪\x82̈ʒu\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x81B + WString substring(int start)const { + return WString(string + start); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B + // \x88\xF8\x90\x94: + // start \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̐擪\x82̈ʒu\x81B + // end \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̌\xE3\x82̈ʒu\x81B + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x81B + WString substring(int start, int end)const { + return WString(string + start, end - start); + } + // \x8Ew\x92\xE8\x82̈ʒu\x82ɂ\xA0\x82镶\x8E\x9A\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B + // \x88\xF8\x90\x94: + // index \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x82̈ʒu\x81B + // \x95Ԓl: + // \x8Ew\x92\xE8\x82̈ʒu\x82ɂ\xA0\x82镶\x8E\x9A\x81B + char charAt(size_t index)const { + return index < length() ? string[index] : '\0'; + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xF0\x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82ɒu\x82\xAB\x8A\xB7\x82\xA6\x82܂\xB7\x81B + // \x88\xF8\x90\x94: + // oldChr \x8C\xB3\x82̕\xB6\x8E\x9A\x81B + // newChr \x92u\x82\xAB\x8A\xB7\x82\xA6\x82镶\x8E\x9A\x81B + // \x95Ԓl: + // \x92u\x8A\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString replace(char oldChr, char newChr)const { + WString result(string); + char* s = (char*) result.string; + while (*s != '\0'){ + if (WString::isLeadByte(*s)) + s++; + else if (*s == oldChr) + *s = newChr; + s++; + } + return result; + } + // \x95\xB6\x8E\x9A\x97̑啶\x8E\x9A\x82\xF0\x8F\xAC\x95\xB6\x8E\x9A\x82ɕϊ\xB7\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x95ϊ\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString toLowerCase()const { + WString result(string); + char* s = (char*) result.string; + while (*s != '\0'){ + if (WString::isLeadByte(*s)) + s++; + else if ('A' <= *s && *s <= 'Z') + *s += 'a' - 'A'; + s++; + } + return result; + } + // \x95\xB6\x8E\x9A\x97̏\xAC\x95\xB6\x8E\x9A\x82\xF0\x91啶\x8E\x9A\x82ɕϊ\xB7\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x95ϊ\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString toUpperCase()const { + WString result(string); + char* s = (char*) result.string; + while (*s != '\0'){ + if (WString::isLeadByte(*s)) + s++; + else if ('a' <= *s && *s <= 'z') + *s += 'A' - 'a'; + s++; + } + return result; + } + // \x95\xB6\x8E\x9A\x97\xF1\x82̑O\x8C\xE3\x82̋\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x8D폜\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString trim()const { + const wchar_t* s = string; + while (*s != '\0' && (unsigned char) *s <= ' ') + s++; + const wchar_t* start = s; + s = string + length(); + while (s > start && (*s != '\0' && (unsigned char) *s <= ' ')) + s--; + return WString(start, s - start); + } + + // operators + + // const char*\x82ւ̃L\x83\x83\x83X\x83g\x89\x89\x8EZ\x8Eq + // \x95Ԓl: + // \x95\xB6\x8E\x9A\x97\xF1\x82ւ̃A\x83h\x83\x8C\x83X\x81B + operator const wchar_t*()const { + return string; + } + // char\x94z\x97\xF1\x82̂悤\x82Ɉ\xB5\x82\xA4\x82\xBD\x82߂\xCC[]\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // index \x8E擾\x82\xB7\x82镶\x8E\x9A\x82̃C\x83\x93\x83f\x83b\x83N\x83X\x81B + // \x95Ԓl: + // \x8Ew\x92\xE8\x82̃C\x83\x93\x83f\x83b\x83N\x83X\x82ɂ\xA0\x82镶\x8E\x9A\x81B + char operator[](size_t index)const { + return charAt(index); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B + WString operator+(const wchar_t* source)const { + return WString(string, source); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B + WString operator+(const WString& source)const { + return *string != '\0' ? WString(string, source.string) : source; + } + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str1 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x91O)\x81B + // str2 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x8C\xE3)\x81B + // \x95Ԓl: + // \x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B + friend WString operator+(const wchar_t* str1, const WString& str2) { + return *str1 != '\0' ? WString(str1, str2.string) : str2; + } + // \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // source \x91\xE3\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB + WString& operator=(const wchar_t* source) { + set(create(source)); + return *this; + } + // \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // source \x91\xE3\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB + WString& operator=(const WString& source) { + set(source.string); + return *this; + } + // \x98A\x8C\x8B\x82\xB5\x82\xBD\x8C\x8B\x89ʂ\xF0\x91\xE3\x93\xFC\x82\xB7\x82鉉\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x98A\x8C\x8B\x8C\x8B\x89ʁB + WString& operator+=(const wchar_t* source) { + if (*source != '\0') + set(concat(string, source)); + return *this; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator==(const WString& str)const { + return compareTo(str.string) == 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator==(const wchar_t* str)const { + return compareTo(str) == 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + friend bool operator==(const wchar_t* str1, const WString& str2) { + return str2.compareTo(str1) == 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B + bool operator!=(const WString& str)const { + return compareTo(str) != 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B + bool operator!=(const wchar_t* str)const { + return compareTo(str) != 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B + friend bool operator!=(const wchar_t* str1, const WString& str2) { + return str2.compareTo(str1) != 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator<(const WString& str)const { + return compareTo(str) < 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator<(const wchar_t* str)const { + return compareTo(str) < 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str1\x82\xE6\x82\xE8str2\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B + friend bool operator<(const wchar_t* str1, const WString& str2) { + return str2.compareTo(str1) > 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator<=(const WString& str)const { + return compareTo(str) <= 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator<=(const wchar_t* str)const { + return compareTo(str) <= 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str1\x82\xE6\x82\xE8str2\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + friend bool operator<=(const wchar_t* str1, const WString& str2) { + return str2.compareTo(str1) >= 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator>(const WString& str)const { + return compareTo(str) > 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator>(const wchar_t* str)const { + return compareTo(str) > 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B + friend bool operator>(const wchar_t* str1, const WString& str2) { + return str2.compareTo(str1) < 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator>=(const WString& str)const { + return compareTo(str) >= 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + bool operator>=(const wchar_t* str)const { + return compareTo(str) >= 0; + } + // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B + // \x88\xF8\x90\x94: + // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B + friend bool operator>=(const wchar_t* str1, const WString& str2) { + return str2.compareTo(str1) <= 0; + } + + // public utilities + + // 2\x83o\x83C\x83g\x95\xB6\x8E\x9A\x82̍ŏ\x89\x82\xCC1\x83o\x83C\x83g\x82\xA9\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B + // \x88\xF8\x90\x94: + // \x94\xBB\x92肷\x82\xE9\x83o\x83C\x83g\x81B + // \x95Ԓl: + // 2\x83o\x83C\x83g\x95\xB6\x8E\x9A\x82̍ŏ\x89\x82\xCC1\x83o\x83C\x83g\x82ł\xA0\x82\xEA\x82ΐ^\x81B + static bool isLeadByte(char ch) { + #ifdef _INC_WINDOWS + return ::IsDBCSLeadByte(ch) != 0; + #else + return (ch & 0x80) != 0; + #endif + } +}; + +} + +#endif//_YCL_WSTRING_H_ Added: trunk/TTProxy/YCL/include/YCL/WStringBuffer.h =================================================================== --- trunk/TTProxy/YCL/include/YCL/WStringBuffer.h (rev 0) +++ trunk/TTProxy/YCL/include/YCL/WStringBuffer.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* StringBuffer.h \x82\xF0\x8A\xEE\x82ɍ쐬 */ + +#ifndef _YCL_WSTRINGBUFFER_H_ +#define _YCL_WSTRINGBUFFER_H_ + +#pragma once + +#include <YCL/common.h> + +#include <YCL/WString.h> + +#include <malloc.h> + +namespace yebisuya { + +// \x89ϒ\xB7\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x88\xB5\x82\xA4\x82\xBD\x82߂̃N\x83\x89\x83X\x81B +class WStringBuffer { +private: + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x83o\x83b\x83t\x83@\x81B + wchar_t* buffer; + // \x8C\xBB\x8DݗL\x8C\xF8\x82ȕ\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B + size_t validLength; + // \x83o\x83b\x83t\x83@\x82̑傫\x82\xB3\x81B + size_t bufferSize; + enum { + // \x83o\x83b\x83t\x83@\x82\xF0\x8DL\x82\xB0\x82\xE9\x8DۂɎg\x97p\x82\xB7\x82\xE9\x83T\x83C\x83Y\x81B + INIT_CAPACITY = 16, + }; + // \x83o\x83b\x83t\x83@\x82\xF0\x8F\x89\x8A\x{227B0B7}\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x8F\x89\x8A\x{257639A}\x97\xF1\x81B + // length \x8F\x89\x8A\x{257639A}\x97\xF1\x82̒\xB7\x82\xB3\x81B + // capacity \x83o\x83b\x83t\x83@\x82̏\x89\x8A\xFA\x83T\x83C\x83Y\x81B + void init(const wchar_t* source, size_t length, size_t capacity) { + if ((capacity != 0 || length != 0) && capacity < length + INIT_CAPACITY) + capacity = length + INIT_CAPACITY; + validLength = length; + bufferSize = capacity; + if (bufferSize == 0) { + buffer = NULL; + }else{ + buffer = new wchar_t[bufferSize]; + } + if (source != NULL) { + memcpy(buffer, source, validLength); + } + memset(buffer + validLength, '\0', bufferSize - validLength); + } +public: + // \x83f\x83t\x83H\x83\x8B\x83g\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + WStringBuffer() { + init(NULL, 0, 0); + } + // \x83o\x83b\x83t\x83@\x82̏\x89\x8A\xFA\x83T\x83C\x83Y\x82\xF0\x8Ew\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // capacity \x83o\x83b\x83t\x83@\x82̏\x89\x8A\xFA\x83T\x83C\x83Y\x81B + WStringBuffer(size_t capacity) { + init(NULL, 0, capacity); + } + // \x83o\x83b\x83t\x83@\x82̏\x89\x8A\x{257639A}\x97\xF1\x82\xF0\x8Ew\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // source \x8F\x89\x8A\x{257639A}\x97\xF1\x81B + WStringBuffer(const wchar_t* source) { + init(source, wcslen(source), 0); + } + // \x83R\x83s\x81[\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B + // \x88\xF8\x90\x94: + // source \x8F\x89\x8A\x{257639A}\x97\xF1\x81B + WStringBuffer(const WStringBuffer& source) { + init(source.buffer, source.validLength, source.bufferSize); + } + // \x83f\x83X\x83g\x83\x89\x83N\x83^\x81B + ~WStringBuffer() { + delete[] buffer; + } + + // \x8C\xBB\x8DݗL\x8C\xF8\x82ȕ\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x97L\x8C\xF8\x82ȕ\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B + size_t length()const { + return validLength; + } + // \x83o\x83b\x83t\x83@\x82̃T\x83C\x83Y\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x83o\x83b\x83t\x83@\x82̃T\x83C\x83Y\x81B + size_t capacity()const { + return bufferSize; + } + // \x83o\x83b\x83t\x83@\x82̃T\x83C\x83Y\x82\xF0\x8Ew\x92\xE8\x82̒\xB7\x82\xB3\x82\xAA\x8E\xFB\x82܂\xE9\x82悤\x82ɒ\xB2\x90߂\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // newLength \x92\xB2\x90߂\xB7\x82钷\x82\xB3\x81B + void ensureCapacity(size_t newLength) { + if (bufferSize < newLength) { + wchar_t* oldBuffer = buffer; + init(oldBuffer, validLength, newLength + INIT_CAPACITY); + delete[] oldBuffer; + } + } + // \x97L\x8C\xF8\x82ȕ\xB6\x8E\x9A\x97\xF0\x95ύX\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // newLength \x90V\x82\xB5\x82\xA2\x95\xB6\x8E\x9A\x97B + void setLength(size_t newLength) { + if (validLength < newLength) + ensureCapacity(newLength); + validLength = newLength; + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // index \x95\xB6\x8E\x9A\x82̈ʒu\x81B + // \x95Ԓl: + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x81B + char charAt(size_t index)const { + return index < validLength ? buffer[index] : '\0'; + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // index \x95\xB6\x8E\x9A\x82̈ʒu\x81B + // \x95Ԓl: + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x82̎Q\x8FƁB + wchar_t& charAt(size_t index) { + if (index >= validLength) { + ensureCapacity(validLength + 1); + index = validLength++; + } + return buffer[index]; + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x82\xF0\x95ύX\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // index \x95ύX\x82\xB7\x82镶\x8E\x9A\x82̈ʒu\x81B + // chr \x95ύX\x82\xB7\x82镶\x8E\x9A\x81B + void setCharAt(int index, char chr) { + charAt(index) = chr; + } + // \x95\xB6\x8E\x9A\x82\xF0\x92lj\xC1\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // chr \x92lj\xC1\x82\xB7\x82镶\x8E\x9A\x81B + // \x95Ԓl: + // \x92lj\xC1\x8C\x8B\x89ʁB + WStringBuffer& append(wchar_t chr) { + charAt(validLength) = chr; + return *this; + } + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x92lj\xC1\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x92lj\xC1\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x92lj\xC1\x8C\x8B\x89ʁB + WStringBuffer& append(const wchar_t* source) { + return append(source, wcslen(source)); + } + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x92lj\xC1\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x92lj\xC1\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // length \x92lj\xC1\x82\xB7\x82镶\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B + // \x95Ԓl: + // \x92lj\xC1\x8C\x8B\x89ʁB + WStringBuffer& append(const wchar_t* source, size_t length) { + size_t oldLength = validLength; + ensureCapacity(validLength + length); + memcpy(buffer + oldLength, source, length); + validLength += length; + return *this; + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // start \x8D폜\x82\xB7\x82\xE9\x88ʒu\x81B + // \x95Ԓl: + // \x8D폜\x8C\x8B\x89ʁB + WStringBuffer& remove(size_t index) { + return remove(index, index + 1); + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x8D폜\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // start \x8D폜\x82\xB7\x82\xE9\x90擪\x88ʒu\x81B + // end \x8D폜\x82\xB7\x82\xE9\x8FI\x82\xED\x82\xE8\x82̈ʒu\x81B + // \x95Ԓl: + // \x8D폜\x8C\x8B\x89ʁB + WStringBuffer& remove(size_t start, size_t end) { + if (start < end) { + if (end < validLength){ + memcpy(buffer + start, buffer + end, validLength - end); + validLength -= end - start; + }else{ + validLength = start; + } + } + return *this; + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x92u\x8A\xB7\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // start \x92u\x8A\xB7\x82\xB7\x82\xE9\x90擪\x88ʒu\x81B + // end \x92u\x8A\xB7\x82\xB7\x82\xE9\x8FI\x82\xED\x82\xE8\x82̈ʒu\x81B + // source \x92u\x8A\xB7\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x92u\x8A\xB7\x8C\x8B\x89ʁB + WStringBuffer& replace(size_t start, size_t end, const char* source) { + if (end > validLength) + end = validLength; + if (start < end) { + size_t length = strlen(source); + size_t oldLength = validLength; + ensureCapacity(validLength += length - (end - start)); + memcpy(buffer + start + length, buffer + end, oldLength - end); + memcpy(buffer + start, source, length); + } + return *this; + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // start \x8E擾\x82\xB7\x82镶\x8E\x9A\x97\xF1\x82̐擪\x88ʒu\x81B + // \x95Ԓl: + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString substring(size_t index)const { + return WString(buffer + index, validLength - index); + } + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // start \x8E擾\x82\xB7\x82镶\x8E\x9A\x97\xF1\x82̐擪\x88ʒu\x81B + // end \x8E擾\x82\xB7\x82镶\x8E\x9A\x97\xF1\x82̏I\x82\xED\x82\xE8\x82̈ʒu\x81B + // \x95Ԓl: + // \x8Ew\x92\xE8\x82̈ʒu\x82̕\xB6\x8E\x9A\x97\xF1\x81B + WString substring(size_t start, size_t end)const { + if (end > validLength) + end = validLength; + return WString(buffer + start, end - start); + } + // \x8Ew\x92\xE8\x82̈ʒu\x82ɕ\xB6\x8E\x9A\x82\xF0\x91}\x93\xFC\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // index \x91}\x93\xFC\x82\xB7\x82\xE9\x88ʒu\x81B + // source \x91}\x93\xFC\x82\xB7\x82镶\x8E\x9A\x81B + // \x95Ԓl: + // \x91}\x93\xFC\x8C\x8B\x89ʁB + WStringBuffer& insert(size_t index, char chr) { + return insert(index, &chr, 1); + } + // \x8Ew\x92\xE8\x82̈ʒu\x82ɕ\xB6\x8E\x9A\x97\xF1\x82\xF0\x91}\x93\xFC\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // index \x91}\x93\xFC\x82\xB7\x82\xE9\x88ʒu\x81B + // source \x91}\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x91}\x93\xFC\x8C\x8B\x89ʁB + WStringBuffer& insert(size_t index, const char* source) { + return insert(index, source, strlen(source)); + } + // \x8Ew\x92\xE8\x82̈ʒu\x82ɕ\xB6\x8E\x9A\x97\xF1\x82\xF0\x91}\x93\xFC\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // index \x91}\x93\xFC\x82\xB7\x82\xE9\x88ʒu\x81B + // source \x91}\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B + // \x95Ԓl: + // \x91}\x93\xFC\x8C\x8B\x89ʁB + WStringBuffer& insert(size_t index, const char* source, size_t length) { + if (index >= validLength) + index = validLength; + size_t oldLength = validLength; + ensureCapacity(validLength + length); + char* temp = (char*) alloca(oldLength - index); + memcpy(temp, buffer + index, oldLength - index); + memcpy(buffer + index, source, length); + memcpy(buffer + index + length, temp, oldLength - index); + validLength += length; + return *this; + } +#if 0 + // \x95\xB6\x8E\x9A\x97\xF1\x82]\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x94\xBD\x93]\x8C\x8B\x89ʁB + WStringBuffer& reverse() { + char* temporary = (char*) alloca(sizeof (char) * validLength); + char* dst = temporary + validLength; + wchar_t* src = buffer; + while (temporary < dst) { + if (String::isLeadByte(*src)) { + char pre = *src++; + *--dst = *src++; + *--dst = pre; + }else{ + *--dst = *src++; + } + } + memcpy(buffer, temporary, validLength); + return *this; + } +#endif + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x8C\xBB\x8Dݐݒ肳\x82\xEA\x82Ă\xA2\x82镶\x8E\x9A\x97\xF1\x81B + WString toString()const { + return WString(buffer, validLength); + } + + // \x88ꕶ\x8E\x9A\x82\xBE\x82\xAF\x82̕\xB6\x8E\x9A\x97\xF1\x82ɕύX\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // \x95ύX\x82\xB7\x82\xE9\x88ꕶ\x8E\x9A\x81B + // \x95Ԓl: + // \x95ύX\x8C\x8B\x89ʁB + WStringBuffer& set(char chr) { + ensureCapacity(1); + buffer[0] = chr; + validLength = 1; + return *this; + } + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97\xF1\x82ɕύX\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x95ύX\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x95ύX\x8C\x8B\x89ʁB + WStringBuffer& set(const char* source) { + size_t length = strlen(source); + ensureCapacity(validLength = length); + memcpy(buffer, source, length); + return *this; + } + + // char*\x82ɕϊ\xB7\x82\xB7\x82\xE9\x83L\x83\x83\x83X\x83g\x89\x89\x8EZ\x8Eq\x81B + // \x83o\x83b\x83t\x83@\x82̃A\x83h\x83\x8C\x83X\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x83o\x83b\x83t\x83@\x82̃A\x83h\x83\x8C\x83X\x81B + operator wchar_t*() { + return buffer; + } + // String\x82ɕϊ\xB7\x82\xB7\x82\xE9\x83L\x83\x83\x83X\x83g\x89\x89\x8EZ\x8Eq\x81B + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B + // \x95Ԓl: + // \x8C\xBB\x8Dݐݒ肳\x82\xEA\x82Ă\xA2\x82镶\x8E\x9A\x97\xF1\x81B + operator WString()const { + return toString(); + } + // \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B + // \x88ꕶ\x8E\x9A\x82\xBE\x82\xAF\x82̕\xB6\x8E\x9A\x97\xF1\x82ɕύX\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // ch \x95ύX\x82\xB7\x82\xE9\x88ꕶ\x8E\x9A\x81B + // \x95Ԓl: + // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB + WStringBuffer& operator=(char ch) { + return set(ch); + } + // \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B + // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97\xF1\x82ɕύX\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x95ύX\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB + WStringBuffer& operator=(const char* source) { + return set(source); + } + // \x98A\x8C\x8B\x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B + // \x95\xB6\x8E\x9A\x82\xF0\x92lj\xC1\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // ch \x92lj\xC1\x82\xB7\x82镶\x8E\x9A\x81B + // \x95Ԓl: + // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB + WStringBuffer& operator+=(char ch) { + return append(ch); + } + // \x98A\x8C\x8B\x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B + // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x92lj\xC1\x82\xB7\x82\xE9\x81B + // \x88\xF8\x90\x94: + // source \x92lj\xC1\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B + // \x95Ԓl: + // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB + WStringBuffer& operator+=(const wchar_t* source) { + return append(source); + } +}; + +} + +#endif//_YCL_WSTRINGBUFFER_H_ Modified: trunk/TTProxy/YCL/include/YCL/Window.h =================================================================== --- trunk/TTProxy/YCL/include/YCL/Window.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/YCL/include/YCL/Window.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -10,6 +10,7 @@ #include <YCL/common.h> #include <YCL/String.h> +#include <YCL/WString.h> namespace yebisuya { @@ -37,9 +38,15 @@ int GetWindowTextLength()const { return ::GetWindowTextLength(window); } + int GetWindowTextLengthW()const { + return ::GetWindowTextLengthW(window); + } int GetWindowText(char* buffer, int size)const { return ::GetWindowText(window, buffer, size); } + int GetWindowTextW(wchar_t* buffer, int size)const { + return ::GetWindowTextW(window, buffer, size); + } String GetWindowText()const { int length = GetWindowTextLength(); char* buffer = (char*) alloca(length + 1); @@ -46,9 +53,18 @@ GetWindowText(buffer, length + 1); return buffer; } + WString GetWindowTextW()const { + int length = GetWindowTextLengthW(); + wchar_t* buffer = (wchar_t*) alloca(sizeof(wchar_t) * (length + 1)); + GetWindowTextW(buffer, length + 1); + return buffer; + } bool SetWindowText(const char* text) { return ::SetWindowText(window, text) != FALSE; } + bool SetWindowTextW(const wchar_t* text) { + return ::SetWindowTextW(window, text) != FALSE; + } LRESULT SendMessage(UINT message, WPARAM wparam = 0, LPARAM lparam = 0)const { return ::SendMessage(window, message, wparam, lparam); } Deleted: trunk/TTProxy/YCL/include/YCL/wstring.h =================================================================== --- trunk/TTProxy/YCL/include/YCL/wstring.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/TTProxy/YCL/include/YCL/wstring.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -1,684 +0,0 @@ -/* - * Copyright (C) 2021- TeraTerm Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _YCL_WSTRING_H_ -#define _YCL_WSTRING_H_ - -#pragma once - -#include <YCL/common.h> - -#include <string.h> -#include <wchar.h> - -namespace yebisuya { - -// \x95\xB6\x8E\x9A\x97\xF1\x82̊Ǘ\x9D\x81E\x91\x80\x8D\xEC\x82\xF0\x8Ds\x82\xA4\x83N\x83\x89\x83X\x81B -class WString { -private: - // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x83o\x83b\x83t\x83@\x81B - // \x95\xB6\x8E\x9A\x97\xF1\x82̑O\x82ɂ͎Q\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8E\x9D\x82\xBF\x81A - // \x91\xE3\x93\xFC\x82\xE2\x94j\x8A\xFC\x82̍ۂɂ͂\xBB\x82\xB1\x82\xF0\x95ύX\x82\xB7\x82\xE9\x81B - const wchar_t* string; - - // utilities - // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B - // \x95\xB6\x8E\x9A\x97\xF1\x82ƎQ\x8FƃJ\x83E\x83\x93\x83^\x82̕\xAA\x82̗̈\xE6\x82\xF0\x8Am\x95ۂ\xB7\x82\xE9\x81B - // \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82\xCD0\x82ɂȂ\xC1\x82Ă\xA2\x82\xE9\x81B - // \x88\xF8\x90\x94: - // length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B - // \x95Ԓl: - // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B - static wchar_t* createBuffer(size_t length) { - size_t* count = (size_t*) new unsigned char[sizeof (size_t) + sizeof (wchar_t) * (length + 1)]; - *count = 0; - return (wchar_t*) (count + 1); - } - // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // source \x8Ai\x94[\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B - static const wchar_t* create(const wchar_t* source) { - return source != NULL ? create(source, wcslen(source)) : NULL; - } - // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // source \x8Ai\x94[\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B - // \x95Ԓl: - // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B - static const wchar_t* create(const wchar_t* source, size_t length) { - if (source != NULL) { - wchar_t* buffer = createBuffer(length); - wmemcpy(buffer, source, length); - buffer[length] = '\0'; - return buffer; - } - return NULL; - } - // \x93\xF1\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB5\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str1 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x91O)\x81B - // str2 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x8C\xE3)\x81B - // \x95Ԓl: - // \x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97̃A\x83h\x83\x8C\x83X\x81B - static const wchar_t* concat(const wchar_t* str1, const wchar_t* str2) { - size_t len1 = wcslen(str1); - size_t len2 = wcslen(str2); - wchar_t* buffer = createBuffer(len1 + len2); - wmemcpy(buffer, str1, len1); - wmemcpy(buffer + len1, str2, len2); - buffer[len1 + len2] = '\0'; - return buffer; - } - // private methods - // \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8C\xB8\x82炵\x81A0\x82ɂȂ\xC1\x82\xBD\x82\xE7\x83o\x83b\x83t\x83@\x82\xF0\x94j\x8A\xFC\x82\xB7\x82\xE9\x81B - void release() { - if (string != NULL) { - size_t* count = (size_t*) string - 1; - if (--*count == 0) - delete[] (unsigned char*) count; - } - } - // \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82𑝂₷\x81B - void add() { - if (string != NULL) { - size_t* count = (size_t*) string - 1; - ++*count; - } - } - // \x95ʂ̃o\x83b\x83t\x83@\x82ƒu\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B - // \x8C\xB3\x82̃o\x83b\x83t\x83@\x82̎Q\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8C\xB8\x82炵\x81A - // \x90V\x82\xB5\x82\xA2\x83o\x83b\x83t\x83@\x82̎Q\x8FƃJ\x83E\x83\x93\x83^\x82𑝂₷\x81B - // \x88\xF8\x90\x94: - // source \x92u\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x90V\x82\xB5\x82\xA2\x83o\x83b\x83t\x83@\x81B - void set(const wchar_t* source) { - if (string != source) { - release(); - string = source; - add(); - } - } -public: - // constructor - // \x83f\x83t\x83H\x83\x8B\x83g\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B - // NULL\x82\xAA\x93\xFC\x82\xC1\x82Ă\xA2\x82\xE9\x82̂ŁA\x82\xB1\x82̂܂܂ŕ\xB6\x8E\x9A\x97삷\x82\xE9\x82ƃA\x83N\x83Z\x83X\x88ᔽ\x82ɂȂ\xE9\x82̂Œ\x8D\x88ӁB - WString():string(NULL) { - } - // \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ew\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B - // \x88\xF8\x90\x94: - // source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B - WString(const wchar_t* source):string(NULL) { - set(create(source)); - } - // \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x82\xB3\x95t\x82\xAB\x82Ŏw\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B - // \x88\xF8\x90\x94: - // source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B - // length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B - WString(const wchar_t* source, size_t length):string(NULL) { - set(create(source, length)); - } - // \x83R\x83s\x81[\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B - // \x88\xF8\x90\x94: - // source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B - WString(const WString& source):string(NULL) { - set(source.string); - } - // \x93\xF1\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B - // \x88\xF8\x90\x94: - // str1 \x91O\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B - // str2 \x8C\xE3\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B - WString(const wchar_t* str1, const wchar_t* str2):string(NULL) { - set(concat(str1, str2)); - } - // \x93\xF1\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B - // \x88\xF8\x90\x94: - // str1 \x91O\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B - // str2 \x8C\xE3\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B - WString(const WString& str1, const wchar_t* str2):string(NULL) { - set(*str2 != '\0' ? concat(str1.string, str2) : str1.string); - } - // destructor - // \x83f\x83X\x83g\x83\x89\x83N\x83^\x81B - // \x94h\x90\xB6\x82\xB7\x82邱\x82Ƃ͍l\x82\xA6\x82Ă\xA2\x82Ȃ\xA2\x82̂ʼn\xBC\x91z\x8A\x94\x82ɂ͂\xB5\x82Ȃ\xA2\x81B - ~WString() { - release(); - } - // public methods - // \x82\xB1\x82̕\xB6\x8E\x9A\x97\xF1\x82̌\xE3\x82Ɏw\x92\xE8\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x98A\x8C\x8B\x82\xB3\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x81B - WString concat(const wchar_t* source)const { - return WString(*this, source); - } - // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x8Ds\x82\xA4\x81B - // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82\xCE0\x81Astr\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82Ε\x89\x81A\x8F\xAC\x82\xB3\x82\xAF\x82\xEA\x82ΐ\xB3\x81B - int compareTo(const wchar_t* str)const { - if (str == NULL) - return string == NULL ? 0 : 1; - else if (string == NULL) - return -1; - return wcscmp(string, str); - } - // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x91啶\x8E\x9A\x8F\xAC\x95\xB6\x8E\x9A\x82̋\xE6\x95ʂȂ\xB5\x82ōs\x82\xA4\x81B - // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82\xCE0\x81Astr\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82Ε\x89\x81A\x8F\xAC\x82\xB3\x82\xAF\x82\xEA\x82ΐ\xB3\x81B - int compareToIgnoreCase(const wchar_t* str)const { - if (str == NULL) - return string == NULL ? 0 : 1; - else if (string == NULL) - return -1; - return _wcsicmp(string, str); - } - // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x8Ds\x82\xA4\x81B - // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool equals(const wchar_t* str)const { - return compareTo(str) == 0; - } - // \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x91啶\x8E\x9A\x8F\xAC\x95\xB6\x8E\x9A\x82̋\xE6\x95ʂȂ\xB5\x82ōs\x82\xA4\x81B - // NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool equalsIgnoreCase(const wchar_t* str)const { - return compareToIgnoreCase(str) == 0; - } - // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B - bool startsWith(const wchar_t* str)const { - return startsWith(str, 0); - } - // \x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B - bool startsWith(const wchar_t* str, int offset)const { - return wcsncmp(string, str, wcslen(str)) == 0; - } - // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82ŏI\x82\xED\x82\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82ŏI\x82\xED\x82\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B - // - bool endsWith(const wchar_t* str)const { - size_t str_length = wcslen(str); - size_t string_length = length(); - if (string_length < str_length) - return false; - return wcscmp(string + string_length - str_length, str) == 0; - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x82ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x92T\x82\xB7\x81B - // \x88\xF8\x90\x94: - // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - int indexOf(char chr)const { - return indexOf(chr, 0); - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x82ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B - // \x88\xF8\x90\x94: - // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B - // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - int indexOf(wchar_t chr, size_t from)const { - if (from >= length()) - return -1; - const wchar_t* found = wcschr(string + from, chr); - if (found == NULL) - return -1; - return found - string; - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x92T\x82\xB7\x81B - // \x88\xF8\x90\x94: - // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - int indexOf(const wchar_t* str)const { - return indexOf(str, 0); - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B - // \x88\xF8\x90\x94: - // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B - // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - // - int indexOf(const wchar_t* str, size_t from)const { - if (from >= length()) - return -1; - const wchar_t* found = wcsstr(string + from, str); - if (found == NULL) - return -1; - return found - string; - } - // \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x82\xF0\x95Ԃ\xB7\x81B - size_t length()const { - return wcslen(string); - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x8DŌ\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - int lastIndexOf(char chr)const { - return lastIndexOf(chr, (size_t) -1); - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x8Ew\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B - // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - int lastIndexOf(wchar_t chr, size_t from)const { - size_t len = length(); - if (from > len - 1) - from = len - 1; - const wchar_t* s = string; - const wchar_t* end = string + from; - const wchar_t* found = NULL; - while (*s != '0' && s <= end) { - if (*s == chr) - found = s; - s++; - } - return found != NULL ? found - string : -1; - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97Ō\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - int lastIndexOf(const wchar_t* str)const { - return lastIndexOf(str, (size_t) -1); - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97w\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B - // \x88\xF8\x90\x94: - // str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B - // from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B - int lastIndexOf(const wchar_t* str, size_t from)const { - size_t len = length(); - size_t str_len = wcslen(str); - if (from > len - str_len) - from = len - str_len; - const wchar_t* s = string + from; - while (s >= string) { - if (wcsncmp(s, str, str_len) == 0) - return s - string; - s--; - } - return -1; - } - // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B - // \x88\xF8\x90\x94: - // start \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̐擪\x82̈ʒu\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x81B - WString substring(int start)const { - return WString(string + start); - } - // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B - // \x88\xF8\x90\x94: - // start \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̐擪\x82̈ʒu\x81B - // end \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̌\xE3\x82̈ʒu\x81B - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x81B - WString substring(int start, int end)const { - return WString(string + start, end - start); - } - // \x8Ew\x92\xE8\x82̈ʒu\x82ɂ\xA0\x82镶\x8E\x9A\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B - // \x88\xF8\x90\x94: - // index \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x82̈ʒu\x81B - // \x95Ԓl: - // \x8Ew\x92\xE8\x82̈ʒu\x82ɂ\xA0\x82镶\x8E\x9A\x81B - char charAt(size_t index)const { - return index < length() ? string[index] : '\0'; - } - // \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xF0\x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82ɒu\x82\xAB\x8A\xB7\x82\xA6\x82܂\xB7\x81B - // \x88\xF8\x90\x94: - // oldChr \x8C\xB3\x82̕\xB6\x8E\x9A\x81B - // newChr \x92u\x82\xAB\x8A\xB7\x82\xA6\x82镶\x8E\x9A\x81B - // \x95Ԓl: - // \x92u\x8A\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B - WString replace(char oldChr, char newChr)const { - WString result(string); - char* s = (char*) result.string; - while (*s != '\0'){ - if (WString::isLeadByte(*s)) - s++; - else if (*s == oldChr) - *s = newChr; - s++; - } - return result; - } - // \x95\xB6\x8E\x9A\x97̑啶\x8E\x9A\x82\xF0\x8F\xAC\x95\xB6\x8E\x9A\x82ɕϊ\xB7\x82\xB7\x82\xE9\x81B - // \x95Ԓl: - // \x95ϊ\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B - WString toLowerCase()const { - WString result(string); - char* s = (char*) result.string; - while (*s != '\0'){ - if (WString::isLeadByte(*s)) - s++; - else if ('A' <= *s && *s <= 'Z') - *s += 'a' - 'A'; - s++; - } - return result; - } - // \x95\xB6\x8E\x9A\x97̏\xAC\x95\xB6\x8E\x9A\x82\xF0\x91啶\x8E\x9A\x82ɕϊ\xB7\x82\xB7\x82\xE9\x81B - // \x95Ԓl: - // \x95ϊ\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B - WString toUpperCase()const { - WString result(string); - char* s = (char*) result.string; - while (*s != '\0'){ - if (WString::isLeadByte(*s)) - s++; - else if ('a' <= *s && *s <= 'z') - *s += 'A' - 'a'; - s++; - } - return result; - } - // \x95\xB6\x8E\x9A\x97\xF1\x82̑O\x8C\xE3\x82̋\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9\x81B - // \x95Ԓl: - // \x8D폜\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B - WString trim()const { - const wchar_t* s = string; - while (*s != '\0' && (unsigned char) *s <= ' ') - s++; - const wchar_t* start = s; - s = string + length(); - while (s > start && (*s != '\0' && (unsigned char) *s <= ' ')) - s--; - return WString(start, s - start); - } - - // operators - - // const char*\x82ւ̃L\x83\x83\x83X\x83g\x89\x89\x8EZ\x8Eq - // \x95Ԓl: - // \x95\xB6\x8E\x9A\x97\xF1\x82ւ̃A\x83h\x83\x8C\x83X\x81B - operator const wchar_t*()const { - return string; - } - // char\x94z\x97\xF1\x82̂悤\x82Ɉ\xB5\x82\xA4\x82\xBD\x82߂\xCC[]\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // index \x8E擾\x82\xB7\x82镶\x8E\x9A\x82̃C\x83\x93\x83f\x83b\x83N\x83X\x81B - // \x95Ԓl: - // \x8Ew\x92\xE8\x82̃C\x83\x93\x83f\x83b\x83N\x83X\x82ɂ\xA0\x82镶\x8E\x9A\x81B - char operator[](size_t index)const { - return charAt(index); - } - // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B - WString operator+(const wchar_t* source)const { - return WString(string, source); - } - // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B - WString operator+(const WString& source)const { - return *string != '\0' ? WString(string, source.string) : source; - } - // \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str1 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x91O)\x81B - // str2 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x8C\xE3)\x81B - // \x95Ԓl: - // \x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B - friend WString operator+(const wchar_t* str1, const WString& str2) { - return *str1 != '\0' ? WString(str1, str2.string) : str2; - } - // \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // source \x91\xE3\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB - WString& operator=(const wchar_t* source) { - set(create(source)); - return *this; - } - // \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // source \x91\xE3\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x91\xE3\x93\xFC\x8C\x8B\x89ʁB - WString& operator=(const WString& source) { - set(source.string); - return *this; - } - // \x98A\x8C\x8B\x82\xB5\x82\xBD\x8C\x8B\x89ʂ\xF0\x91\xE3\x93\xFC\x82\xB7\x82鉉\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // \x98A\x8C\x8B\x8C\x8B\x89ʁB - WString& operator+=(const wchar_t* source) { - if (*source != '\0') - set(concat(string, source)); - return *this; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator==(const WString& str)const { - return compareTo(str.string) == 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator==(const wchar_t* str)const { - return compareTo(str) == 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - friend bool operator==(const wchar_t* str1, const WString& str2) { - return str2.compareTo(str1) == 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B - bool operator!=(const WString& str)const { - return compareTo(str) != 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B - bool operator!=(const wchar_t* str)const { - return compareTo(str) != 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B - friend bool operator!=(const wchar_t* str1, const WString& str2) { - return str2.compareTo(str1) != 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator<(const WString& str)const { - return compareTo(str) < 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator<(const wchar_t* str)const { - return compareTo(str) < 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str1\x82\xE6\x82\xE8str2\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B - friend bool operator<(const wchar_t* str1, const WString& str2) { - return str2.compareTo(str1) > 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator<=(const WString& str)const { - return compareTo(str) <= 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator<=(const wchar_t* str)const { - return compareTo(str) <= 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str1\x82\xE6\x82\xE8str2\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - friend bool operator<=(const wchar_t* str1, const WString& str2) { - return str2.compareTo(str1) >= 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator>(const WString& str)const { - return compareTo(str) > 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator>(const wchar_t* str)const { - return compareTo(str) > 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B - friend bool operator>(const wchar_t* str1, const WString& str2) { - return str2.compareTo(str1) < 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator>=(const WString& str)const { - return compareTo(str) >= 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - bool operator>=(const wchar_t* str)const { - return compareTo(str) >= 0; - } - // \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B - // \x88\xF8\x90\x94: - // str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B - // \x95Ԓl: - // str1\x82\xE6\x82\xE8str2\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B - friend bool operator>=(const wchar_t* str1, const WString& str2) { - return str2.compareTo(str1) <= 0; - } - - // public utilities - - // 2\x83o\x83C\x83g\x95\xB6\x8E\x9A\x82̍ŏ\x89\x82\xCC1\x83o\x83C\x83g\x82\xA9\x82ǂ\xA4\x82\xA9\x82肷\x82\xE9\x81B - // \x88\xF8\x90\x94: - // \x94\xBB\x92肷\x82\xE9\x83o\x83C\x83g\x81B - // \x95Ԓl: - // 2\x83o\x83C\x83g\x95\xB6\x8E\x9A\x82̍ŏ\x89\x82\xCC1\x83o\x83C\x83g\x82ł\xA0\x82\xEA\x82ΐ^\x81B - static bool isLeadByte(char ch) { - #ifdef _INC_WINDOWS - return ::IsDBCSLeadByte(ch) != 0; - #else - return (ch & 0x80) != 0; - #endif - } -}; - -} - -#endif//_YCL_WSTRING_H_ Modified: trunk/teraterm/common/ttlib.h =================================================================== --- trunk/teraterm/common/ttlib.h 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/teraterm/common/ttlib.h 2021-10-14 14:52:23 UTC (rev 9471) @@ -189,6 +189,8 @@ BOOL IsTextW(const wchar_t *str, size_t len); wchar_t *NormalizeLineBreakCR(const wchar_t *src, size_t *len); wchar_t *NormalizeLineBreakCRLF(const wchar_t *src_); +BOOL IsRelativePathA(const char *path); +BOOL IsRelativePathW(const wchar_t *path); #ifdef __cplusplus } Modified: trunk/teraterm/common/ttlib_static_cpp.cpp =================================================================== --- trunk/teraterm/common/ttlib_static_cpp.cpp 2021-10-14 14:52:13 UTC (rev 9470) +++ trunk/teraterm/common/ttlib_static_cpp.cpp 2021-10-14 14:52:23 UTC (rev 9471) @@ -1106,7 +1106,7 @@ PWSTR pPath; hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pPath); if (SUCCEEDED(hr)) { - *folder = wcsdup(pPath); + *folder = _wcsdup(pPath); CoTaskMemFree(pPath); result = TRUE; } @@ -1246,3 +1246,23 @@ } wcsncat_s(FName,destlen,Temp,_TRUNCATE); } + +/** + * path\x82\xAA\x91\x8A\x91p\x83X\x82\xA9\x82ǂ\xA4\x82\xA9\x82\xF0\x95Ԃ\xB7 + * TODO "\path\path" \x82\xCD \x91\x8A\x91p\x83X\x82ł͂Ȃ\xA2\x82̂ł͂Ȃ\xA2\x82\xA9? + */ +BOOL IsRelativePathW(const wchar_t *path) +{ + if (path[0] == '\\' || path[0] == '/' || path[0] != '\0' && path[1] == ':') { + return FALSE; + } + return TRUE; +} + +BOOL IsRelativePathA(const char *path) +{ + if (path[0] == '\\' || path[0] == '/' || path[0] != '\0' && path[1] == ':') { + return FALSE; + } + return TRUE; +}