VirtualBox

Changeset 34214 in vbox


Ignore:
Timestamp:
Nov 19, 2010 5:18:15 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67956
Message:

IPRT: Added RTPathJoinEx and RTPathAppendEx.

Location:
trunk
Files:
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/path.h

    r34002 r34214  
    445445 *                          NULL, in which case nothing is done.
    446446 *
     447 * @remarks See the RTPathAppendEx remarks.
     448 */
     449RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend);
     450
     451/**
     452 * Appends one partial path to another.
     453 *
     454 * The main purpose of this function is to deal correctly with the slashes when
     455 * concatenating the two partial paths.
     456 *
     457 * @retval  VINF_SUCCESS on success.
     458 * @retval  VERR_BUFFER_OVERFLOW if the result is too big to fit within
     459 *          cbPathDst bytes. No changes has been made.
     460 * @retval  VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
     461 *          than cbPathDst-1 bytes (failed to find terminator). Asserted.
     462 *
     463 * @param   pszPath         The path to append pszAppend to. This serves as both
     464 *                          input and output. This can be empty, in which case
     465 *                          pszAppend is just copied over.
     466 * @param   cbPathDst       The size of the buffer pszPath points to, terminator
     467 *                          included. This should NOT be strlen(pszPath).
     468 * @param   pszAppend       The partial path to append to pszPath. This can be
     469 *                          NULL, in which case nothing is done.
     470 * @param   cchAppendMax    The maximum number or characters to take from @a
     471 *                          pszAppend.  RTSTR_MAX is fine.
     472 *
    447473 * @remarks On OS/2, Window and similar systems, concatenating a drive letter
    448474 *          specifier with a slash prefixed path will result in an absolute
     
    456482 *          sizeof(szBuf), "bar") will result in "C:bar".
    457483 */
    458 RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend);
     484RTDECL(int) RTPathAppendEx(char *pszPath, size_t cbPathDst, const char *pszAppend, size_t cchAppendMax);
    459485
    460486/**
     
    492518 */
    493519RTDECL(char *) RTPathJoinA(const char *pszPathSrc, const char *pszAppend);
     520
     521/**
     522 * Extended version of RTPathJoin, both inputs can be specified as substrings.
     523 *
     524 * @retval  VINF_SUCCESS on success.
     525 * @retval  VERR_BUFFER_OVERFLOW if the result is too big to fit within
     526 *          cbPathDst bytes.
     527 * @retval  VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
     528 *          than cbPathDst-1 bytes (failed to find terminator). Asserted.
     529 *
     530 * @param   pszPathDst      Where to store the resulting path.
     531 * @param   cbPathDst       The size of the buffer pszPathDst points to,
     532 *                          terminator included.
     533 * @param   pszPathSrc      The base path to copy into @a pszPathDst before
     534 *                          appending @a pszAppend.
     535 * @param   cchPathSrcMax   The maximum number of bytes to copy from @a
     536 *                          pszPathSrc.  RTSTR_MAX is find.
     537 * @param   pszAppend       The partial path to append to pszPathSrc. This can
     538 *                          be NULL, in which case nothing is done.
     539 * @param   cchAppendMax    The maximum number of bytes to copy from @a
     540 *                          pszAppend.  RTSTR_MAX is find.
     541 *
     542 */
     543RTDECL(int) RTPathJoinEx(char *pszPathDst, size_t cbPathDst,
     544                         const char *pszPathSrc, size_t cchPathSrcMax,
     545                         const char *pszAppend, size_t cchAppendMax);
    494546
    495547/**
  • trunk/src/VBox/Runtime/Makefile.kmk

    r34045 r34214  
    289289        common/path/RTPathAbsExDup.cpp \
    290290        common/path/RTPathAppend.cpp \
     291        common/path/RTPathAppendEx.cpp \
    291292        common/path/RTPathChangeToDosSlashes.cpp \
    292293        common/path/RTPathChangeToUnixSlashes.cpp \
     
    299300        common/path/RTPathJoin.cpp \
    300301        common/path/RTPathJoinA.cpp \
     302        common/path/RTPathJoinEx.cpp \
    301303        common/path/RTPathParse.cpp \
    302304        common/path/RTPathRealDup.cpp \
     
    984986        common/path/RTPathAbsExDup.cpp \
    985987        common/path/RTPathAppend.cpp \
     988        common/path/RTPathAppendEx.cpp \
    986989        common/path/RTPathExt.cpp \
    987990        common/path/RTPathFilename.cpp \
     
    14571460        common/path/RTPathAbsExDup.cpp \
    14581461        common/path/RTPathAppend.cpp \
     1462        common/path/RTPathAppendEx.cpp \
    14591463        common/path/RTPathExt.cpp \
    14601464        common/path/RTPathFilename.cpp \
  • trunk/src/VBox/Runtime/common/path/RTPathAppend.cpp

    r30320 r34214  
    3232#include <iprt/path.h>
    3333
    34 #include <iprt/assert.h>
    35 #include <iprt/ctype.h>
    36 #include <iprt/err.h>
    3734#include <iprt/string.h>
    38 
    39 
    40 /**
    41  * Figures the length of the root part of the path.
    42  *
    43  * @returns length of the root specifier.
    44  * @retval  0 if none.
    45  *
    46  * @param   pszPath         The path to investigate.
    47  *
    48  * @remarks Unnecessary root slashes will not be counted. The caller will have
    49  *          to deal with it where it matters.  (Unlike rtPathRootSpecLen which
    50  *          counts them.)
    51  */
    52 static size_t rtPathRootSpecLen2(const char *pszPath)
    53 {
    54     /* fend of wildlife. */
    55     if (!pszPath)
    56         return 0;
    57 
    58     /* Root slash? */
    59     if (RTPATH_IS_SLASH(pszPath[0]))
    60     {
    61 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
    62         /* UNC? */
    63         if (    RTPATH_IS_SLASH(pszPath[1])
    64             &&  pszPath[2] != '\0'
    65             &&  !RTPATH_IS_SLASH(pszPath[2]))
    66         {
    67             /* Find the end of the server name. */
    68             const char *pszEnd = pszPath + 2;
    69             pszEnd += 2;
    70             while (   *pszEnd != '\0'
    71                    && !RTPATH_IS_SLASH(*pszEnd))
    72                 pszEnd++;
    73             if (RTPATH_IS_SLASH(*pszEnd))
    74             {
    75                 pszEnd++;
    76                 while (RTPATH_IS_SLASH(*pszEnd))
    77                     pszEnd++;
    78 
    79                 /* Find the end of the share name */
    80                 while (   *pszEnd != '\0'
    81                        && !RTPATH_IS_SLASH(*pszEnd))
    82                     pszEnd++;
    83                 if (RTPATH_IS_SLASH(*pszEnd))
    84                     pszEnd++;
    85                 return pszPath - pszEnd;
    86             }
    87         }
    88 #endif
    89         return 1;
    90     }
    91 
    92 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
    93     /* Drive specifier? */
    94     if (   pszPath[0] != '\0'
    95         && pszPath[1] == ':'
    96         && RT_C_IS_ALPHA(pszPath[0]))
    97     {
    98         if (RTPATH_IS_SLASH(pszPath[2]))
    99             return 3;
    100         return 2;
    101     }
    102 #endif
    103     return 0;
    104 }
    10535
    10636
    10737RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend)
    10838{
    109     char *pszPathEnd = RTStrEnd(pszPath, cbPathDst);
    110     AssertReturn(pszPathEnd, VERR_INVALID_PARAMETER);
    111 
    112     /*
    113      * Special cases.
    114      */
    115     if (!pszAppend)
    116         return VINF_SUCCESS;
    117     size_t cchAppend = strlen(pszAppend);
    118     if (!cchAppend)
    119         return VINF_SUCCESS;
    120     if (pszPathEnd == pszPath)
    121     {
    122         if (cchAppend >= cbPathDst)
    123             return VERR_BUFFER_OVERFLOW;
    124         memcpy(pszPath, pszAppend, cchAppend + 1);
    125         return VINF_SUCCESS;
    126     }
    127 
    128     /*
    129      * Balance slashes and check for buffer overflow.
    130      */
    131     bool fAddSlash = false;
    132     if (!RTPATH_IS_SLASH(pszPathEnd[-1]))
    133     {
    134         if (!RTPATH_IS_SLASH(pszAppend[0]))
    135         {
    136 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
    137             if (    (size_t)(pszPathEnd - pszPath) == 2
    138                 &&  pszPath[1] == ':'
    139                 &&  RT_C_IS_ALPHA(pszPath[0]))
    140             {
    141                 if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cbPathDst)
    142                     return VERR_BUFFER_OVERFLOW;
    143             }
    144             else
    145 #endif
    146             {
    147                 if ((size_t)(pszPathEnd - pszPath) + 1 + cchAppend >= cbPathDst)
    148                     return VERR_BUFFER_OVERFLOW;
    149                 *pszPathEnd++ = '/';
    150             }
    151         }
    152         else
    153         {
    154             /* One slash is sufficient at this point. */
    155             while (RTPATH_IS_SLASH(pszAppend[1]))
    156                 pszAppend++, cchAppend--;
    157 
    158             if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cbPathDst)
    159                 return VERR_BUFFER_OVERFLOW;
    160         }
    161     }
    162     else
    163     {
    164         /* No slashes needed in the appended bit. */
    165         while (RTPATH_IS_SLASH(*pszAppend))
    166             pszAppend++, cchAppend--;
    167 
    168         /* In the leading path we can skip unnecessary trailing slashes, but
    169            be sure to leave one. */
    170         size_t const cchRoot = rtPathRootSpecLen2(pszPath);
    171         while (     (size_t)(pszPathEnd - pszPath) > RT_MAX(1, cchRoot)
    172                &&   RTPATH_IS_SLASH(pszPathEnd[-2]))
    173             pszPathEnd--;
    174 
    175         if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cbPathDst)
    176             return VERR_BUFFER_OVERFLOW;
    177     }
    178 
    179     /*
    180      * What remains now is the just the copying.
    181      */
    182     memcpy(pszPathEnd, pszAppend, cchAppend + 1);
    183     return VINF_SUCCESS;
     39    return RTPathAppendEx(pszPath, cbPathDst, pszAppend, RTSTR_MAX);
    18440}
    18541
  • trunk/src/VBox/Runtime/common/path/RTPathAppendEx.cpp

    r34201 r34214  
    11/* $Id$ */
    22/** @file
    3  * IPRT - RTPathAppend
     3 * IPRT - RTPathAppendEx
    44 */
    55
    66/*
    7  * Copyright (C) 2009 Oracle Corporation
     7 * Copyright (C) 2009-2010 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    105105
    106106
    107 RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend)
     107RTDECL(int) RTPathAppendEx(char *pszPath, size_t cbPathDst, const char *pszAppend, size_t cchAppendMax)
    108108{
    109109    char *pszPathEnd = RTStrEnd(pszPath, cbPathDst);
     
    115115    if (!pszAppend)
    116116        return VINF_SUCCESS;
    117     size_t cchAppend = strlen(pszAppend);
     117    size_t cchAppend = RTStrNLen(pszAppend, cchAppendMax);
    118118    if (!cchAppend)
    119119        return VINF_SUCCESS;
     
    122122        if (cchAppend >= cbPathDst)
    123123            return VERR_BUFFER_OVERFLOW;
    124         memcpy(pszPath, pszAppend, cchAppend + 1);
     124        memcpy(pszPath, pszAppend, cchAppend);
     125        pszPath[cchAppend] = '\0';
    125126        return VINF_SUCCESS;
    126127    }
     
    153154        {
    154155            /* One slash is sufficient at this point. */
    155             while (RTPATH_IS_SLASH(pszAppend[1]))
     156            while (cchAppend > 1 && RTPATH_IS_SLASH(pszAppend[1]))
    156157                pszAppend++, cchAppend--;
    157158
     
    163164    {
    164165        /* No slashes needed in the appended bit. */
    165         while (RTPATH_IS_SLASH(*pszAppend))
     166        while (cchAppend && RTPATH_IS_SLASH(*pszAppend))
    166167            pszAppend++, cchAppend--;
    167168
     
    180181     * What remains now is the just the copying.
    181182     */
    182     memcpy(pszPathEnd, pszAppend, cchAppend + 1);
     183    memcpy(pszPathEnd, pszAppend, cchAppend);
     184    pszPathEnd[cchAppend] = '\0';
    183185    return VINF_SUCCESS;
    184186}
  • trunk/src/VBox/Runtime/common/path/RTPathJoinEx.cpp

    r34201 r34214  
    11/* $Id$ */
    22/** @file
    3  * IPRT - RTPathJoin.
     3 * IPRT - RTPathJoinEx.
    44 */
    55
     
    3838
    3939
    40 RTDECL(int) RTPathJoin(char *pszPathDst, size_t cbPathDst, const char *pszPathSrc,
    41                        const char *pszAppend)
     40RTDECL(int) RTPathJoinEx(char *pszPathDst, size_t cbPathDst,
     41                         const char *pszPathSrc, size_t cchPathSrcMax,
     42                         const char *pszAppend, size_t cchAppendMax)
    4243{
    4344    AssertPtr(pszPathDst);
     
    4849     * The easy way: Copy the path into the buffer and call RTPathAppend.
    4950     */
    50     size_t cchPathSrc = strlen(pszPathSrc);
     51    size_t cchPathSrc = RTStrNLen(pszPathSrc, cchPathSrcMax);
    5152    if (cchPathSrc >= cbPathDst)
    5253        return VERR_BUFFER_OVERFLOW;
    53     memcpy(pszPathDst, pszPathSrc, cchPathSrc + 1);
     54    memcpy(pszPathDst, pszPathSrc, cchPathSrc);
     55    pszPathDst[cchPathSrc] = '\0';
    5456
    55     return RTPathAppend(pszPathDst, cbPathDst, pszAppend);
     57    return RTPathAppendEx(pszPathDst, cbPathDst, pszAppend, cchAppendMax);
    5658}
    5759
Note: See TracChangeset for help on using the changeset viewer.

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