VirtualBox

Ignore:
Timestamp:
Nov 14, 2009 11:41:50 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
54838
Message:

Moved RTStrVersionToUInt32 out of strtonum.cpp.

Location:
trunk/src/VBox/Runtime/common/string
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/string/strtonum.cpp

    r24661 r24662  
    3333*   Header Files                                                               *
    3434*******************************************************************************/
    35 #include <iprt/mem.h>
    3635#include <iprt/string.h>
    3736#include "internal/iprt.h"
     
    9291}
    9392*/
    94 
    95 
    96 /**
    97  * Converts a string representation of a version number to an unsigned number.
    98  *
    99  * @returns iprt status code.
    100  *          Warnings are used to indicate convertion problems.
    101  * @retval  VWRN_NUMBER_TOO_BIG
    102  * @retval  VWRN_TRAILING_CHARS
    103  * @retval  VWRN_TRAILING_SPACES
    104  * @retval  VINF_SUCCESS
    105  * @retval  VERR_NO_MEMORY
    106  * @retval  VERR_NO_DIGITS
    107  *
    108  * @param   pszValue    Pointer to the string value.
    109  * @param   pu32        Where to store the converted number.
    110  *
    111  * @todo    r=bird: The returned value isn't really suitable for comparing two
    112  *          version strings.  Try see which result you get when converting
    113  *          "3.0.14" and "3.1.0" and comparing the values.  The way to fix this
    114  *          deficiency would be to convert the individual parts and dividing the
    115  *          return value into sections: bits 31:24 FirstNumber; 23:16 Second;
    116  *          15:8 Third; 7:0 Forth.  It would probably be a good idea to use a
    117  *          64-bit return value instead of a 32-bit one, so there is room for
    118  *          revision number when found.
    119  *
    120  *          Actually, because of the above, the kind of API I had in mind was
    121  *          int RTStrVersionCompare(const char *pszVer1, const char *pszVer2).
    122  *          It wouldn't try convert input to numbers, just do a parallel parse.
    123  *          This would allow easy handling beta/alpha/++ indicators and any
    124  *          number of dots and dashes.
    125  */
    126 RTDECL(int) RTStrVersionToUInt32(const char *pszVer, uint32_t *pu32)
    127 {
    128     const char *psz = pszVer;
    129     AssertPtr(pu32);
    130     AssertPtr(psz);
    131 
    132     char *pszNew = (char*)RTMemAllocZ((strlen(pszVer) + 1) * sizeof(char));
    133     if (pszNew == NULL)
    134         return VERR_NO_MEMORY;
    135 
    136     unsigned    i            = 0;
    137     bool        fLastInvalid = false;
    138     while (    psz
    139            && *psz != '\0')
    140     {
    141         if (fLastInvalid)
    142         {
    143             if (   *psz == '-'
    144                 || *psz == '_')
    145                 fLastInvalid = false;
    146         }
    147         else
    148         {
    149             if (RT_C_IS_DIGIT(*psz))
    150                 pszNew[i++] = *psz;
    151             else if (   *psz != '.'
    152                      && i == 0)
    153                 fLastInvalid = true;
    154         }
    155         psz++;
    156     }
    157     pszNew[i] = '\0';
    158 
    159     /* Convert final number string to number */
    160     int rc;
    161     if (fLastInvalid)
    162     {
    163         *pu32 = 0;
    164         rc = VERR_NO_DIGITS;
    165     }
    166     else
    167     {
    168         rc = RTStrToUInt32Ex(pszNew, NULL /*pszNext*/, 10 /*uBase*/, pu32);
    169         if (rc != VINF_SUCCESS)
    170             *pu32 = 0;
    171     }
    172     RTStrFree(pszNew);
    173     return rc;
    174 }
    17593
    17694
  • trunk/src/VBox/Runtime/common/string/strversion.cpp

    r24661 r24662  
    11/* $Id$ */
    22/** @file
    3  * IPRT - String To Number Convertion.
     3 * IPRT - Version String Parsing.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2009 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3333*   Header Files                                                               *
    3434*******************************************************************************/
    35 #include <iprt/mem.h>
    3635#include <iprt/string.h>
    3736#include "internal/iprt.h"
     
    4039#include <iprt/ctype.h> /* needed for RT_C_IS_DIGIT */
    4140#include <iprt/err.h>
     41#include <iprt/mem.h>
    4242
    43 
    44 /*******************************************************************************
    45 *   Global Variables                                                           *
    46 *******************************************************************************/
    47 /** 8-bit char -> digit. */
    48 static const unsigned char g_auchDigits[256] =
    49 {
    50     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    51     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,255,255,255,255,255,255,
    52     255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
    53     255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
    54     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    55     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    56     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    57     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
    58 };
    59 /** Approximated overflow shift checks. */
    60 static const char g_auchShift[36] =
    61 {
    62   /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35 */
    63      64, 64, 63, 63, 62, 62, 62, 62, 61, 61, 61, 61, 61, 61, 61, 61, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 59, 59, 59, 59
    64 };
    65 
    66 /*
    67 #include <stdio.h>
    68 int main()
    69 {
    70     int i;
    71     printf("static const unsigned char g_auchDigits[256] =\n"
    72            "{");
    73     for (i = 0; i < 256; i++)
    74     {
    75         int ch = 255;
    76         if (i >= '0' && i <= '9')
    77             ch = i - '0';
    78         else if (i >= 'a' && i <= 'z')
    79             ch = i - 'a' + 10;
    80         else if (i >= 'A' && i <= 'Z')
    81             ch = i - 'A' + 10;
    82         if (i == 0)
    83             printf("\n    %3d", ch);
    84         else if ((i % 32) == 0)
    85             printf(",\n    %3d", ch);
    86         else
    87             printf(",%3d", ch);
    88     }
    89     printf("\n"
    90            "};\n");
    91     return 0;
    92 }
    93 */
    9443
    9544
     
    174123}
    175124
    176 
    177 /**
    178  * Converts a string representation of a number to a 64-bit unsigned number.
    179  *
    180  * @returns iprt status code.
    181  *          Warnings are used to indicate convertion problems.
    182  * @retval  VWRN_NUMBER_TOO_BIG
    183  * @retval  VWRN_NEGATIVE_UNSIGNED
    184  * @retval  VWRN_TRAILING_CHARS
    185  * @retval  VWRN_TRAILING_SPACES
    186  * @retval  VINF_SUCCESS
    187  * @retval  VERR_NO_DIGITS
    188  *
    189  * @param   pszValue    Pointer to the string value.
    190  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    191  * @param   uBase       The base of the representation used.
    192  *                      If the function will look for known prefixes before defaulting to 10.
    193  * @param   pu64        Where to store the converted number. (optional)
    194  */
    195 RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint64_t *pu64)
    196 {
    197     const char   *psz = pszValue;
    198     int           iShift;
    199     int           rc;
    200     uint64_t      u64;
    201     unsigned char uch;
    202 
    203     /*
    204      * Positive/Negative stuff.
    205      */
    206     bool fPositive = true;
    207     for (;; psz++)
    208     {
    209         if (*psz == '+')
    210             fPositive = true;
    211         else if (*psz == '-')
    212             fPositive = !fPositive;
    213         else
    214             break;
    215     }
    216 
    217     /*
    218      * Check for hex prefix.
    219      */
    220     if (!uBase)
    221     {
    222         if (    psz[0] == '0'
    223             &&  (psz[1] == 'x' || psz[1] == 'X')
    224             &&  g_auchDigits[(unsigned char)psz[2]] < 16)
    225         {
    226             uBase = 16;
    227             psz += 2;
    228         }
    229         else if (   psz[0] == '0'
    230                  && g_auchDigits[(unsigned char)psz[1]] < 8)
    231         {
    232             uBase = 8;
    233             psz++;
    234         }
    235         else
    236             uBase = 10;
    237     }
    238     else if (   uBase == 16
    239              && psz[0] == '0'
    240              && (psz[1] == 'x' || psz[1] == 'X')
    241              && g_auchDigits[(unsigned char)psz[2]] < 16)
    242         psz += 2;
    243 
    244     /*
    245      * Interpret the value.
    246      * Note: We only support ascii digits at this time... :-)
    247      */
    248     iShift = g_auchShift[uBase];
    249     pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
    250     rc = VINF_SUCCESS;
    251     u64 = 0;
    252     while ((uch = (unsigned char)*psz) != 0)
    253     {
    254         unsigned char chDigit = g_auchDigits[uch];
    255         uint64_t u64Prev;
    256 
    257         if (chDigit >= uBase)
    258             break;
    259 
    260         u64Prev = u64;
    261         u64 *= uBase;
    262         u64 += chDigit;
    263         if (u64Prev > u64 || (u64Prev >> iShift))
    264             rc = VWRN_NUMBER_TOO_BIG;
    265         psz++;
    266     }
    267 
    268     if (!fPositive)
    269     {
    270         if (rc == VINF_SUCCESS)
    271             rc = VWRN_NEGATIVE_UNSIGNED;
    272         u64 = -(int64_t)u64;
    273     }
    274 
    275     if (pu64)
    276         *pu64 = u64;
    277 
    278     if (psz == pszValue)
    279         rc = VERR_NO_DIGITS;
    280 
    281     if (ppszNext)
    282         *ppszNext = (char *)psz;
    283 
    284     /*
    285      * Warn about trailing chars/spaces.
    286      */
    287     if (    rc == VINF_SUCCESS
    288         &&  *psz)
    289     {
    290         while (*psz == ' ' || *psz == '\t')
    291             psz++;
    292         rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
    293     }
    294 
    295     return rc;
    296 }
    297 RT_EXPORT_SYMBOL(RTStrToUInt64Ex);
    298 
    299 
    300 /**
    301  * Converts a string representation of a number to a 64-bit unsigned number,
    302  * making sure the full string is converted.
    303  *
    304  * @returns iprt status code.
    305  *          Warnings are used to indicate convertion problems.
    306  * @retval  VWRN_NUMBER_TOO_BIG
    307  * @retval  VWRN_NEGATIVE_UNSIGNED
    308  * @retval  VINF_SUCCESS
    309  * @retval  VERR_NO_DIGITS
    310  * @retval  VERR_TRAILING_SPACES
    311  * @retval  VERR_TRAILING_CHARS
    312  *
    313  * @param   pszValue    Pointer to the string value.
    314  * @param   uBase       The base of the representation used.
    315  *                      If the function will look for known prefixes before defaulting to 10.
    316  * @param   pu64        Where to store the converted number. (optional)
    317  */
    318 RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBase, uint64_t *pu64)
    319 {
    320     char *psz;
    321     int rc = RTStrToUInt64Ex(pszValue, &psz, uBase, pu64);
    322     if (RT_SUCCESS(rc) && *psz)
    323     {
    324         if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
    325             rc = -rc;
    326         else
    327         {
    328             while (*psz == ' ' || *psz == '\t')
    329                 psz++;
    330             rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
    331         }
    332     }
    333     return rc;
    334 }
    335 RT_EXPORT_SYMBOL(RTStrToUInt64Full);
    336 
    337 
    338 /**
    339  * Converts a string representation of a number to a 64-bit unsigned number.
    340  * The base is guessed.
    341  *
    342  * @returns 64-bit unsigned number on success.
    343  * @returns 0 on failure.
    344  * @param   pszValue    Pointer to the string value.
    345  */
    346 RTDECL(uint64_t) RTStrToUInt64(const char *pszValue)
    347 {
    348     uint64_t u64;
    349     int rc = RTStrToUInt64Ex(pszValue, NULL, 0, &u64);
    350     if (RT_SUCCESS(rc))
    351         return u64;
    352     return 0;
    353 }
    354 RT_EXPORT_SYMBOL(RTStrToUInt64);
    355 
    356 
    357 /**
    358  * Converts a string representation of a number to a 32-bit unsigned number.
    359  *
    360  * @returns iprt status code.
    361  *          Warnings are used to indicate convertion problems.
    362  * @retval  VWRN_NUMBER_TOO_BIG
    363  * @retval  VWRN_NEGATIVE_UNSIGNED
    364  * @retval  VWRN_TRAILING_CHARS
    365  * @retval  VWRN_TRAILING_SPACES
    366  * @retval  VINF_SUCCESS
    367  * @retval  VERR_NO_DIGITS
    368  *
    369  * @param   pszValue    Pointer to the string value.
    370  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    371  * @param   uBase       The base of the representation used.
    372  *                      If the function will look for known prefixes before defaulting to 10.
    373  * @param   pu32        Where to store the converted number. (optional)
    374  */
    375 RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32)
    376 {
    377     uint64_t u64;
    378     int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
    379     if (RT_SUCCESS(rc))
    380     {
    381         if (u64 & ~0xffffffffULL)
    382             rc = VWRN_NUMBER_TOO_BIG;
    383     }
    384     if (pu32)
    385         *pu32 = (uint32_t)u64;
    386     return rc;
    387 }
    388 RT_EXPORT_SYMBOL(RTStrToUInt32Ex);
    389 
    390 
    391 /**
    392  * Converts a string representation of a number to a 32-bit unsigned number,
    393  * making sure the full string is converted.
    394  *
    395  * @returns iprt status code.
    396  *          Warnings are used to indicate convertion problems.
    397  * @retval  VWRN_NUMBER_TOO_BIG
    398  * @retval  VWRN_NEGATIVE_UNSIGNED
    399  * @retval  VINF_SUCCESS
    400  * @retval  VERR_NO_DIGITS
    401  * @retval  VERR_TRAILING_SPACES
    402  * @retval  VERR_TRAILING_CHARS
    403  *
    404  * @param   pszValue    Pointer to the string value.
    405  * @param   uBase       The base of the representation used.
    406  *                      If the function will look for known prefixes before defaulting to 10.
    407  * @param   pu32        Where to store the converted number. (optional)
    408  */
    409 RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32)
    410 {
    411     uint64_t u64;
    412     int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
    413     if (RT_SUCCESS(rc))
    414     {
    415         if (u64 & ~0xffffffffULL)
    416             rc = VWRN_NUMBER_TOO_BIG;
    417     }
    418     if (pu32)
    419         *pu32 = (uint32_t)u64;
    420     return rc;
    421 }
    422 RT_EXPORT_SYMBOL(RTStrToUInt32Full);
    423 
    424 
    425 /**
    426  * Converts a string representation of a number to a 64-bit unsigned number.
    427  * The base is guessed.
    428  *
    429  * @returns 32-bit unsigned number on success.
    430  * @returns 0 on failure.
    431  * @param   pszValue    Pointer to the string value.
    432  */
    433 RTDECL(uint32_t) RTStrToUInt32(const char *pszValue)
    434 {
    435     uint32_t u32;
    436     int rc = RTStrToUInt32Ex(pszValue, NULL, 0, &u32);
    437     if (RT_SUCCESS(rc))
    438         return u32;
    439     return 0;
    440 }
    441 RT_EXPORT_SYMBOL(RTStrToUInt32);
    442 
    443 
    444 /**
    445  * Converts a string representation of a number to a 16-bit unsigned number.
    446  *
    447  * @returns iprt status code.
    448  *          Warnings are used to indicate convertion problems.
    449  * @retval  VWRN_NUMBER_TOO_BIG
    450  * @retval  VWRN_NEGATIVE_UNSIGNED
    451  * @retval  VWRN_TRAILING_CHARS
    452  * @retval  VWRN_TRAILING_SPACES
    453  * @retval  VINF_SUCCESS
    454  * @retval  VERR_NO_DIGITS
    455  *
    456  * @param   pszValue    Pointer to the string value.
    457  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    458  * @param   uBase       The base of the representation used.
    459  *                      If the function will look for known prefixes before defaulting to 10.
    460  * @param   pu16        Where to store the converted number. (optional)
    461  */
    462 RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint16_t *pu16)
    463 {
    464     uint64_t u64;
    465     int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
    466     if (RT_SUCCESS(rc))
    467     {
    468         if (u64 & ~0xffffULL)
    469             rc = VWRN_NUMBER_TOO_BIG;
    470     }
    471     if (pu16)
    472         *pu16 = (uint16_t)u64;
    473     return rc;
    474 }
    475 RT_EXPORT_SYMBOL(RTStrToUInt16Ex);
    476 
    477 
    478 /**
    479  * Converts a string representation of a number to a 16-bit unsigned number,
    480  * making sure the full string is converted.
    481  *
    482  * @returns iprt status code.
    483  *          Warnings are used to indicate convertion problems.
    484  * @retval  VWRN_NUMBER_TOO_BIG
    485  * @retval  VWRN_NEGATIVE_UNSIGNED
    486  * @retval  VINF_SUCCESS
    487  * @retval  VERR_NO_DIGITS
    488  * @retval  VERR_TRAILING_SPACES
    489  * @retval  VERR_TRAILING_CHARS
    490  *
    491  * @param   pszValue    Pointer to the string value.
    492  * @param   uBase       The base of the representation used.
    493  *                      If the function will look for known prefixes before defaulting to 10.
    494  * @param   pu16        Where to store the converted number. (optional)
    495  */
    496 RTDECL(int) RTStrToUInt16Full(const char *pszValue, unsigned uBase, uint16_t *pu16)
    497 {
    498     uint64_t u64;
    499     int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
    500     if (RT_SUCCESS(rc))
    501     {
    502         if (u64 & ~0xffffULL)
    503             rc = VWRN_NUMBER_TOO_BIG;
    504     }
    505     if (pu16)
    506         *pu16 = (uint16_t)u64;
    507     return rc;
    508 }
    509 RT_EXPORT_SYMBOL(RTStrToUInt16Full);
    510 
    511 
    512 /**
    513  * Converts a string representation of a number to a 16-bit unsigned number.
    514  * The base is guessed.
    515  *
    516  * @returns 16-bit unsigned number on success.
    517  * @returns 0 on failure.
    518  * @param   pszValue    Pointer to the string value.
    519  */
    520 RTDECL(uint16_t) RTStrToUInt16(const char *pszValue)
    521 {
    522     uint16_t u16;
    523     int rc = RTStrToUInt16Ex(pszValue, NULL, 0, &u16);
    524     if (RT_SUCCESS(rc))
    525         return u16;
    526     return 0;
    527 }
    528 RT_EXPORT_SYMBOL(RTStrToUInt16);
    529 
    530 
    531 /**
    532  * Converts a string representation of a number to a 8-bit unsigned number.
    533  *
    534  * @returns iprt status code.
    535  *          Warnings are used to indicate convertion problems.
    536  * @retval  VWRN_NUMBER_TOO_BIG
    537  * @retval  VWRN_NEGATIVE_UNSIGNED
    538  * @retval  VWRN_TRAILING_CHARS
    539  * @retval  VWRN_TRAILING_SPACES
    540  * @retval  VINF_SUCCESS
    541  * @retval  VERR_NO_DIGITS
    542  *
    543  * @param   pszValue    Pointer to the string value.
    544  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    545  * @param   uBase       The base of the representation used.
    546  *                      If the function will look for known prefixes before defaulting to 10.
    547  * @param   pu8         Where to store the converted number. (optional)
    548  */
    549 RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint8_t *pu8)
    550 {
    551     uint64_t u64;
    552     int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
    553     if (RT_SUCCESS(rc))
    554     {
    555         if (u64 & ~0xffULL)
    556             rc = VWRN_NUMBER_TOO_BIG;
    557     }
    558     if (pu8)
    559         *pu8 = (uint8_t)u64;
    560     return rc;
    561 }
    562 RT_EXPORT_SYMBOL(RTStrToUInt8Ex);
    563 
    564 
    565 /**
    566  * Converts a string representation of a number to a 8-bit unsigned number,
    567  * making sure the full string is converted.
    568  *
    569  * @returns iprt status code.
    570  *          Warnings are used to indicate convertion problems.
    571  * @retval  VWRN_NUMBER_TOO_BIG
    572  * @retval  VWRN_NEGATIVE_UNSIGNED
    573  * @retval  VINF_SUCCESS
    574  * @retval  VERR_NO_DIGITS
    575  * @retval  VERR_TRAILING_SPACES
    576  * @retval  VERR_TRAILING_CHARS
    577  *
    578  * @param   pszValue    Pointer to the string value.
    579  * @param   uBase       The base of the representation used.
    580  *                      If the function will look for known prefixes before defaulting to 10.
    581  * @param   pu8         Where to store the converted number. (optional)
    582  */
    583 RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBase, uint8_t *pu8)
    584 {
    585     uint64_t u64;
    586     int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
    587     if (RT_SUCCESS(rc))
    588     {
    589         if (u64 & ~0xffULL)
    590             rc = VWRN_NUMBER_TOO_BIG;
    591     }
    592     if (pu8)
    593         *pu8 = (uint8_t)u64;
    594     return rc;
    595 }
    596 RT_EXPORT_SYMBOL(RTStrToUInt8Full);
    597 
    598 
    599 /**
    600  * Converts a string representation of a number to a 8-bit unsigned number.
    601  * The base is guessed.
    602  *
    603  * @returns 8-bit unsigned number on success.
    604  * @returns 0 on failure.
    605  * @param   pszValue    Pointer to the string value.
    606  */
    607 RTDECL(uint8_t) RTStrToUInt8(const char *pszValue)
    608 {
    609     uint8_t u8;
    610     int rc = RTStrToUInt8Ex(pszValue, NULL, 0, &u8);
    611     if (RT_SUCCESS(rc))
    612         return u8;
    613     return 0;
    614 }
    615 RT_EXPORT_SYMBOL(RTStrToUInt8);
    616 
    617 
    618 
    619 
    620 
    621 
    622 
    623 /**
    624  * Converts a string representation of a number to a 64-bit signed number.
    625  *
    626  * @returns iprt status code.
    627  *          Warnings are used to indicate convertion problems.
    628  * @retval  VWRN_NUMBER_TOO_BIG
    629  * @retval  VWRN_TRAILING_CHARS
    630  * @retval  VWRN_TRAILING_SPACES
    631  * @retval  VINF_SUCCESS
    632  * @retval  VERR_NO_DIGITS
    633  *
    634  * @param   pszValue    Pointer to the string value.
    635  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    636  * @param   uBase       The base of the representation used.
    637  *                      If the function will look for known prefixes before defaulting to 10.
    638  * @param   pi64        Where to store the converted number. (optional)
    639  */
    640 RTDECL(int) RTStrToInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, int64_t *pi64)
    641 {
    642     const char   *psz = pszValue;
    643     int           iShift;
    644     int           rc;
    645     int64_t       i64;
    646     unsigned char uch;
    647 
    648     /*
    649      * Positive/Negative stuff.
    650      */
    651     bool fPositive = true;
    652     for (;; psz++)
    653     {
    654         if (*psz == '+')
    655             fPositive = true;
    656         else if (*psz == '-')
    657             fPositive = !fPositive;
    658         else
    659             break;
    660     }
    661 
    662     /*
    663      * Check for hex prefix.
    664      */
    665     if (!uBase)
    666     {
    667         if (    *psz == '0'
    668             &&  (psz[1] == 'x' || psz[1] == 'X')
    669             &&  g_auchDigits[(unsigned char)psz[2]] < 16)
    670         {
    671             uBase = 16;
    672             psz += 2;
    673         }
    674         else if (   *psz == '0'
    675                  && g_auchDigits[(unsigned char)psz[1]] < 8)
    676         {
    677             uBase = 8;
    678             psz++;
    679         }
    680         else
    681             uBase = 10;
    682     }
    683     else if (   uBase == 16
    684              && *psz == '0'
    685              && (psz[1] == 'x' || psz[1] == 'X')
    686              && g_auchDigits[(unsigned char)psz[2]] < 16)
    687         psz += 2;
    688 
    689     /*
    690      * Interpret the value.
    691      * Note: We only support ascii digits at this time... :-)
    692      */
    693     iShift = g_auchShift[uBase]; /** @todo test this, it's probably not 100% right yet. */
    694     pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
    695     rc = VINF_SUCCESS;
    696     i64 = 0;
    697     while ((uch = (unsigned char)*psz) != 0)
    698     {
    699         unsigned char chDigit = g_auchDigits[uch];
    700         int64_t i64Prev;
    701 
    702         if (chDigit >= uBase)
    703             break;
    704 
    705         i64Prev = i64;
    706         i64 *= uBase;
    707         i64 += chDigit;
    708         if (i64Prev > i64 || (i64Prev >> iShift))
    709             rc = VWRN_NUMBER_TOO_BIG;
    710         psz++;
    711     }
    712 
    713     if (!fPositive)
    714         i64 = -i64;
    715 
    716     if (pi64)
    717         *pi64 = i64;
    718 
    719     if (psz == pszValue)
    720         rc = VERR_NO_DIGITS;
    721 
    722     if (ppszNext)
    723         *ppszNext = (char *)psz;
    724 
    725     /*
    726      * Warn about trailing chars/spaces.
    727      */
    728     if (    rc == VINF_SUCCESS
    729         &&  *psz)
    730     {
    731         while (*psz == ' ' || *psz == '\t')
    732             psz++;
    733         rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
    734     }
    735 
    736     return rc;
    737 }
    738 RT_EXPORT_SYMBOL(RTStrToInt64Ex);
    739 
    740 
    741 /**
    742  * Converts a string representation of a number to a 64-bit signed number,
    743  * making sure the full string is converted.
    744  *
    745  * @returns iprt status code.
    746  *          Warnings are used to indicate convertion problems.
    747  * @retval  VWRN_NUMBER_TOO_BIG
    748  * @retval  VINF_SUCCESS
    749  * @retval  VERR_TRAILING_CHARS
    750  * @retval  VERR_TRAILING_SPACES
    751  * @retval  VERR_NO_DIGITS
    752  *
    753  * @param   pszValue    Pointer to the string value.
    754  * @param   uBase       The base of the representation used.
    755  *                      If the function will look for known prefixes before defaulting to 10.
    756  * @param   pi64        Where to store the converted number. (optional)
    757  */
    758 RTDECL(int) RTStrToInt64Full(const char *pszValue, unsigned uBase, int64_t *pi64)
    759 {
    760     char *psz;
    761     int rc = RTStrToInt64Ex(pszValue, &psz, uBase, pi64);
    762     if (RT_SUCCESS(rc) && *psz)
    763     {
    764         if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
    765             rc = -rc;
    766         else
    767         {
    768             while (*psz == ' ' || *psz == '\t')
    769                 psz++;
    770             rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
    771         }
    772     }
    773     return rc;
    774 }
    775 RT_EXPORT_SYMBOL(RTStrToInt64Full);
    776 
    777 
    778 /**
    779  * Converts a string representation of a number to a 64-bit signed number.
    780  * The base is guessed.
    781  *
    782  * @returns 64-bit signed number on success.
    783  * @returns 0 on failure.
    784  * @param   pszValue    Pointer to the string value.
    785  */
    786 RTDECL(int64_t) RTStrToInt64(const char *pszValue)
    787 {
    788     int64_t i64;
    789     int rc = RTStrToInt64Ex(pszValue, NULL, 0, &i64);
    790     if (RT_SUCCESS(rc))
    791         return i64;
    792     return 0;
    793 }
    794 RT_EXPORT_SYMBOL(RTStrToInt64);
    795 
    796 
    797 /**
    798  * Converts a string representation of a number to a 32-bit signed number.
    799  *
    800  * @returns iprt status code.
    801  *          Warnings are used to indicate convertion problems.
    802  * @retval  VWRN_NUMBER_TOO_BIG
    803  * @retval  VWRN_TRAILING_CHARS
    804  * @retval  VWRN_TRAILING_SPACES
    805  * @retval  VINF_SUCCESS
    806  * @retval  VERR_NO_DIGITS
    807  *
    808  * @param   pszValue    Pointer to the string value.
    809  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    810  * @param   uBase       The base of the representation used.
    811  *                      If the function will look for known prefixes before defaulting to 10.
    812  * @param   pi32        Where to store the converted number. (optional)
    813  */
    814 RTDECL(int) RTStrToInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, int32_t *pi32)
    815 {
    816     int64_t i64;
    817     int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
    818     if (RT_SUCCESS(rc))
    819     {
    820         int32_t i32 = (int32_t)i64;
    821         if (i64 != (int64_t)i32)
    822             rc = VWRN_NUMBER_TOO_BIG;
    823     }
    824     if (pi32)
    825         *pi32 = (int32_t)i64;
    826     return rc;
    827 }
    828 RT_EXPORT_SYMBOL(RTStrToInt32Ex);
    829 
    830 
    831 /**
    832  * Converts a string representation of a number to a 32-bit signed number,
    833  * making sure the full string is converted.
    834  *
    835  * @returns iprt status code.
    836  *          Warnings are used to indicate convertion problems.
    837  * @retval  VWRN_NUMBER_TOO_BIG
    838  * @retval  VINF_SUCCESS
    839  * @retval  VERR_TRAILING_CHARS
    840  * @retval  VERR_TRAILING_SPACES
    841  * @retval  VERR_NO_DIGITS
    842  *
    843  * @param   pszValue    Pointer to the string value.
    844  * @param   uBase       The base of the representation used.
    845  *                      If the function will look for known prefixes before defaulting to 10.
    846  * @param   pi32        Where to store the converted number. (optional)
    847  */
    848 RTDECL(int) RTStrToInt32Full(const char *pszValue, unsigned uBase, int32_t *pi32)
    849 {
    850     int64_t i64;
    851     int rc = RTStrToInt64Full(pszValue, uBase, &i64);
    852     if (RT_SUCCESS(rc))
    853     {
    854         int32_t i32 = (int32_t)i64;
    855         if (i64 != (int64_t)i32)
    856             rc = VWRN_NUMBER_TOO_BIG;
    857     }
    858     if (pi32)
    859         *pi32 = (int32_t)i64;
    860     return rc;
    861 }
    862 RT_EXPORT_SYMBOL(RTStrToInt32Full);
    863 
    864 
    865 /**
    866  * Converts a string representation of a number to a 32-bit signed number.
    867  * The base is guessed.
    868  *
    869  * @returns 32-bit signed number on success.
    870  * @returns 0 on failure.
    871  * @param   pszValue    Pointer to the string value.
    872  */
    873 RTDECL(int32_t) RTStrToInt32(const char *pszValue)
    874 {
    875     int32_t i32;
    876     int rc = RTStrToInt32Ex(pszValue, NULL, 0, &i32);
    877     if (RT_SUCCESS(rc))
    878         return i32;
    879     return 0;
    880 }
    881 RT_EXPORT_SYMBOL(RTStrToInt32);
    882 
    883 
    884 /**
    885  * Converts a string representation of a number to a 16-bit signed number.
    886  *
    887  * @returns iprt status code.
    888  *          Warnings are used to indicate convertion problems.
    889  * @retval  VWRN_NUMBER_TOO_BIG
    890  * @retval  VWRN_TRAILING_CHARS
    891  * @retval  VWRN_TRAILING_SPACES
    892  * @retval  VINF_SUCCESS
    893  * @retval  VERR_NO_DIGITS
    894  *
    895  * @param   pszValue    Pointer to the string value.
    896  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    897  * @param   uBase       The base of the representation used.
    898  *                      If the function will look for known prefixes before defaulting to 10.
    899  * @param   pi16        Where to store the converted number. (optional)
    900  */
    901 RTDECL(int) RTStrToInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, int16_t *pi16)
    902 {
    903     int64_t i64;
    904     int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
    905     if (RT_SUCCESS(rc))
    906     {
    907         int16_t i16 = (int16_t)i64;
    908         if (i64 != (int64_t)i16)
    909             rc = VWRN_NUMBER_TOO_BIG;
    910     }
    911     if (pi16)
    912         *pi16 = (int16_t)i64;
    913     return rc;
    914 }
    915 RT_EXPORT_SYMBOL(RTStrToInt16Ex);
    916 
    917 
    918 /**
    919  * Converts a string representation of a number to a 16-bit signed number,
    920  * making sure the full string is converted.
    921  *
    922  * @returns iprt status code.
    923  *          Warnings are used to indicate convertion problems.
    924  * @retval  VWRN_NUMBER_TOO_BIG
    925  * @retval  VINF_SUCCESS
    926  * @retval  VERR_TRAILING_CHARS
    927  * @retval  VERR_TRAILING_SPACES
    928  * @retval  VERR_NO_DIGITS
    929  *
    930  * @param   pszValue    Pointer to the string value.
    931  * @param   uBase       The base of the representation used.
    932  *                      If the function will look for known prefixes before defaulting to 10.
    933  * @param   pi16        Where to store the converted number. (optional)
    934  */
    935 RTDECL(int) RTStrToInt16Full(const char *pszValue, unsigned uBase, int16_t *pi16)
    936 {
    937     int64_t i64;
    938     int rc = RTStrToInt64Full(pszValue, uBase, &i64);
    939     if (RT_SUCCESS(rc))
    940     {
    941         int16_t i16 = (int16_t)i64;
    942         if (i64 != (int64_t)i16)
    943             rc = VWRN_NUMBER_TOO_BIG;
    944     }
    945     if (pi16)
    946         *pi16 = (int16_t)i64;
    947     return rc;
    948 }
    949 RT_EXPORT_SYMBOL(RTStrToInt16Full);
    950 
    951 
    952 /**
    953  * Converts a string representation of a number to a 16-bit signed number.
    954  * The base is guessed.
    955  *
    956  * @returns 16-bit signed number on success.
    957  * @returns 0 on failure.
    958  * @param   pszValue    Pointer to the string value.
    959  */
    960 RTDECL(int16_t) RTStrToInt16(const char *pszValue)
    961 {
    962     int16_t i16;
    963     int rc = RTStrToInt16Ex(pszValue, NULL, 0, &i16);
    964     if (RT_SUCCESS(rc))
    965         return i16;
    966     return 0;
    967 }
    968 RT_EXPORT_SYMBOL(RTStrToInt16);
    969 
    970 
    971 /**
    972  * Converts a string representation of a number to a 8-bit signed number.
    973  *
    974  * @returns iprt status code.
    975  *          Warnings are used to indicate convertion problems.
    976  * @retval  VWRN_NUMBER_TOO_BIG
    977  * @retval  VWRN_TRAILING_CHARS
    978  * @retval  VWRN_TRAILING_SPACES
    979  * @retval  VINF_SUCCESS
    980  * @retval  VERR_NO_DIGITS
    981  *
    982  * @param   pszValue    Pointer to the string value.
    983  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    984  * @param   uBase       The base of the representation used.
    985  *                      If the function will look for known prefixes before defaulting to 10.
    986  * @param   pi8        Where to store the converted number. (optional)
    987  */
    988 RTDECL(int) RTStrToInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, int8_t *pi8)
    989 {
    990     int64_t i64;
    991     int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
    992     if (RT_SUCCESS(rc))
    993     {
    994         int8_t i8 = (int8_t)i64;
    995         if (i64 != (int64_t)i8)
    996             rc = VWRN_NUMBER_TOO_BIG;
    997     }
    998     if (pi8)
    999         *pi8 = (int8_t)i64;
    1000     return rc;
    1001 }
    1002 RT_EXPORT_SYMBOL(RTStrToInt8Ex);
    1003 
    1004 
    1005 /**
    1006  * Converts a string representation of a number to a 8-bit signed number,
    1007  * making sure the full string is converted.
    1008  *
    1009  * @returns iprt status code.
    1010  *          Warnings are used to indicate convertion problems.
    1011  * @retval  VWRN_NUMBER_TOO_BIG
    1012  * @retval  VINF_SUCCESS
    1013  * @retval  VERR_TRAILING_CHARS
    1014  * @retval  VERR_TRAILING_SPACES
    1015  * @retval  VERR_NO_DIGITS
    1016  *
    1017  * @param   pszValue    Pointer to the string value.
    1018  * @param   uBase       The base of the representation used.
    1019  *                      If the function will look for known prefixes before defaulting to 10.
    1020  * @param   pi8         Where to store the converted number. (optional)
    1021  */
    1022 RTDECL(int) RTStrToInt8Full(const char *pszValue, unsigned uBase, int8_t *pi8)
    1023 {
    1024     int64_t i64;
    1025     int rc = RTStrToInt64Full(pszValue, uBase, &i64);
    1026     if (RT_SUCCESS(rc))
    1027     {
    1028         int8_t i8 = (int8_t)i64;
    1029         if (i64 != (int64_t)i8)
    1030             rc = VWRN_NUMBER_TOO_BIG;
    1031     }
    1032     if (pi8)
    1033         *pi8 = (int8_t)i64;
    1034     return rc;
    1035 }
    1036 RT_EXPORT_SYMBOL(RTStrToInt8Full);
    1037 
    1038 
    1039 /**
    1040  * Converts a string representation of a number to a 8-bit signed number.
    1041  * The base is guessed.
    1042  *
    1043  * @returns 8-bit signed number on success.
    1044  * @returns 0 on failure.
    1045  * @param   pszValue    Pointer to the string value.
    1046  */
    1047 RTDECL(int8_t) RTStrToInt8(const char *pszValue)
    1048 {
    1049     int8_t i8;
    1050     int rc = RTStrToInt8Ex(pszValue, NULL, 0, &i8);
    1051     if (RT_SUCCESS(rc))
    1052         return i8;
    1053     return 0;
    1054 }
    1055 RT_EXPORT_SYMBOL(RTStrToInt8);
    1056 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette