00001
00002
00003
00004
00005
00198 #include "Humble.h"
00199 #include "HWidget.h"
00200
00201
00202
00203 HMap<HANDLE, HWidget *> HWidget::s_map;
00204
00205
00206
00207 namespace Humble
00208 {
00222 int32
00223 safe_memcmp(PtrConst p1, PtrConst p2, uint32 uBytes)
00224 {
00225 if (uBytes == 0) return 0;
00226 if (NULL_PTR(p1)) return NULL_PTR(p2) ? 0 : -1;
00227 if (NULL_PTR(p2)) return NULL_PTR(p1) ? 0 : +1;
00228
00229 return memcmp(p1, p2, uBytes);
00230 }
00245 Ptr
00246 safe_memcpy(Ptr pDst, PtrConst pSrc, uint32 uBytes)
00247 {
00248 if (GOOD_PTR(pDst) && GOOD_PTR(pSrc) && uBytes > 0)
00249 {
00250 PtrData pEnd = MAKE_PTR(PtrData, pSrc, uBytes);
00251
00252 pDst = (pDst < pSrc || pDst >= pEnd) ?
00253 memcpy(pDst, pSrc, uBytes) :
00254 memmove(pDst, pSrc, uBytes);
00255 }
00256
00257 return pDst;
00258 }
00272 Ptr
00273 safe_memmove(Ptr pDst, PtrConst pSrc, uint32 uBytes)
00274 {
00275 if (GOOD_PTR(pDst) && GOOD_PTR(pSrc) && uBytes > 0)
00276 (void) memmove(pDst, pSrc, uBytes);
00277
00278 return pDst;
00279 }
00293 Ptr
00294 safe_memset(Ptr pDst, uint8 xVal, uint32 uBytes)
00295 {
00296 if (GOOD_PTR(pDst) && uBytes > 0)
00297 (void) memset(pDst, xVal, uBytes);
00298
00299 return pDst;
00300 }
00314 StringPtr
00315 safe_strchr(StringPtr pstr, Text ch)
00316 { return STR_VALID(pstr) ? strchr(pstr, ch) : NULL; }
00329 int32
00330 safe_strcmp(StringPtr pstr1, StringPtr pstr2)
00331 {
00332 if (NULL_PTR(pstr1)) return NULL_PTR(pstr2) ? 0 : -1;
00333 if (NULL_PTR(pstr2)) return NULL_PTR(pstr1) ? 0 : +1;
00334
00335 return strcmp(pstr1, pstr2);
00336 }
00349 int32
00350 safe_strcmpi(StringPtr pstr1, StringPtr pstr2)
00351 {
00352 if (NULL_PTR(pstr1)) return NULL_PTR(pstr2) ? 0 : -1;
00353 if (NULL_PTR(pstr2)) return NULL_PTR(pstr1) ? 0 : +1;
00354
00355 return stricmp(pstr1, pstr2);
00356 }
00369 int32
00370 safe_strcmpn(StringPtr pstr1, StringPtr pstr2, uint32 uMaxLen)
00371 {
00372 if (uMaxLen == 0) return 0;
00373 if (NULL_PTR(pstr1)) return NULL_PTR(pstr2) ? 0 : -1;
00374 if (NULL_PTR(pstr2)) return NULL_PTR(pstr1) ? 0 : +1;
00375
00376 uint32 udx;
00377
00378 for (udx = 0; udx < uMaxLen; ++udx)
00379 {
00380 if (pstr1[udx] == '\0' ||
00381 pstr2[udx] == '\0' ||
00382 pstr1[udx] != pstr2[udx])
00383 {
00384 break;
00385 }
00386 }
00387
00388 return int32(pstr1[udx] - pstr2[udx]);
00389 }
00403 bool
00404 safe_strcmpw(StringPtr pstr, StringPtr pstrMask)
00405 {
00406 Text ch;
00407
00408 while (STR_VALID(pstrMask))
00409 {
00410 ch = *pstrMask++;
00411 switch (ch)
00412 {
00413 case '*':
00414 if (STR_EMPTY(pstrMask))
00415 return true;
00416
00417 do
00418 {
00419 if (safe_strcmpw(pstr, pstrMask))
00420 return true;
00421 }
00422 while (*pstr++ != '\0');
00423 return false;
00424
00425 case '?':
00426 if (*pstr++ == '\0')
00427 return false;
00428 break;
00429
00430 case '[':
00431 {
00432 Text cSaved;
00433 bool bOK = false,
00434 bNegate = false;
00435
00436 if ((cSaved = *pstr++) == '\0')
00437 return 0;
00438
00439 if (*pstrMask == '!')
00440 {
00441 bNegate = true;
00442 ++pstrMask;
00443 }
00444
00445 while ((ch = *pstrMask++) != ']')
00446 if (*pstrMask == '~')
00447 {
00448 if (ch <= cSaved && cSaved <= pstrMask[1])
00449 bOK = true;
00450 pstrMask += 2;
00451 }
00452 else if (ch == cSaved)
00453 bOK = true;
00454
00455 if (bOK == bNegate)
00456 return false;
00457 }
00458 break;
00459
00460 default:
00461 if (*pstr++ != ch)
00462 return false;
00463 break;
00464 }
00465 }
00466
00467 return STR_EMPTY(pstr);
00468 }
00482 TextPtr
00483 safe_strncat(TextPtr pszSrc, StringPtr pstrDst, int32 nMaxLen)
00484 {
00485 if (GOOD_PTR(pszSrc) && GOOD_PTR(pstrDst) && nMaxLen > 0)
00486 {
00487 TextPtr psz;
00488
00489 for (psz = pszSrc; *psz && nMaxLen > 0; ++psz)
00490 nMaxLen--;
00491
00492 for ( ; *pstrDst && nMaxLen > 0; --nMaxLen)
00493 *psz++ = *pstrDst++;
00494
00495 *psz = '\0';
00496 }
00497
00498 return pszSrc;
00499 }
00514 TextPtr
00515 safe_strncpy(TextPtr pszDst, StringPtr pstrSrc, int32 nMaxLen)
00516 {
00517 if (GOOD_PTR(pszDst) && GOOD_PTR(pstrSrc) && nMaxLen > 0)
00518 {
00519 TextPtr psz;
00520
00521 for (psz = pszDst; *pstrSrc && nMaxLen > 0; --nMaxLen)
00522 *psz++ = *pstrSrc++;
00523
00524 *psz = '\0';
00525 }
00526
00527 return pszDst;
00528 }
00537 int32
00538 safe_strcount(StringPtr pstr, Text ch)
00539 {
00540 int32 nCount;
00541
00542 for (nCount = 0; STR_VALID(pstr); ++pstr)
00543 if (*pstr == ch)
00544 nCount++;
00545
00546 return nCount;
00547 }
00562 int
00563 safe_strlen(StringPtr pstr, int32 nMaxLen)
00564 {
00565 int32 nLen;
00566
00567 for (nLen = 0; STR_VALID(pstr) && nLen < nMaxLen; ++nLen)
00568 pstr++;
00569
00570 return nLen;
00571 }
00584 TextPtr
00585 safe_strlwr(TextPtr psz)
00586 {
00587 for (TextPtr p = psz; STR_VALID(p); ++p)
00588 *p = tolower(*p);
00589
00590 return psz;
00591 }
00605 StringPtr
00606 safe_strrchr(StringPtr pstr, Text ch)
00607 {
00608 StringPtr pstrFound = NULL;
00609
00610 for ( ; STR_VALID(pstr); ++pstr)
00611 if (*pstr == ch)
00612 pstrFound = pstr;
00613
00614 return pstrFound;
00615 }
00628 TextPtr
00629 safe_strrev(TextPtr psz)
00630 {
00631
00632
00633
00634 if (STR_EMPTY(psz) || psz[1] == '\0')
00635 return psz;
00636
00637
00638
00639 TextPtr pszLast = psz;
00640
00641 while (pszLast[1] != '\0')
00642 pszLast++;
00643
00644
00645
00646
00647 for (TextPtr p = psz; p < pszLast; p++, pszLast--)
00648 std::swap(*p, *pszLast);
00649
00650 return psz;
00651 }
00665 StringPtr
00666 safe_strstr(StringPtr pstr, StringPtr pstrFind)
00667 {
00668 if (STR_VALID(pstr))
00669 {
00670 const int32 nLen = safe_strlen(pstrFind) * sizeof(Text);
00671
00672 while ((pstr = safe_strchr(pstr, *pstrFind)) != NULL)
00673 {
00674 if (safe_memcmp(pstr, pstrFind, nLen * sizeof(Text)) == 0)
00675 return pstr;
00676 pstr++;
00677 }
00678 }
00679
00680 return NULL;
00681 }
00689 int32
00690 safe_strtoi(StringPtr pstr)
00691 {
00692 Text ch;
00693 int32 nTotal = 0;
00694 bool bNegative = false;
00695
00696 if (STR_EMPTY(pstr)) return 0;
00697
00698 while (isspace(*pstr))
00699 ++pstr;
00700
00701 ch = *pstr++;
00702 if (ch == '+' || ch == '-')
00703 {
00704 bNegative = (ch == '-');
00705 ch = *pstr++;
00706 }
00707
00708 while (isdigit(ch))
00709 {
00710 nTotal = (10 * nTotal) + int32(ch - '0');
00711 ch = *pstr++;
00712 }
00713
00714 ASSERT( nTotal >= 0);
00715
00716 return (bNegative) ? -nTotal : nTotal;
00717 }
00730 TextPtr
00731 safe_strupr(TextPtr psz)
00732 {
00733 for (TextPtr p = psz; STR_VALID(p); ++p)
00734 *p = toupper(*p);
00735
00736 return psz;
00737 }
00753 int32
00754 safe_vsprintf(TextPtr pstr, int32 nMaxLen, StringPtr pstrFormat, va_list vaList)
00755 {
00756 int32 nLen = 0;
00757
00758 if (GOOD_PTR(pstr) && nMaxLen > 0 && STR_VALID(pstrFormat))
00759 {
00760 const int32 kMaxPrintLen = 4095;
00761 Text szTmp[kMaxPrintLen+1] = { '\0' };
00762
00763 nLen = vsprintf(szTmp, pstrFormat, vaList);
00764 if (nLen > kMaxPrintLen)
00765 throw std::overflow_error("vsprintf() buffer overflow.");
00766
00767
00768
00769
00770
00771 if (nLen < nMaxLen)
00772 nMaxLen = nLen + 1;
00773 safe_memcpy(pstr, szTmp, nMaxLen);
00774 }
00775
00776 return nLen;
00777 }
00792 int32
00793 safe_sprintf(TextPtr pstr, int32 nMaxLen, StringPtr pstrFormat, ...)
00794 {
00795 int32 nLen;
00796 va_list vaList;
00797
00798 va_start(vaList, pstrFormat);
00799 nLen = safe_vsprintf(pstr, nMaxLen, pstrFormat, vaList);
00800 va_end(vaList);
00801
00802 return nLen;
00803 }
00814 void
00815 PopUpAlert(StringPtr pstrTitle, StringPtr pstrBase, ...)
00816 {
00817 HString strText,
00818 strTitle(pstrTitle);
00819
00820 if (STR_VALID(pstrBase))
00821 {
00822 va_list vaList;
00823
00824 va_start(vaList, pstrBase);
00825 (void) strText.FormatV(pstrBase, vaList);
00826 va_end(vaList);
00827 }
00828
00829 (void) GI_messagebox( NULL,
00830 WGF_MB_OK | WGF_MB_ICON_STOP,
00831 const_cast<TextPtr>( strTitle.GetString() ),
00832 const_cast<TextPtr>( strText.GetString() ));
00833 }
00844 void
00845 PopUpInfo(StringPtr pstrTitle, StringPtr pstrBase, ...)
00846 {
00847 HString strText,
00848 strTitle(pstrTitle);
00849
00850 if (STR_VALID(pstrBase))
00851 {
00852 va_list vaList;
00853
00854 va_start(vaList, pstrBase);
00855 (void) strText.FormatV(pstrBase, vaList);
00856 va_end(vaList);
00857 }
00858
00859 (void) GI_messagebox( NULL,
00860 WGF_MB_OK | WGF_MB_ICON_INFO,
00861 const_cast<TextPtr>( strTitle.GetString() ),
00862 const_cast<TextPtr>( strText.GetString() ));
00863 }
00874 int32
00875 PopUpOKCancel(StringPtr pstrTitle, StringPtr pstrBase, ...)
00876 {
00877 int32 nRC;
00878 HString strText,
00879 strTitle(pstrTitle);
00880
00881 if (STR_VALID(pstrBase))
00882 {
00883 va_list vaList;
00884
00885 va_start(vaList, pstrBase);
00886 (void) strText.FormatV(pstrBase, vaList);
00887 va_end(vaList);
00888 }
00889
00890 nRC = GI_messagebox(NULL,
00891 WGF_MB_CANCEL | WGF_MB_ICON_ASK,
00892 const_cast<TextPtr>( strTitle.GetString() ),
00893 const_cast<TextPtr>( strText.GetString() ));
00894
00895 DEBUG_CHECK( nRC == ID_OK || nRC == ID_CANCEL );
00896
00897 return nRC;
00898 }
00909 int32
00910 PopUpYesNo(StringPtr pstrTitle, StringPtr pstrBase, ...)
00911 {
00912 int32 nRC;
00913 HString strText,
00914 strTitle(pstrTitle);
00915
00916 if (STR_VALID(pstrBase))
00917 {
00918 va_list vaList;
00919
00920 va_start(vaList, pstrBase);
00921 (void) strText.FormatV(pstrBase, vaList);
00922 va_end(vaList);
00923 }
00924
00925 nRC = GI_messagebox(NULL,
00926 WGF_MB_YESNO | WGF_MB_ICON_ASK,
00927 const_cast<TextPtr>( strTitle.GetString() ),
00928 const_cast<TextPtr>( strText.GetString() ));
00929
00930 DEBUG_CHECK( nRC == ID_YES || nRC == ID_NO );
00931
00932 return nRC;
00933 }
00934 };
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972