📄 wxutil.cpp
字号:
LPWSTR lpString1,
LPCWSTR lpString2,
int iMaxLength
)
{
ASSERT(iMaxLength);
LPWSTR lpReturn = lpString1;
if (iMaxLength) {
while (--iMaxLength && (*lpString1++ = *lpString2++));
// If we ran out of room (which will be the case if
// iMaxLength is now 0) we still need to terminate the
// string.
if (!iMaxLength) *lpString1 = L'\0';
}
return lpReturn;
}
int
WINAPI
lstrcmpWInternal(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
do {
WCHAR c1 = *lpString1;
WCHAR c2 = *lpString2;
if (c1 != c2)
return (int) c1 - (int) c2;
} while (*lpString1++ && *lpString2++);
return 0;
}
int
WINAPI
lstrcmpiWInternal(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
do {
WCHAR c1 = *lpString1;
WCHAR c2 = *lpString2;
if (c1 >= L'A' && c1 <= L'Z')
c1 -= (WCHAR) (L'A' - L'a');
if (c2 >= L'A' && c2 <= L'Z')
c2 -= (WCHAR) (L'A' - L'a');
if (c1 != c2)
return (int) c1 - (int) c2;
} while (*lpString1++ && *lpString2++);
return 0;
}
int
WINAPI
lstrlenWInternal(
LPCWSTR lpString
)
{
int i = -1;
while (*(lpString+(++i)))
;
return i;
}
int WINAPIV wsprintfWInternal(LPWSTR wszOut, LPCWSTR pszFmt, ...)
{
char fmt[256]; // !!!
char ach[256]; // !!!
int i;
va_list va;
va_start(va, pszFmt);
WideCharToMultiByte(GetACP(), 0, pszFmt, -1, fmt, 256, NULL, NULL);
i = wvsprintfA(ach, fmt, va);
va_end(va);
MultiByteToWideChar(CP_ACP, 0, ach, -1, wszOut, i+1);
return i;
}
#else
// need to provide the implementations in unicode for non-unicode
// builds linking with the unicode strmbase.lib
LPWSTR WINAPI lstrcpyWInternal(
LPWSTR lpString1,
LPCWSTR lpString2
)
{
return lstrcpyW(lpString1, lpString2);
}
LPWSTR WINAPI lstrcpynWInternal(
LPWSTR lpString1,
LPCWSTR lpString2,
int iMaxLength
)
{
return lstrcpynW(lpString1, lpString2, iMaxLength);
}
int WINAPI lstrcmpWInternal(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
return lstrcmpW(lpString1, lpString2);
}
int WINAPI lstrcmpiWInternal(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
return lstrcmpiW(lpString1, lpString2);
}
int WINAPI lstrlenWInternal(
LPCWSTR lpString
)
{
return lstrlenW(lpString);
}
int WINAPIV wsprintfWInternal(
LPWSTR wszOut, LPCWSTR pszFmt, ...)
{
va_list va;
va_start(va, pszFmt);
int i = wvsprintfW(wszOut, pszFmt, va);
va_end(va);
return i;
}
#endif
// Helper function - convert int to WSTR
void WINAPI IntToWstr(int i, LPWSTR wstr)
{
#ifdef UNICODE
wsprintf(wstr, L"%d", i);
#else
TCHAR temp[32];
wsprintf(temp, "%d", i);
MultiByteToWideChar(CP_ACP, 0, temp, -1, wstr, 32);
#endif
} // IntToWstr
#if 0
void * memchrInternal(const void *pv, int c, size_t sz)
{
BYTE *pb = (BYTE *) pv;
while (sz--) {
if (*pb == c)
return (void *) pb;
pb++;
}
return NULL;
}
#endif
#define MEMORY_ALIGNMENT 4
#define MEMORY_ALIGNMENT_LOG2 2
#define MEMORY_ALIGNMENT_MASK MEMORY_ALIGNMENT - 1
void * __stdcall memmoveInternal(void * dst, const void * src, size_t count)
{
void * ret = dst;
#ifdef _X86_
if (dst <= src || (char *)dst >= ((char *)src + count)) {
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
_asm {
mov esi,src
mov edi,dst
mov ecx,count
cld
mov edx,ecx
and edx,MEMORY_ALIGNMENT_MASK
shr ecx,MEMORY_ALIGNMENT_LOG2
rep movsd
or ecx,edx
jz memmove_done
rep movsb
memmove_done:
}
}
else {
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
_asm {
mov esi,src
mov edi,dst
mov ecx,count
std
add esi,ecx
add edi,ecx
dec esi
dec edi
rep movsb
cld
}
}
#else
MoveMemory(dst, src, count);
#endif
return ret;
}
/* Arithmetic functions to help with time format conversions
*/
#ifdef _M_ALPHA
// work around bug in version 12.00.8385 of the alpha compiler where
// UInt32x32To64 sign-extends its arguments (?)
#undef UInt32x32To64
#define UInt32x32To64(a, b) (((ULONGLONG)((ULONG)(a)) & 0xffffffff) * ((ULONGLONG)((ULONG)(b)) & 0xffffffff))
#endif
/* Compute (a * b + d) / c */
LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d)
{
/* Compute the absolute values to avoid signed arithmetic problems */
ULARGE_INTEGER ua, ub;
DWORDLONG uc;
ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b);
uc = (DWORDLONG)(c >= 0 ? c : -c);
BOOL bSign = (a < 0) ^ (b < 0);
/* Do long multiplication */
ULARGE_INTEGER p[2];
p[0].QuadPart = UInt32x32To64(ua.LowPart, ub.LowPart);
/* This next computation cannot overflow into p[1].HighPart because
the max number we can compute here is:
(2 ** 32 - 1) * (2 ** 32 - 1) + // ua.LowPart * ub.LowPart
(2 ** 32) * (2 ** 31) * (2 ** 32 - 1) * 2 // x.LowPart * y.HighPart * 2
== 2 ** 96 - 2 ** 64 + (2 ** 64 - 2 ** 33 + 1)
== 2 ** 96 - 2 ** 33 + 1
< 2 ** 96
*/
ULARGE_INTEGER x;
x.QuadPart = UInt32x32To64(ua.LowPart, ub.HighPart) +
UInt32x32To64(ua.HighPart, ub.LowPart) +
p[0].HighPart;
p[0].HighPart = x.LowPart;
p[1].QuadPart = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart;
if (d != 0) {
ULARGE_INTEGER ud[2];
if (bSign) {
ud[0].QuadPart = (DWORDLONG)(-d);
if (d > 0) {
/* -d < 0 */
ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
} else {
ud[1].QuadPart = (DWORDLONG)0;
}
} else {
ud[0].QuadPart = (DWORDLONG)d;
if (d < 0) {
ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
} else {
ud[1].QuadPart = (DWORDLONG)0;
}
}
/* Now do extended addition */
ULARGE_INTEGER uliTotal;
/* Add ls DWORDs */
uliTotal.QuadPart = (DWORDLONG)ud[0].LowPart + p[0].LowPart;
p[0].LowPart = uliTotal.LowPart;
/* Propagate carry */
uliTotal.LowPart = uliTotal.HighPart;
uliTotal.HighPart = 0;
/* Add 2nd most ls DWORDs */
uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart;
p[0].HighPart = uliTotal.LowPart;
/* Propagate carry */
uliTotal.LowPart = uliTotal.HighPart;
uliTotal.HighPart = 0;
/* Add MS DWORDLONGs - no carry expected */
p[1].QuadPart += ud[1].QuadPart + uliTotal.QuadPart;
/* Now see if we got a sign change from the addition */
if ((LONG)p[1].HighPart < 0) {
bSign = !bSign;
/* Negate the current value (ugh!) */
p[0].QuadPart = ~p[0].QuadPart;
p[1].QuadPart = ~p[1].QuadPart;
p[0].QuadPart += 1;
p[1].QuadPart += (p[0].QuadPart == 0);
}
}
/* Now for the division */
if (c < 0) {
bSign = !bSign;
}
/* This will catch c == 0 and overflow */
if (uc <= p[1].QuadPart) {
return bSign ? (LONGLONG)0x8000000000000000 :
(LONGLONG)0x7FFFFFFFFFFFFFFF;
}
DWORDLONG ullResult;
/* Do the division */
/* If the dividend is a DWORD_LONG use the compiler */
if (p[1].QuadPart == 0) {
ullResult = p[0].QuadPart / uc;
return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult;
}
/* If the divisor is a DWORD then its simpler */
ULARGE_INTEGER ulic;
ulic.QuadPart = uc;
if (ulic.HighPart == 0) {
ULARGE_INTEGER uliDividend;
ULARGE_INTEGER uliResult;
DWORD dwDivisor = (DWORD)uc;
// ASSERT(p[1].HighPart == 0 && p[1].LowPart < dwDivisor);
uliDividend.HighPart = p[1].LowPart;
uliDividend.LowPart = p[0].HighPart;
#ifndef USE_LARGEINT
uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor);
p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor);
uliResult.LowPart = 0;
uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart;
#else
/* NOTE - this routine will take exceptions if
the result does not fit in a DWORD
*/
if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
uliResult.HighPart = EnlargedUnsignedDivide(
uliDividend,
dwDivisor,
&p[0].HighPart);
} else {
uliResult.HighPart = 0;
}
uliResult.LowPart = EnlargedUnsignedDivide(
p[0],
dwDivisor,
NULL);
#endif
return bSign ? -(LONGLONG)uliResult.QuadPart :
(LONGLONG)uliResult.QuadPart;
}
ullResult = 0;
/* OK - do long division */
for (int i = 0; i < 64; i++) {
ullResult <<= 1;
/* Shift 128 bit p left 1 */
p[1].QuadPart <<= 1;
if ((p[0].HighPart & 0x80000000) != 0) {
p[1].LowPart++;
}
p[0].QuadPart <<= 1;
/* Compare */
if (uc <= p[1].QuadPart) {
p[1].QuadPart -= uc;
ullResult += 1;
}
}
return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult;
}
LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG d)
{
ULARGE_INTEGER ua;
DWORD ub;
DWORD uc;
/* Compute the absolute values to avoid signed arithmetic problems */
ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
ub = (DWORD)(b >= 0 ? b : -b);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -