Mikołaj Zalewski : shlwapi: Make StrFormatByteSize format numbers using locale settings.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Aug 23 05:55:36 CDT 2006
Module: wine
Branch: master
Commit: c4c00040ba40580035bc547ee561b14396cada25
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c4c00040ba40580035bc547ee561b14396cada25
Author: Mikołaj Zalewski <mikolaj at zalewski.pl>
Date: Tue Aug 22 16:52:52 2006 +0200
shlwapi: Make StrFormatByteSize format numbers using locale settings.
---
dlls/shlwapi/string.c | 127 +++++++++++++++++++++++++++++--------------------
1 files changed, 76 insertions(+), 51 deletions(-)
diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c
index 34ab520..8551c91 100644
--- a/dlls/shlwapi/string.c
+++ b/dlls/shlwapi/string.c
@@ -66,6 +66,38 @@ static HRESULT WINAPI _SHStrDupAA(LPCSTR
static HRESULT WINAPI _SHStrDupAW(LPCWSTR,LPSTR*);
+static void FillNumberFmt(NUMBERFMTW *fmt, WCHAR decimal_buffer[8], WCHAR thousand_buffer[8])
+{
+ WCHAR grouping[64];
+ WCHAR *c;
+
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_ILZERO|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt->LeadingZero, sizeof(fmt->LeadingZero)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt->LeadingZero, sizeof(fmt->NegativeOrder)/sizeof(WCHAR));
+ fmt->NumDigits = 0;
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal_buffer, sizeof(decimal_buffer)/sizeof(WCHAR));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousand_buffer, sizeof(thousand_buffer)/sizeof(WCHAR));
+ fmt->lpThousandSep = thousand_buffer;
+ fmt->lpDecimalSep = decimal_buffer;
+
+ /*
+ * Converting grouping string to number as described on
+ * http://blogs.msdn.com/oldnewthing/archive/2006/04/18/578251.aspx
+ */
+ fmt->Grouping = 0;
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, grouping, sizeof(grouping)/sizeof(WCHAR));
+ for (c = grouping; *c; c++)
+ if (*c >= '0' && *c < '9')
+ {
+ fmt->Grouping *= 10;
+ fmt->Grouping += *c - '0';
+ }
+
+ if (fmt->Grouping % 10 == 0)
+ fmt->Grouping /= 10;
+ else
+ fmt->Grouping *= 10;
+}
+
/*************************************************************************
* FormatInt [internal]
*
@@ -78,36 +110,11 @@ static int FormatInt(LONGLONG qdwValue,
{
NUMBERFMTW fmt;
WCHAR decimal[8], thousand[8];
- WCHAR grouping[64];
WCHAR buf[24];
WCHAR *c;
BOOL neg = (qdwValue < 0);
-
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_ILZERO|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt.LeadingZero, sizeof(fmt.LeadingZero)/sizeof(WCHAR));
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt.LeadingZero, sizeof(fmt.NegativeOrder)/sizeof(WCHAR));
- fmt.NumDigits = 0;
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, sizeof(decimal)/sizeof(WCHAR));
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousand, sizeof(thousand)/sizeof(WCHAR));
- fmt.lpThousandSep = thousand;
- fmt.lpDecimalSep = decimal;
-
- /*
- * Converting grouping string to number as described on
- * http://blogs.msdn.com/oldnewthing/archive/2006/04/18/578251.aspx
- */
- fmt.Grouping = 0;
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, grouping, sizeof(grouping)/sizeof(WCHAR));
- for (c = grouping; *c; c++)
- if (*c >= '0' && *c < '9')
- {
- fmt.Grouping *= 10;
- fmt.Grouping += *c - '0';
- }
- if (fmt.Grouping % 10 == 0)
- fmt.Grouping /= 10;
- else
- fmt.Grouping *= 10;
+ FillNumberFmt(&fmt, decimal, thousand);
c = &buf[24];
*(--c) = 0;
@@ -123,6 +130,29 @@ static int FormatInt(LONGLONG qdwValue,
}
/*************************************************************************
+ * FormatDouble [internal]
+ *
+ * Format an integer according to the current locale. Prints the specified number of digits
+ * after the decimal point
+ *
+ * RETURNS
+ * The number of bytes written on success or 0 on failure
+ */
+static int FormatDouble(double value, int decimals, LPWSTR pszBuf, int cchBuf)
+{
+ static const WCHAR flfmt[] = {'%','f',0};
+ WCHAR buf[64];
+ NUMBERFMTW fmt;
+ WCHAR decimal[8], thousand[8];
+
+ snprintfW(buf, 64, flfmt, value);
+
+ FillNumberFmt(&fmt, decimal, thousand);
+ fmt.NumDigits = decimals;
+ return GetNumberFormatW(LOCALE_USER_DEFAULT, 0, buf, &fmt, pszBuf, cchBuf);
+}
+
+/*************************************************************************
* SHLWAPI_ChrCmpHelperA
*
* Internal helper for SHLWAPI_ChrCmpA/ChrCMPIA.
@@ -2251,7 +2281,7 @@ typedef struct tagSHLWAPI_BYTEFORMATS
LONGLONG dLimit;
double dDivisor;
double dNormaliser;
- LPCWSTR lpwszFormat;
+ int nDecimals;
WCHAR wPrefix;
} SHLWAPI_BYTEFORMATS;
@@ -2273,10 +2303,6 @@ typedef struct tagSHLWAPI_BYTEFORMATS
*/
LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
{
- static const WCHAR wsz3_0[] = {'%','3','.','0','f',0};
- static const WCHAR wsz3_1[] = {'%','3','.','1','f',0};
- static const WCHAR wsz3_2[] = {'%','3','.','2','f',0};
-
#define KB ((ULONGLONG)1024)
#define MB (KB*KB)
#define GB (KB*KB*KB)
@@ -2285,24 +2311,23 @@ #define PB (KB*KB*KB*KB*KB)
static const SHLWAPI_BYTEFORMATS bfFormats[] =
{
- { 10*KB, 10.24, 100.0, wsz3_2, 'K' }, /* 10 KB */
- { 100*KB, 102.4, 10.0, wsz3_1, 'K' }, /* 100 KB */
- { 1000*KB, 1024.0, 1.0, wsz3_0, 'K' }, /* 1000 KB */
- { 10*MB, 10485.76, 100.0, wsz3_2, 'M' }, /* 10 MB */
- { 100*MB, 104857.6, 10.0, wsz3_1, 'M' }, /* 100 MB */
- { 1000*MB, 1048576.0, 1.0, wsz3_0, 'M' }, /* 1000 MB */
- { 10*GB, 10737418.24, 100.0, wsz3_2, 'G' }, /* 10 GB */
- { 100*GB, 107374182.4, 10.0, wsz3_1, 'G' }, /* 100 GB */
- { 1000*GB, 1073741824.0, 1.0, wsz3_0, 'G' }, /* 1000 GB */
- { 10*TB, 10485.76, 100.0, wsz3_2, 'T' }, /* 10 TB */
- { 100*TB, 104857.6, 10.0, wsz3_1, 'T' }, /* 100 TB */
- { 1000*TB, 1048576.0, 1.0, wsz3_0, 'T' }, /* 1000 TB */
- { 10*PB, 10737418.24, 100.00, wsz3_2, 'P' }, /* 10 PB */
- { 100*PB, 107374182.4, 10.00, wsz3_1, 'P' }, /* 100 PB */
- { 1000*PB, 1073741824.0, 1.00, wsz3_0, 'P' }, /* 1000 PB */
- { 0, 10995116277.76, 100.00, wsz3_2, 'E' } /* EB's, catch all */
+ { 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 wszBuff[32];
WCHAR wszAdd[] = {' ','?','B',0};
double dBytes;
UINT i = 0;
@@ -2342,10 +2367,10 @@ #define PB (KB*KB*KB*KB*KB)
dBytes = floor(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser;
- sprintfW(wszBuff, bfFormats[i].lpwszFormat, dBytes);
+ if (!FormatDouble(dBytes, bfFormats[i].nDecimals, lpszDest, cchMax))
+ return NULL;
wszAdd[1] = bfFormats[i].wPrefix;
- strcatW(wszBuff, wszAdd);
- lstrcpynW(lpszDest, wszBuff, cchMax);
+ StrCatBuffW(lpszDest, wszAdd, cchMax);
return lpszDest;
}
More information about the wine-cvs
mailing list