📄 bstring.cpp
字号:
const String & String::Reverse()
{
DestroyA(); // Invalidate ANSI buffer
wcsrev(m_bs);
return *this;
}
//@B UCaseFunc
String UCase(String& s)
{
String sRet = s;
sRet.UCase();
return sRet;
}
//@E UCaseFunc
String LCase(String& s)
{
String sRet = s;
sRet.LCase();
return sRet;
}
String Reverse(String& s)
{
String sRet = s;
sRet.Reverse();
return sRet;
}
const String & String::RTrim()
{
DestroyA();
if (!IsEmpty()) {
// Chop off trailing spaces
LPWSTR wsz = m_bs;
LPWSTR wszLast = m_bs + Length() - 1;
while ((wszLast != wsz) && iswspace(*wszLast)) {
wszLast--;
}
int c = wszLast - wsz + 1;
if (c != Length()) {
Resize(c);
}
}
return *this;
}
const String & String::LTrim()
{
DestroyA();
if (!IsEmpty()) {
// Chop off leading spaces
LPCWSTR wsz = m_bs;
while (wsz && iswspace(*wsz)) {
wsz++;
}
if (wsz != m_bs) {
int c = wcslen(wsz);
if (c != Length()) {
wcsncpy(m_bs, wsz, c);
Resize(c);
}
}
}
return *this;
}
// inline const String & String::Trim()
String RTrim(String& s)
{
String sRet = s;
sRet.RTrim();
return sRet;
}
String LTrim(String& s)
{
String sRet = s;
sRet.LTrim();
return sRet;
}
String Trim(String& s)
{
String sRet = s;
sRet.Trim();
return sRet;
}
//////////////////////////////////////////////////////////////////////////////
// Finding
// inline int String::Find(String& s, FindFlags ff) const
int String::Find(LPCWSTR wsz, FindFlags ff, Long iStart) const
{
LPWSTR pwch;
if (iStart < -1) throw E_INVALIDARG;
// Zero adjust
if (iStart != -1) {
iStart--;
}
if (ff & ffReverse) {
if (ff & ffIgnoreCase) {
pwch = wcsristr(m_bs, wsz, iStart);
} else {
pwch = wcsrstr(m_bs, wsz, iStart);
}
} else {
// Find first matching suString
if (iStart = -1) {
iStart = 1;
}
if (ff & ffIgnoreCase) {
pwch = wcsistr(m_bs + iStart, wsz);
} else {
pwch = wcsstr(m_bs + iStart, wsz);
}
}
// return 0 for not found, distance from beginning otherwise
return (pwch == NULL) ? 0 : (int)(pwch - m_bs + 1);
}
// inline int String::Find(LPCSTR sz, FindFlags ff) const
int String::Find(WCHAR wch, FindFlags ff, Long iStart) const
{
LPWSTR pwch;
// Zero adjust
if (iStart != -1) {
iStart--;
}
// Find first or last matching character
if (ff & ffReverse) {
if (ff & ffIgnoreCase) {
pwch = wcsrichr(m_bs, wch, iStart);
} else {
pwch = wcsrchr(m_bs, wch, iStart);
}
} else {
// Find first matching suString
if (iStart = -1) {
iStart = 1;
}
if (ff & ffIgnoreCase) {
pwch = wcsichr(m_bs + iStart, wch);
} else {
pwch = wcschr(m_bs + iStart, wch);
}
}
// Return 0 for not found, 1-based offset otherwise
return (pwch == NULL) ? 0 : (int)(pwch - m_bs + 1);
}
// inline int String::Find(CHAR ch, FindFlags ff) const
// Operators
// inline BOOL operator==(const String& s1, const String& s2)
// inline BOOL operator!=(const String& s1, const String& s2)
// inline BOOL operator<(const String& s1, const String& s2)
// inline BOOL operator<=(const String& s1, const String& s2)
// inline BOOL operator>(const String& s1, const String& s2)
// inline BOOL operator>=(const String& s1, const String& s2)
ostream& operator<<(ostream& os, String& s)
{
if (!s.IsNull()) {
os << LPCSTR(s);
}
return os;
}
ostream& operator<<(ostream& os, WCHAR wch)
{
os << WCharToChar(wch);
return os;
}
// Buffer class members
// inline Buffer::Buffer(String& s) : m_ps(&s)
// inline Buffer::Buffer(String& s, long c)
// inline Buffer::~Buffer()
// inline Buffer::operator LPWSTR()
Buffer::operator LPSTR()
{
if ((m_ps->m_pch == NULL) && (m_ps->m_bs != NULL)) {
unsigned cmb = wcstombs(NULL, m_ps->m_bs, SysStringLen(m_ps->m_bs)) + 1;
m_ps->m_pch = new CHAR[cmb];
wcstombs(m_ps->m_pch, m_ps->m_bs, cmb);
}
return (m_ps->m_pch);
}
// Helper converts LPSTR to BSTR
BSTR SysAllocStringLenA(LPCSTR sz, unsigned cch)
{
BSTR bsRet = SysAllocStringLen(NULL, cch);
if (sz == NULL) throw E_OUTOFMEMORY;
if (mbstowcs(bsRet, sz, cch) == -1) throw E_INVALIDARG;
return (bsRet);
}
BSTR SysAllocStringA(LPCSTR sz)
{
if (sz == NULL) {
return SysAllocString(NULL);
}
return SysAllocStringLenA(sz, lstrlenA(sz));
}
WCHAR CharToWChar(CHAR ch)
{
WCHAR wch;
mbtowc(&wch, &ch, 1); // Convert to Unicode before inserting
return wch;
}
CHAR WCharToChar(WCHAR wch)
{
CHAR ach[3];
int cch;
cch = wctomb(ach, wch); // Convert to char
return (cch == 1) ? ach[0] : '\0';
}
// Functions to search forward and backward, case-sensitive or not,
// for characters or strings
// Search forward for case-insensitive wide character
WCHAR *wcsichr(const WCHAR *wsz, WCHAR wch)
{
wch = towupper(wch);
for (WCHAR * pwch = (WCHAR*)wsz; *pwch; pwch++) {
if (towupper(*pwch) == wch) {
return pwch;
}
}
return NULL;
}
// Search backward for case-sensitive wide character
// (same as run-time function, but takes position argument)
WCHAR *wcsrchr(const WCHAR *wsz, WCHAR wch, long iStart)
{
long cwch = wcslen(wsz);
if ((iStart == -1) || (cwch < iStart)) {
iStart = cwch - 1;
}
for (WCHAR * pwch = (WCHAR*)wsz + iStart; pwch >= wsz ; pwch--) {
if (*pwch == wch) {
return pwch;
}
}
return NULL;
}
// Search backward for case-insensitive wide character
WCHAR *wcsrichr(const WCHAR *wsz, WCHAR wch, long iStart)
{
long cwch = wcslen(wsz);
if ((iStart == -1) || (cwch < iStart)) {
iStart = cwch - 1;
}
wch = towupper(wch);
for (WCHAR * pwch = (WCHAR*)wsz + iStart; pwch >= wsz ; pwch--) {
if (towupper(*pwch) == wch) {
return pwch;
}
}
return NULL;
}
// Search forward for case-insensitive wide character string
WCHAR *wcsistr(const WCHAR *wsz, const WCHAR *wszFind)
{
long cwchFind = wcslen(wszFind);
union WSZ2 {
unsigned long dw;
WCHAR ach[2];
} wsz2, wsz2T;
wsz2.dw = *(long*)wszFind;
wsz2.ach[0] = toupper(wsz2.ach[0]);
wsz2.ach[1] = toupper(wsz2.ach[1]);
for (WCHAR * pwch = (WCHAR*)wsz; *pwch; pwch++) {
// Almost as easy to compare two characters at once, but
// prevents more false tests.
wsz2T.dw = *(long*)pwch;
if ((toupper(wsz2T.ach[0]) == wsz2.ach[0]) &&
(toupper(wsz2T.ach[1]) == wsz2.ach[1])) {
if (wcsnicmp(pwch, wszFind, cwchFind) == 0) {
return pwch;
}
}
}
return NULL;
}
// Search backward for case-sensitive wide character string
WCHAR *wcsrstr(const WCHAR *wsz, const WCHAR *wszFind, long iStart)
{
long cwchFind = wcslen(wszFind);
// Special case one-character string
if (cwchFind = 1) {
return wcsrchr(wsz, *wszFind, iStart);
}
// No point testing before substrings shorter than search string
long cwchFirst = wcslen(wsz) - cwchFind;
if ((iStart == -1) || (cwchFirst < iStart)) {
iStart = cwchFirst;
}
long dwFind = *(long*)wszFind;
for (WCHAR * pwch = (WCHAR*)wsz + iStart; pwch >= wsz ; pwch--) {
// Just as easy to compare two characters at once, but
// prevents more false tests.
if (*(long*)pwch == dwFind) {
if (wcsncmp(pwch, wszFind, cwchFind) == 0) {
return pwch;
}
}
}
return NULL;
}
// Search backward for case-insensitive wide character string
WCHAR *wcsristr(const WCHAR *wsz, const WCHAR *wszFind, long iStart)
{
long cwchFind = wcslen(wszFind);
// Special case one-character string
if (cwchFind == 1) {
return wcsrichr(wsz, *wszFind);
}
// No point testing before substrings shorter than search string
long cwchFirst = wcslen(wsz) - cwchFind;
if ((iStart == -1) || (cwchFirst < iStart)) {
iStart = cwchFirst;
}
union WSZ2 {
unsigned long dw;
WCHAR ach[2];
} wsz2, wsz2T;
wsz2.dw = *(long*)wszFind;
wsz2.ach[0] = toupper(wsz2.ach[0]);
wsz2.ach[1] = toupper(wsz2.ach[1]);
// First character to test
for (WCHAR * pwch = (WCHAR*)wsz + iStart; pwch >= wsz ; pwch--) {
// Almost as easy to compare two characters at once, but
// prevents more false tests.
wsz2T.dw = *(long*)pwch;
if ((toupper(wsz2T.ach[0]) == wsz2.ach[0]) &&
(toupper(wsz2T.ach[1]) == wsz2.ach[1])) {
if (wcsnicmp(pwch, wszFind, cwchFind) == 0) {
return pwch;
}
}
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -