Humble Framework for SkyOS


Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

Humble.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 **  $Header: /SkyOS.root/HFramework/Humble.cpp 6     4/17/05 12:29p Lee Neuse $
00004 **
00005 ****************************************************************************/
00198 #include "Humble.h"
00199 #include "HWidget.h"
00200 /*  ----------------------------------------------------------------------
00201     Global Variables
00202     ----------------------------------------------------------------------  */
00203 HMap<HANDLE, HWidget *> HWidget::s_map;     
00204 /*  ----------------------------------------------------------------------
00205     Global Functions
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' ||       // hit the end of string 1
00381                 pstr2[udx] == '\0' ||       // hit the end of string 2
00382                 pstr1[udx] != pstr2[udx])   // hit the first mismatch
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 '*':   // M_ALL
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 '?':   // M_ONE
00426                     if (*pstr++ == '\0')
00427                         return false;
00428                     break;
00429 
00430                 case '[':   // M_SET
00431                     {
00432                     Text    cSaved;
00433                     bool    bOK = false,
00434                             bNegate = false;
00435                             
00436                     if ((cSaved = *pstr++) == '\0')
00437                         return 0;
00438                     
00439                     if (*pstrMask == '!')   // M_NOT
00440                         {
00441                         bNegate = true;
00442                         ++pstrMask;
00443                         }
00444                     
00445                     while ((ch = *pstrMask++) != ']')   // M_END
00446                         if (*pstrMask == '~')   // M_RNG
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         // optimize NULL, zero-length, and single-char case
00633         //
00634         if (STR_EMPTY(psz) || psz[1] == '\0')
00635             return psz;
00636         //
00637         //  Find the last character in the string immediated before the '\0'
00638         //
00639         TextPtr     pszLast = psz;
00640         
00641         while (pszLast[1] != '\0')
00642             pszLast++;
00643         //
00644         //  Now walk the string up to the last character, swapping each pair
00645         //  along the way.
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;    // true if negative, positive otherwise
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++;   // advance to next character
00706             }
00707 
00708         while (isdigit(ch))
00709             {
00710             nTotal = (10 * nTotal) + int32(ch - '0');
00711             ch = *pstr++;
00712             }
00713 
00714         ASSERT( nTotal >= 0);   // goes negative if rolled over beyond INT32_MAX        
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             //  Copy from the temporary buffer into the caller's buffer. Use
00768             //  memcpy() because the string length is already known and we
00769             //  want to copy the '\0' terminator as well.
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     };  // namespace Humble
00935 /****************************************************************************
00936 **
00937 **  $History: Humble.cpp $
00938  * 
00939  * *****************  Version 6  *****************
00940  * User: Lee Neuse    Date: 4/17/05    Time: 12:29p
00941  * Updated in $/SkyOS.root/HFramework
00942  * Development snapshot 050417
00943  * 
00944  * *****************  Version 5  *****************
00945  * User: Neusel       Date: 2/04/05    Time: 10:45a
00946  * Updated in $/SkyOS.root/pig/Humble
00947  * 
00948  * *****************  Version 4  *****************
00949  * User: Neusel       Date: 12/23/04   Time: 1:34p
00950  * Updated in $/SkyOS.root/pig/Humble
00951  * Posted as HFramework-debug 20041223
00952  * 
00953  * *****************  Version 3  *****************
00954  * User: Neusel       Date: 12/10/04   Time: 3:57p
00955  * Updated in $/SkyOS.root/pig/Humble
00956  * 20041210
00957  * 
00958  * *****************  Version 2  *****************
00959  * User: Neusel       Date: 12/08/04   Time: 5:06p
00960  * Updated in $/SkyOS.root/pig/Humble
00961  * 20041208
00962  * 
00963  * *****************  Version 1  *****************
00964  * User: Neusel       Date: 11/30/04   Time: 1:01p
00965  * Created in $/SkyOS.root/pig/Humble
00966  * Released as HUMBLE_VER 20041130.
00967 **
00968 **  -------------------------------------------------------------------------
00969 **
00970 **  End of Humble.cpp
00971 **
00972 ****************************************************************************/