VirtualBox

Changeset 26481 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Feb 14, 2010 1:00:49 AM (15 years ago)
Author:
vboxsync
Message:

IPRT: Added RTStrAAppend, RTStrAAppendN, RTStrAAppendExN[V]{,1}, RTStrAlloc, RTStrAllocEx and RTStrRealloc. Fixed bug in RTStrDupN.

File:
1 edited

Legend:

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

    r26480 r26481  
    3636#include "internal/iprt.h"
    3737
    38 #include <iprt/alloc.h>
     38#include <iprt/alloca.h>
    3939#include <iprt/assert.h>
     40#include <iprt/mem.h>
    4041#include <iprt/err.h>
    4142#include "internal/string.h"
    4243
    4344
    44 /**
    45  * Free string allocated by any of the non-UCS-2 string functions.
    46  *
    47  * @returns iprt status code.
    48  * @param   pszString      Pointer to buffer with string to free.
    49  *                         NULL is accepted.
    50  */
     45
     46RTDECL(char *) RTStrAlloc(size_t cb)
     47{
     48    char *psz = (char *)RTMemAlloc(RT_MAX(cb, 1));
     49    if (psz)
     50        *psz = '\0';
     51    return psz;
     52}
     53RT_EXPORT_SYMBOL(RTStrAlloc);
     54
     55
     56RTDECL(int) RTStrAllocEx(char **ppsz, size_t cb)
     57{
     58    char *psz = *ppsz = (char *)RTMemAlloc(RT_MAX(cb, 1));
     59    if (psz)
     60    {
     61        *psz = '\0';
     62        return VINF_SUCCESS;
     63    }
     64    return VERR_NO_STR_MEMORY;
     65}
     66RT_EXPORT_SYMBOL(RTStrAlloc);
     67
     68
     69RTDECL(int) RTStrRealloc(char **ppsz, size_t cbNew)
     70{
     71    char *pszOld = *ppsz;
     72    if (!cbNew)
     73    {
     74        RTMemFree(pszOld);
     75        *ppsz = NULL;
     76    }
     77    else if (pszOld)
     78    {
     79        char *pszNew = (char *)RTMemRealloc(pszOld, cbNew);
     80        if (!pszNew)
     81            return VERR_NO_STR_MEMORY;
     82        pszNew[cbNew - 1] = '\0';
     83        *ppsz = pszNew;
     84    }
     85    else
     86    {
     87        char *pszNew = (char *)RTMemAlloc(cbNew);
     88        if (!pszNew)
     89            return VERR_NO_STR_MEMORY;
     90        pszNew[0] = '\0';
     91        pszNew[cbNew - 1] = '\0';
     92        *ppsz = pszNew;
     93    }
     94    return VINF_SUCCESS;
     95}
     96
    5197RTDECL(void)  RTStrFree(char *pszString)
    5298{
     
    57103
    58104
    59 /**
    60  * Allocates a new copy of the given UTF-8 string.
    61  *
    62  * @returns Pointer to the allocated UTF-8 string.
    63  * @param   pszString       UTF-8 string to duplicate.
    64  */
    65105RTDECL(char *) RTStrDup(const char *pszString)
    66106{
     
    75115
    76116
    77 /**
    78  * Allocates a new copy of the given UTF-8 string.
    79  *
    80  * @returns iprt status code.
    81  * @param   ppszString      Receives pointer of the allocated UTF-8 string.
    82  *                          The returned pointer must be freed using RTStrFree().
    83  * @param   pszString       UTF-8 string to duplicate.
    84  */
    85117RTDECL(int)  RTStrDupEx(char **ppszString, const char *pszString)
    86118{
     
    101133
    102134
    103 /**
    104  * Allocates a new copy of the given UTF-8 substring.
    105  *
    106  * @returns Pointer to the allocated UTF-8 substring.
    107  * @param   pszString       UTF-8 string to duplicate.
    108  * @param   cchMax          The max number of chars to duplicate, not counting
    109  *                          the terminator.
    110  */
    111135RTDECL(char *) RTStrDupN(const char *pszString, size_t cchMax)
    112136{
     
    114138    char  *pszEnd = (char *)memchr(pszString, '\0', cchMax);
    115139    size_t cch    = pszEnd ? (uintptr_t)pszEnd - (uintptr_t)pszString : cchMax;
    116     char  *pszDst = (char *)RTMemAlloc(cch);
     140    char  *pszDst = (char *)RTMemAlloc(cch + 1);
    117141    if (pszDst)
    118142    {
     
    124148RT_EXPORT_SYMBOL(RTStrDupN);
    125149
     150
     151RTDECL(int) RTStrAAppend(char **ppsz, const char *pszAppend)
     152{
     153    if (!pszAppend)
     154        return VINF_SUCCESS;
     155    return RTStrAAppendN(ppsz, pszAppend, RTSTR_MAX);
     156}
     157
     158
     159RTDECL(int) RTStrAAppendN(char **ppsz, const char *pszAppend, size_t cchAppend)
     160{
     161    if (!cchAppend)
     162        return VINF_SUCCESS;
     163    if (cchAppend == RTSTR_MAX)
     164        cchAppend = strlen(pszAppend);
     165    else
     166        Assert(cchAppend == RTStrNLen(pszAppend, cchAppend));
     167
     168    size_t const cchOrg = *ppsz ? strlen(*ppsz) : 0;
     169    char *pszNew = (char *)RTMemRealloc(*ppsz, cchOrg + cchAppend + 1);
     170    if (!pszNew)
     171        return VERR_NO_STR_MEMORY;
     172
     173    memcpy(&pszNew[cchOrg], pszAppend, cchAppend);
     174    pszNew[cchOrg + cchAppend] = '\0';
     175
     176    *ppsz = pszNew;
     177    return VINF_SUCCESS;
     178}
     179
     180
     181RTDECL(int) RTStrAAppendExNV(char **ppsz, size_t cPairs, va_list va)
     182{
     183    AssertPtr(ppsz);
     184    if (!cPairs)
     185        return VINF_SUCCESS;
     186
     187    /*
     188     * Determin the length of each string and calc the new total.
     189     */
     190    struct RTStrAAppendExNVStruct
     191    {
     192        const char *psz;
     193        size_t      cch;
     194    } *paPairs = (struct RTStrAAppendExNVStruct *)alloca(cPairs * sizeof(*paPairs));
     195    AssertReturn(paPairs, VERR_NO_STR_MEMORY);
     196
     197    size_t  cchOrg      = *ppsz ? strlen(*ppsz) : 0;
     198    size_t  cchNewTotal = cchOrg;
     199    for (size_t i = 0; i < cPairs; i++)
     200    {
     201        const char *psz = va_arg(va, const char *);
     202        size_t      cch = va_arg(va, size_t);
     203        AssertPtrNull(psz);
     204        Assert(cch == RTSTR_MAX || cch == RTStrNLen(psz, cch));
     205
     206        if (cch == RTSTR_MAX)
     207            cch = psz ? strlen(psz) : 0;
     208        cchNewTotal += cch;
     209
     210        paPairs[i].cch = cch;
     211        paPairs[i].psz = psz;
     212    }
     213    cchNewTotal++;                      /* '\0' */
     214
     215    /*
     216     * Try reallocate the string.
     217     */
     218    char *pszNew = (char *)RTMemRealloc(*ppsz, cchNewTotal);
     219    if (!pszNew)
     220        return VERR_NO_STR_MEMORY;
     221
     222    /*
     223     * Do the appending.
     224     */
     225    size_t off = cchOrg;
     226    for (size_t i = 0; i < cPairs; i++)
     227    {
     228        memcpy(&pszNew[off], paPairs[i].psz, paPairs[i].cch);
     229        off += paPairs[i].cch;
     230    }
     231    Assert(off + 1 == cchNewTotal);
     232    pszNew[off] = '\0';
     233
     234    /* done */
     235    *ppsz = pszNew;
     236    return VINF_SUCCESS;
     237}
     238RT_EXPORT_SYMBOL(RTStrAAppendExNV);
     239
     240
     241RTDECL(int) RTStrAAppendExN(char **ppsz, size_t cPairs, ...)
     242{
     243    va_list va;
     244    va_start(va, cPairs);
     245    int rc = RTStrAAppendExNV(ppsz, cPairs, va);
     246    va_end(va);
     247    return rc;
     248}
     249RT_EXPORT_SYMBOL(RTStrAAppendExN);
     250
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