⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 string.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
 * StrIsIntlEqualA	[SHLWAPI.@]
 *
 * Compare two strings.
 *
 * PARAMS
 *  bCase    [I] Whether to compare case sensitively
 *  lpszStr  [I] First string to compare
 *  lpszComp [I] Second string to compare
 *  iLen     [I] Length to compare
 *
 * RETURNS
 *  TRUE  If the strings are equal.
 *  FALSE Otherwise.
 */
BOOL WINAPI StrIsIntlEqualA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp,
                            int iLen)
{
  DWORD dwFlags;

  TRACE("(%d,%s,%s,%d)\n", bCase,
        debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);

  /* FIXME: This flag is undocumented and unknown by our CompareString.
   *        We need a define for it.
   */
  dwFlags = 0x10000000;
  if (!bCase) dwFlags |= NORM_IGNORECASE;

  return (CompareStringA(GetThreadLocale(), dwFlags, lpszStr, iLen, lpszComp, iLen) == CSTR_EQUAL);
}

/*************************************************************************
 * StrIsIntlEqualW	[SHLWAPI.@]
 *
 * See StrIsIntlEqualA.
 */
BOOL WINAPI StrIsIntlEqualW(BOOL bCase, LPCWSTR lpszStr, LPCWSTR lpszComp,
                            int iLen)
{
  DWORD dwFlags;

  TRACE("(%d,%s,%s,%d)\n", bCase,
        debugstr_w(lpszStr),debugstr_w(lpszComp), iLen);

  /* FIXME: This flag is undocumented and unknown by our CompareString.
   *        We need a define for it.
   */
  dwFlags = 0x10000000;
  if (!bCase) dwFlags |= NORM_IGNORECASE;

  return (CompareStringW(GetThreadLocale(), dwFlags, lpszStr, iLen, lpszComp, iLen) == CSTR_EQUAL);
}

/*************************************************************************
 * @    [SHLWAPI.399]
 *
 * Copy a string to another string, up to a maximum number of characters.
 *
 * PARAMS
 *  lpszDest [O] Destination string
 *  lpszSrc  [I] Source string
 *  iLen     [I] Maximum number of chars to copy
 *
 * RETURNS
 *  Success: A pointer to the last character written to lpszDest.
 *  Failure: lpszDest, if any arguments are invalid.
 */
LPSTR WINAPI StrCpyNXA(LPSTR lpszDest, LPCSTR lpszSrc, int iLen)
{
  TRACE("(%p,%s,%i)\n", lpszDest, debugstr_a(lpszSrc), iLen);

  if (lpszDest && lpszSrc && iLen > 0)
  {
    while ((iLen-- > 1) && *lpszSrc)
      *lpszDest++ = *lpszSrc++;
    if (iLen >= 0)
     *lpszDest = '\0';
  }
  return lpszDest;
}

/*************************************************************************
 * @    [SHLWAPI.400]
 *
 * Unicode version of StrCpyNXA.
 */
LPWSTR WINAPI StrCpyNXW(LPWSTR lpszDest, LPCWSTR lpszSrc, int iLen)
{
  TRACE("(%p,%s,%i)\n", lpszDest, debugstr_w(lpszSrc), iLen);

  if (lpszDest && lpszSrc && iLen > 0)
  {
    while ((iLen-- > 1) && *lpszSrc)
      *lpszDest++ = *lpszSrc++;
    if (iLen >= 0)
     *lpszDest = '\0';
  }
  return lpszDest;
}

/*************************************************************************
 * StrCmpLogicalW	[SHLWAPI.@]
 *
 * Compare two strings, ignoring case and comparing digits as numbers.
 *
 * PARAMS
 *  lpszStr  [I] First string to compare
 *  lpszComp [I] Second string to compare
 *  iLen     [I] Length to compare
 *
 * RETURNS
 *  TRUE  If the strings are equal.
 *  FALSE Otherwise.
 */
INT WINAPI StrCmpLogicalW(LPCWSTR lpszStr, LPCWSTR lpszComp)
{
  INT iDiff;

  TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszComp));

  if (lpszStr && lpszComp)
  {
    while (*lpszStr)
    {
      if (!*lpszComp)
        return 1;
      else if (isdigitW(*lpszStr))
      {
        int iStr, iComp;

        if (!isdigitW(*lpszComp))
          return -1;

        /* Compare the numbers */
        StrToIntExW(lpszStr, 0, &iStr);
        StrToIntExW(lpszComp, 0, &iComp);

        if (iStr < iComp)
          return -1;
        else if (iStr > iComp)
          return 1;

        /* Skip */
        while (isdigitW(*lpszStr))
          lpszStr++;
        while (isdigitW(*lpszComp))
          lpszComp++;
      }
      else if (isdigitW(*lpszComp))
        return 1;
      else
      {
        iDiff = ChrCmpIW(*lpszStr,*lpszComp);
        if (iDiff > 0)
          return 1;
        else if (iDiff < 0)
          return -1;

        lpszStr++;
        lpszComp++;
      }
    }
    if (*lpszComp)
      return -1;
  }
  return 0;
}

/* Structure for formatting byte strings */
typedef struct tagSHLWAPI_BYTEFORMATS
{
  LONGLONG dLimit;
  double   dDivisor;
  double   dNormaliser;
  int      nDecimals;
  WCHAR     wPrefix;
} SHLWAPI_BYTEFORMATS;

/*************************************************************************
 * StrFormatByteSizeW	[SHLWAPI.@]
 *
 * Create a string containing an abbreviated byte count of up to 2^63-1.
 *
 * PARAMS
 *  llBytes  [I] Byte size to format
 *  lpszDest [I] Destination for formatted string
 *  cchMax   [I] Size of lpszDest
 *
 * RETURNS
 *  lpszDest.
 *
 * NOTES
 *  There is no StrFormatByteSize64W function, it is called StrFormatByteSizeW().
 */
LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
{
#define KB ((ULONGLONG)1024)
#define MB (KB*KB)
#define GB (KB*KB*KB)
#define TB (KB*KB*KB*KB)
#define PB (KB*KB*KB*KB*KB)

  static const SHLWAPI_BYTEFORMATS bfFormats[] =
  {
    { 10*KB, 10.24, 100.0, 2, 'K' }, /* 10 KB */
    { 100*KB, 102.4, 10.0, 1, 'K' }, /* 100 KB */
    { 1000*KB, 1024.0, 1.0, 0, 'K' }, /* 1000 KB */
    { 10*MB, 10485.76, 100.0, 2, 'M' }, /* 10 MB */
    { 100*MB, 104857.6, 10.0, 1, 'M' }, /* 100 MB */
    { 1000*MB, 1048576.0, 1.0, 0, 'M' }, /* 1000 MB */
    { 10*GB, 10737418.24, 100.0, 2, 'G' }, /* 10 GB */
    { 100*GB, 107374182.4, 10.0, 1, 'G' }, /* 100 GB */
    { 1000*GB, 1073741824.0, 1.0, 0, 'G' }, /* 1000 GB */
    { 10*TB, 10485.76, 100.0, 2, 'T' }, /* 10 TB */
    { 100*TB, 104857.6, 10.0, 1, 'T' }, /* 100 TB */
    { 1000*TB, 1048576.0, 1.0, 0, 'T' }, /* 1000 TB */
    { 10*PB, 10737418.24, 100.00, 2, 'P' }, /* 10 PB */
    { 100*PB, 107374182.4, 10.00, 1, 'P' }, /* 100 PB */
    { 1000*PB, 1073741824.0, 1.00, 0, 'P' }, /* 1000 PB */
    { 0, 10995116277.76, 100.00, 2, 'E' } /* EB's, catch all */
  };
  WCHAR wszAdd[] = {' ','?','B',0};
  double dBytes;
  UINT i = 0;

  TRACE("(0x%s,%p,%d)\n", wine_dbgstr_longlong(llBytes), lpszDest, cchMax);

  if (!lpszDest || !cchMax)
    return lpszDest;

  if (llBytes < 1024)  /* 1K */
  {
    WCHAR wszBytesFormat[64];
    LoadStringW(shlwapi_hInstance, IDS_BYTES_FORMAT, wszBytesFormat, 64);
    snprintfW(lpszDest, cchMax, wszBytesFormat, (long)llBytes);
    return lpszDest;
  }

  /* Note that if this loop completes without finding a match, i will be
   * pointing at the last entry, which is a catch all for > 1000 PB
   */
  while (i < sizeof(bfFormats) / sizeof(SHLWAPI_BYTEFORMATS) - 1)
  {
    if (llBytes < bfFormats[i].dLimit)
      break;
    i++;
  }
  /* Above 1 TB we encounter problems with FP accuracy. So for amounts above
   * this number we integer shift down by 1 MB first. The table above has
   * the divisors scaled down from the '< 10 TB' entry onwards, to account
   * for this. We also add a small fudge factor to get the correct result for
   * counts that lie exactly on a 1024 byte boundary.
   */
  if (i > 8)
    dBytes = (double)(llBytes >> 20) + 0.001; /* Scale down by I MB */
  else
    dBytes = (double)llBytes + 0.00001;

  dBytes = floor(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser;

  if (!FormatDouble(dBytes, bfFormats[i].nDecimals, lpszDest, cchMax))
    return NULL;
  wszAdd[1] = bfFormats[i].wPrefix;
  StrCatBuffW(lpszDest, wszAdd, cchMax);
  return lpszDest;
}

/*************************************************************************
 * StrFormatByteSize64A	[SHLWAPI.@]
 *
 * See StrFormatByteSizeW.
 */
LPSTR WINAPI StrFormatByteSize64A(LONGLONG llBytes, LPSTR lpszDest, UINT cchMax)
{
  WCHAR wszBuff[32];

  StrFormatByteSizeW(llBytes, wszBuff, sizeof(wszBuff)/sizeof(WCHAR));

  if (lpszDest)
    WideCharToMultiByte(CP_ACP, 0, wszBuff, -1, lpszDest, cchMax, 0, 0);
  return lpszDest;
}

/*************************************************************************
 * StrFormatByteSizeA	[SHLWAPI.@]
 *
 * Create a string containing an abbreviated byte count of up to 2^31-1.
 *
 * PARAMS
 *  dwBytes  [I] Byte size to format
 *  lpszDest [I] Destination for formatted string
 *  cchMax   [I] Size of lpszDest
 *
 * RETURNS
 *  lpszDest.
 *
 * NOTES
 *  The Ascii and Unicode versions of this function accept a different
 *  integer type for dwBytes. See StrFormatByteSize64A().
 */
LPSTR WINAPI StrFormatByteSizeA(DWORD dwBytes, LPSTR lpszDest, UINT cchMax)
{
  TRACE("(%d,%p,%d)\n", dwBytes, lpszDest, cchMax);

  return StrFormatByteSize64A(dwBytes, lpszDest, cchMax);
}

/*************************************************************************
 *      @	[SHLWAPI.162]
 *
 * Remove a hanging lead byte from the end of a string, if present.
 *
 * PARAMS
 *  lpStr [I] String to check for a hanging lead byte
 *  size  [I] Length of lpStr
 *
 * RETURNS
 *  Success: The new length of the string. Any hanging lead bytes are removed.
 *  Failure: 0, if any parameters are invalid.
 */
DWORD WINAPI SHTruncateString(LPSTR lpStr, DWORD size)
{
  if (lpStr && size)
  {
    LPSTR lastByte = lpStr + size - 1;

    while(lpStr < lastByte)
      lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;

    if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
    {
      *lpStr = '\0';
      size--;
    }
    return size;
  }
  return 0;
}

/*************************************************************************
 *      @	[SHLWAPI.203]
 *
 * Remove a single non-trailing ampersand ('&') from a string.
 *
 * PARAMS
 *  lpszStr [I/O] String to remove ampersand from.
 *
 * RETURNS
 *  The character after the first ampersand in lpszStr, or the first character
 *  in lpszStr if there is no ampersand in the string.
 */
char WINAPI SHStripMneumonicA(LPCSTR lpszStr)
{
  LPSTR lpszIter, lpszTmp;
  char ch;

  TRACE("(%s)\n", debugstr_a(lpszStr));

  ch = *lpszStr;

  if ((lpszIter = StrChrA(lpszStr, '&')))
  {
    lpszTmp = CharNextA(lpszIter);
    if (lpszTmp && *lpszTmp)
    {
      if (*lpszTmp != '&')
        ch =  *lpszTmp;

      while (lpszIter && *lpszIter)
      {
        lpszTmp = CharNextA(lpszIter);
        *lpszIter = *lpszTmp;
        lpszIter = lpszTmp;
      }
    }
  }

  return ch;
}

/*************************************************************************
 *      @	[SHLWAPI.225]
 *
 * Unicode version of SHStripMneumonicA.
 */
WCHAR WINAPI SHStripMneumonicW(LPCWSTR lpszStr)
{
  LPWSTR lpszIter, lpszTmp;
  WCHAR ch;

  TRACE("(%s)\n", debugstr_w(lpszStr));

  ch = *lpszStr;

  if ((lpszIter = StrChrW(lpszStr, '&')))
  {
    lpszTmp = lpszIter + 1;
    if (lpszTmp && *lpszTmp)
    {
      if (*lpszTmp != '&')
        ch =  *lpszTmp;

      while (lpszIter && *lpszIter)
      {
        lpszTmp = lpszIter + 1;
        *lpszIter = *lpszTmp;
        lpszIter = lpszTmp;
      }
    }
  }

  return ch;
}

/*************************************************************************
 *      @	[SHLWAPI.216]
 *
 * Convert an Ascii string to Unicode.
 *
 * PARAMS
 * dwCp     [I] Code page for the conversion
 * lpSrcStr [I] Source Ascii string to convert
 * lpDstStr [O] Destination for converted Unicode string
 * iLen     [I] Length of lpDstStr
 *
 * RETURNS
 *  The return value of the MultiByteToWideChar() function called on lpSrcStr.
 */
DWORD WINAPI SHAnsiToUnicodeCP(DWORD dwCp, LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
{
  DWORD dwRet;

  dwRet = MultiByteToWideChar(dwCp, 0, lpSrcStr, -1, lpDstStr, iLen);
  TRACE("%s->%s,ret=%d\n", debugstr_a(lpSrcStr), debugstr_w(lpDstStr), dwRet);
  return dwRet;
}

/*************************************************************************
 *      @	[SHLWAPI.215]
 *
 * Convert an Ascii string to Unicode.
 *
 * PARAMS
 * lpSrcStr [I] Source Ascii string to convert
 * lpDstStr [O] Destination for converted Unicode string
 * iLen     [I] Length of lpDstStr
 *
 * RETURNS
 *  The return value of the MultiByteToWideChar() function called on lpSrcStr.
 *
 * NOTES
 *  This function simply calls SHAnsiToUnicodeCP with code page CP_ACP.
 */
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
{
  return SHAnsiToUnicodeCP(CP_ACP, lpSrcStr, lpDstStr, iLen);
}

/*************************************************************************
 *      @	[SHLWAPI.218]
 *
 * Convert a Unicode string to Ascii.
 *
 * PARAMS
 *  CodePage [I] Code page to use for the conversion
 *  lpSrcStr [I] Source Unicode string to convert
 *  lpDstStr [O] Destination for converted Ascii string
 *  lpiLen   [I/O] Input length of lpDstStr/destination for length of lpDstStr
 *
 * RETURNS
 *  Success: The number of characters that result from the conversion.
 *  Failure: 0.
 */
INT WINAPI SHUnicodeToAnsiCP(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
                             LPINT lpiLen)
{
  static const WCHAR emptyW[] = { '\0' };
  int len , reqLen;
  LPSTR mem;

  if (!lpDstStr || !lpiLen)
    return 0;

  if (!lpSrcStr)
    lpSrcStr = emptyW;

  *lpDstStr = '\0';

  len = strlenW(lpSrcStr) + 1;

  switch (CodePage)
  {
  case CP_WINUNICODE:
    CodePage = CP_UTF8; /* Fall through... */
  case 0x0000C350: /* FIXME: CP_ #define */
  case CP_UTF7:
  case CP_UTF8:
    {
      DWORD dwMode = 0;
      INT nWideCharCount = len - 1;

      if (!Conver

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -