📄 string.c
字号:
}
/*************************************************************************
* StrCSpnA [SHLWAPI.@]
*
* Find the length of the start of a string that does not contain certain
* characters.
*
* PARAMS
* lpszStr [I] String to search
* lpszMatch [I] Characters that cannot be in the substring
*
* RETURNS
* The length of the part of lpszStr containing only chars not in lpszMatch,
* or 0 if any parameter is invalid.
*/
int WINAPI StrCSpnA(LPCSTR lpszStr, LPCSTR lpszMatch)
{
TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
return SHLWAPI_StrSpnHelperA(lpszStr, lpszMatch, StrChrA, TRUE);
}
/*************************************************************************
* StrCSpnW [SHLWAPI.@]
*
* See StrCSpnA.
*/
int WINAPI StrCSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
{
if (!lpszStr || !lpszMatch) return 0;
return strcspnW( lpszStr, lpszMatch );
}
/*************************************************************************
* StrCSpnIA [SHLWAPI.@]
*
* Find the length of the start of a string that does not contain certain
* characters, ignoring case.
*
* PARAMS
* lpszStr [I] String to search
* lpszMatch [I] Characters that cannot be in the substring
*
* RETURNS
* The length of the part of lpszStr containing only chars not in lpszMatch,
* or 0 if any parameter is invalid.
*/
int WINAPI StrCSpnIA(LPCSTR lpszStr, LPCSTR lpszMatch)
{
TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
return SHLWAPI_StrSpnHelperA(lpszStr, lpszMatch, StrChrIA, TRUE);
}
/*************************************************************************
* StrCSpnIW [SHLWAPI.@]
*
* See StrCSpnIA.
*/
int WINAPI StrCSpnIW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
{
LPCWSTR lpszRead = lpszStr;
TRACE("(%s,%s)\n",debugstr_w(lpszStr), debugstr_w(lpszMatch));
if (lpszStr && *lpszStr && lpszMatch)
{
while (*lpszRead)
{
if (StrChrIW(lpszMatch, *lpszRead)) break;
lpszRead++;
}
}
return lpszRead - lpszStr;
}
/*************************************************************************
* StrPBrkA [SHLWAPI.@]
*
* Search a string for any of a group of characters.
*
* PARAMS
* lpszStr [I] String to search
* lpszMatch [I] Characters to match
*
* RETURNS
* A pointer to the first matching character in lpszStr, or NULL if no
* match was found.
*/
LPSTR WINAPI StrPBrkA(LPCSTR lpszStr, LPCSTR lpszMatch)
{
TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
if (lpszStr && lpszMatch && *lpszMatch)
{
while (*lpszStr)
{
if (StrChrA(lpszMatch, *lpszStr))
return (LPSTR)lpszStr;
lpszStr = CharNextA(lpszStr);
}
}
return NULL;
}
/*************************************************************************
* StrPBrkW [SHLWAPI.@]
*
* See StrPBrkA.
*/
LPWSTR WINAPI StrPBrkW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
{
if (!lpszStr || !lpszMatch) return NULL;
return strpbrkW( lpszStr, lpszMatch );
}
/*************************************************************************
* SHLWAPI_StrRChrHelperA
*
* Internal implementation of StrRChrA/StrRChrIA.
*/
static LPSTR SHLWAPI_StrRChrHelperA(LPCSTR lpszStr,
LPCSTR lpszEnd, WORD ch,
BOOL (WINAPI *pChrCmpFn)(WORD,WORD))
{
LPCSTR lpszRet = NULL;
if (lpszStr)
{
WORD ch2;
if (!lpszEnd)
lpszEnd = lpszStr + lstrlenA(lpszStr);
while (*lpszStr && lpszStr <= lpszEnd)
{
ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
if (!pChrCmpFn(ch, ch2))
lpszRet = lpszStr;
lpszStr = CharNextA(lpszStr);
}
}
return (LPSTR)lpszRet;
}
/**************************************************************************
* StrRChrA [SHLWAPI.@]
*
* Find the last occurrence of a character in string.
*
* PARAMS
* lpszStr [I] String to search in
* lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
* ch [I] Character to search for.
*
* RETURNS
* Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
* or NULL if not found.
* Failure: NULL, if any arguments are invalid.
*/
LPSTR WINAPI StrRChrA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
{
TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
return SHLWAPI_StrRChrHelperA(lpszStr, lpszEnd, ch, SHLWAPI_ChrCmpA);
}
/**************************************************************************
* StrRChrW [SHLWAPI.@]
*
* See StrRChrA.
*/
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
{
WCHAR *ret = NULL;
if (!str) return NULL;
if (!end) end = str + strlenW(str);
while (str < end)
{
if (*str == ch) ret = (WCHAR *)str;
str++;
}
return ret;
}
/**************************************************************************
* StrRChrIA [SHLWAPI.@]
*
* Find the last occurrence of a character in string, ignoring case.
*
* PARAMS
* lpszStr [I] String to search in
* lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
* ch [I] Character to search for.
*
* RETURNS
* Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
* or NULL if not found.
* Failure: NULL, if any arguments are invalid.
*/
LPSTR WINAPI StrRChrIA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
{
TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
return SHLWAPI_StrRChrHelperA(lpszStr, lpszEnd, ch, ChrCmpIA);
}
/**************************************************************************
* StrRChrIW [SHLWAPI.@]
*
* See StrRChrIA.
*/
LPWSTR WINAPI StrRChrIW(LPCWSTR str, LPCWSTR end, WORD ch)
{
WCHAR *ret = NULL;
if (!str) return NULL;
if (!end) end = str + strlenW(str);
while (str < end)
{
if (!ChrCmpIW(*str, ch)) ret = (WCHAR *)str;
str++;
}
return ret;
}
/*************************************************************************
* StrCatBuffA [SHLWAPI.@]
*
* Concatenate two strings together.
*
* PARAMS
* lpszStr [O] String to concatenate to
* lpszCat [I] String to add to lpszCat
* cchMax [I] Maximum number of characters for the whole string
*
* RETURNS
* lpszStr.
*
* NOTES
* cchMax determines the number of characters in the final length of the
* string, not the number appended to lpszStr from lpszCat.
*/
LPSTR WINAPI StrCatBuffA(LPSTR lpszStr, LPCSTR lpszCat, INT cchMax)
{
INT iLen;
TRACE("(%p,%s,%d)\n", lpszStr, debugstr_a(lpszCat), cchMax);
if (!lpszStr)
{
WARN("Invalid lpszStr would crash under Win32!\n");
return NULL;
}
iLen = strlen(lpszStr);
cchMax -= iLen;
if (cchMax > 0)
StrCpyNA(lpszStr + iLen, lpszCat, cchMax);
return lpszStr;
}
/*************************************************************************
* StrCatBuffW [SHLWAPI.@]
*
* See StrCatBuffA.
*/
LPWSTR WINAPI StrCatBuffW(LPWSTR lpszStr, LPCWSTR lpszCat, INT cchMax)
{
INT iLen;
TRACE("(%p,%s,%d)\n", lpszStr, debugstr_w(lpszCat), cchMax);
if (!lpszStr)
{
WARN("Invalid lpszStr would crash under Win32!\n");
return NULL;
}
iLen = strlenW(lpszStr);
cchMax -= iLen;
if (cchMax > 0)
StrCpyNW(lpszStr + iLen, lpszCat, cchMax);
return lpszStr;
}
/*************************************************************************
* StrRetToBufA [SHLWAPI.@]
*
* Convert a STRRET to a normal string.
*
* PARAMS
* lpStrRet [O] STRRET to convert
* pIdl [I] ITEMIDLIST for lpStrRet->uType == STRRET_OFFSET
* lpszDest [O] Destination for normal string
* dwLen [I] Length of lpszDest
*
* RETURNS
* Success: S_OK. lpszDest contains up to dwLen characters of the string.
* If lpStrRet is of type STRRET_WSTR, its memory is freed with
* CoTaskMemFree() and its type set to STRRET_CSTRA.
* Failure: E_FAIL, if any parameters are invalid.
*/
HRESULT WINAPI StrRetToBufA (LPSTRRET src, const ITEMIDLIST *pidl, LPSTR dest, UINT len)
{
/* NOTE:
* This routine is identical to that in dlls/shell32/shellstring.c.
* It was duplicated because not every version of Shlwapi.dll exports
* StrRetToBufA. If you change one routine, change them both.
*/
TRACE("dest=%p len=0x%x strret=%p pidl=%p stub\n",dest,len,src,pidl);
if (!src)
{
WARN("Invalid lpStrRet would crash under Win32!\n");
if (dest)
*dest = '\0';
return E_FAIL;
}
if (!dest || !len)
return E_FAIL;
*dest = '\0';
switch (src->uType)
{
case STRRET_WSTR:
WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, dest, len, NULL, NULL);
CoTaskMemFree(src->u.pOleStr);
break;
case STRRET_CSTR:
lstrcpynA((LPSTR)dest, src->u.cStr, len);
break;
case STRRET_OFFSET:
lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
break;
default:
FIXME("unknown type!\n");
return FALSE;
}
return S_OK;
}
/*************************************************************************
* StrRetToBufW [SHLWAPI.@]
*
* See StrRetToBufA.
*/
HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
{
TRACE("dest=%p len=0x%x strret=%p pidl=%p stub\n",dest,len,src,pidl);
if (!src)
{
WARN("Invalid lpStrRet would crash under Win32!\n");
if (dest)
*dest = '\0';
return E_FAIL;
}
if (!dest || !len)
return E_FAIL;
*dest = '\0';
switch (src->uType)
{
case STRRET_WSTR:
lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
CoTaskMemFree(src->u.pOleStr);
break;
case STRRET_CSTR:
if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len)
dest[len-1] = 0;
break;
case STRRET_OFFSET:
if (pidl)
{
if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1,
dest, len ) && len)
dest[len-1] = 0;
}
break;
default:
FIXME("unknown type!\n");
return FALSE;
}
return S_OK;
}
/*************************************************************************
* StrRetToStrA [SHLWAPI.@]
*
* Converts a STRRET to a normal string.
*
* PARAMS
* lpStrRet [O] STRRET to convert
* pidl [I] ITEMIDLIST for lpStrRet->uType == STRRET_OFFSET
* ppszName [O] Destination for converted string
*
* RETURNS
* Success: S_OK. ppszName contains the new string, allocated with CoTaskMemAlloc().
* Failure: E_FAIL, if any parameters are invalid.
*/
HRESULT WINAPI StrRetToStrA(LPSTRRET lpStrRet, const ITEMIDLIST *pidl, LPSTR *ppszName)
{
HRESULT hRet = E_FAIL;
switch (lpStrRet->uType)
{
case STRRET_WSTR:
hRet = _SHStrDupAW(lpStrRet->u.pOleStr, ppszName);
CoTaskMemFree(lpStrRet->u.pOleStr);
break;
case STRRET_CSTR:
hRet = _SHStrDupAA(lpStrRet->u.cStr, ppszName);
break;
case STRRET_OFFSET:
hRet = _SHStrDupAA(((LPCSTR)&pidl->mkid) + lpStrRet->u.uOffset, ppszName);
break;
default:
*ppszName = NULL;
}
return hRet;
}
/*************************************************************************
* StrRetToStrW [SHLWAPI.@]
*
* See StrRetToStrA.
*/
HRESULT WINAPI StrRetToStrW(LPSTRRET lpStrRet, const ITEMIDLIST *pidl, LPWSTR *ppszName)
{
HRESULT hRet = E_FAIL;
switch (lpStrRet->uType)
{
case STRRET_WSTR:
hRet = SHStrDupW(lpStrRet->u.pOleStr, ppszName);
CoTaskMemFree(lpStrRet->u.pOleStr);
break;
case STRRET_CSTR:
hRet = SHStrDupA(lpStrRet->u.cStr, ppszName);
break;
case STRRET_OFFSET:
hRet = SHStrDupA(((LPCSTR)&pidl->mkid) + lpStrRet->u.uOffset, ppszName);
break;
default:
*ppszName = NULL;
}
return hRet;
}
/* Create an ASCII string copy using SysAllocString() */
static HRESULT _SHStrDupAToBSTR(LPCSTR src, BSTR *pBstrOut)
{
*pBstrOut = NULL;
if (src)
{
INT len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
WCHAR* szTemp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (szTemp)
{
MultiByteToWideChar(CP_ACP, 0, src, -1, szTemp, len);
*pBstrOut = SysAllocString(szTemp);
HeapFree(GetProcessHeap(), 0, szTemp);
if (*pBstrOut)
return S_OK;
}
}
return E_OUTOFMEMORY;
}
/*************************************************************************
* StrRetToBSTR [SHLWAPI.@]
*
* Converts a STRRET to a BSTR.
*
* PARAMS
* lpStrRet [O] STRRET to convert
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -