From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- src/VBox/Runtime/common/string/stringalloc.cpp | 321 +++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 src/VBox/Runtime/common/string/stringalloc.cpp (limited to 'src/VBox/Runtime/common/string/stringalloc.cpp') diff --git a/src/VBox/Runtime/common/string/stringalloc.cpp b/src/VBox/Runtime/common/string/stringalloc.cpp new file mode 100644 index 00000000..921e9bb9 --- /dev/null +++ b/src/VBox/Runtime/common/string/stringalloc.cpp @@ -0,0 +1,321 @@ +/* $Id: stringalloc.cpp $ */ +/** @file + * IPRT - String Manipulation. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include +#include "internal/iprt.h" + +#ifndef IN_RING0 +# include +#endif +#include +#include +#include +#include "internal/string.h" + + + +RTDECL(char *) RTStrAllocTag(size_t cb, const char *pszTag) +{ + char *psz = (char *)RTMemAllocTag(RT_MAX(cb, 1), pszTag); + if (psz) + *psz = '\0'; + return psz; +} +RT_EXPORT_SYMBOL(RTStrAllocTag); + + +RTDECL(int) RTStrAllocExTag(char **ppsz, size_t cb, const char *pszTag) +{ + char *psz = *ppsz = (char *)RTMemAllocTag(RT_MAX(cb, 1), pszTag); + if (psz) + { + *psz = '\0'; + return VINF_SUCCESS; + } + return VERR_NO_STR_MEMORY; +} +RT_EXPORT_SYMBOL(RTStrAllocExTag); + + +RTDECL(int) RTStrReallocTag(char **ppsz, size_t cbNew, const char *pszTag) +{ + char *pszOld = *ppsz; + if (!cbNew) + { + RTMemFree(pszOld); + *ppsz = NULL; + } + else if (pszOld) + { + char *pszNew = (char *)RTMemReallocTag(pszOld, cbNew, pszTag); + if (!pszNew) + return VERR_NO_STR_MEMORY; + pszNew[cbNew - 1] = '\0'; + *ppsz = pszNew; + } + else + { + char *pszNew = (char *)RTMemAllocTag(cbNew, pszTag); + if (!pszNew) + return VERR_NO_STR_MEMORY; + pszNew[0] = '\0'; + pszNew[cbNew - 1] = '\0'; + *ppsz = pszNew; + } + return VINF_SUCCESS; +} +RT_EXPORT_SYMBOL(RTStrReallocTag); + +RTDECL(void) RTStrFree(char *pszString) +{ + if (pszString) + RTMemTmpFree(pszString); +} +RT_EXPORT_SYMBOL(RTStrFree); + + +RTDECL(char *) RTStrDupTag(const char *pszString, const char *pszTag) +{ +#if defined(__cplusplus) + AssertPtr(pszString); +#endif + size_t cch = strlen(pszString) + 1; + char *psz = (char *)RTMemAllocTag(cch, pszTag); + if (psz) + memcpy(psz, pszString, cch); + return psz; +} +RT_EXPORT_SYMBOL(RTStrDupTag); + + +RTDECL(int) RTStrDupExTag(char **ppszCopy, const char *pszString, const char *pszTag) +{ +#if defined(__cplusplus) + AssertPtr(ppszCopy); + AssertPtr(pszString); +#endif + + size_t cch = strlen(pszString); + char *pszDst = (char *)RTMemAllocTag(cch + 1, pszTag); + if (pszDst) + { + memcpy(pszDst, pszString, cch); + pszDst[cch] = '\0'; + *ppszCopy = pszDst; + return VINF_SUCCESS; + } + *ppszCopy = NULL; + return VERR_NO_STR_MEMORY; +} +RT_EXPORT_SYMBOL(RTStrDupExTag); + + +RTDECL(char *) RTStrDupNTag(const char *pszString, size_t cchMax, const char *pszTag) +{ +#if defined(__cplusplus) + AssertPtr(pszString); +#endif + char const *pszEnd = RTStrEnd(pszString, cchMax); + size_t cch = pszEnd ? (uintptr_t)pszEnd - (uintptr_t)pszString : cchMax; + char *pszDst = (char *)RTMemAllocTag(cch + 1, pszTag); + if (pszDst) + { + memcpy(pszDst, pszString, cch); + pszDst[cch] = '\0'; + } + return pszDst; +} +RT_EXPORT_SYMBOL(RTStrDupNTag); + + +RTDECL(int) RTStrDupNExTag(char **ppszCopy, const char *pszString, size_t cchMax, const char *pszTag) +{ +#if defined(__cplusplus) + AssertPtr(pszString); +#endif + char const *pszEnd = RTStrEnd(pszString, cchMax); + size_t cch = pszEnd ? (uintptr_t)pszEnd - (uintptr_t)pszString : cchMax; + char *pszDst = (char *)RTMemAllocTag(cch + 1, pszTag); + if (pszDst) + { + memcpy(pszDst, pszString, cch); + pszDst[cch] = '\0'; + *ppszCopy = pszDst; + return VINF_SUCCESS; + } + *ppszCopy = NULL; + return VERR_NO_STR_MEMORY; +} +RT_EXPORT_SYMBOL(RTStrDupNExTag); + + +RTDECL(int) RTStrAAppendTag(char **ppsz, const char *pszAppend, const char *pszTag) +{ + if (!pszAppend) + return VINF_SUCCESS; + return RTStrAAppendNTag(ppsz, pszAppend, RTSTR_MAX, pszTag); +} + + +RTDECL(int) RTStrAAppendNTag(char **ppsz, const char *pszAppend, size_t cchAppend, const char *pszTag) +{ + size_t cchOrg; + char *pszNew; + + if (!cchAppend) + return VINF_SUCCESS; + if (cchAppend == RTSTR_MAX) + cchAppend = strlen(pszAppend); + else + Assert(cchAppend == RTStrNLen(pszAppend, cchAppend)); + + cchOrg = *ppsz ? strlen(*ppsz) : 0; + pszNew = (char *)RTMemReallocTag(*ppsz, cchOrg + cchAppend + 1, pszTag); + if (!pszNew) + return VERR_NO_STR_MEMORY; + + memcpy(&pszNew[cchOrg], pszAppend, cchAppend); + pszNew[cchOrg + cchAppend] = '\0'; + + *ppsz = pszNew; + return VINF_SUCCESS; +} + + +#if !defined(IN_RING0) && !defined(IPRT_NO_ALLOCA_TROUBLE) + +/* XXX Currently not needed anywhere. alloca() induces some linker problems for ring 0 code + * with newer versions of VCC */ + +RTDECL(int) RTStrAAppendExNVTag(char **ppsz, size_t cPairs, va_list va, const char *pszTag) +{ + AssertPtr(ppsz); + if (!cPairs) + return VINF_SUCCESS; + + /* + * Determine the length of each string and calc the new total. + */ + struct RTStrAAppendExNVStruct + { + const char *psz; + size_t cch; + } *paPairs = (struct RTStrAAppendExNVStruct *)alloca(cPairs * sizeof(*paPairs)); + AssertReturn(paPairs, VERR_NO_STR_MEMORY); + + size_t cchOrg = *ppsz ? strlen(*ppsz) : 0; + size_t cchNewTotal = cchOrg; + for (size_t i = 0; i < cPairs; i++) + { + const char *psz = va_arg(va, const char *); + size_t cch = va_arg(va, size_t); + AssertPtrNull(psz); + Assert(cch == RTSTR_MAX || cch == RTStrNLen(psz, cch)); + + if (cch == RTSTR_MAX) + cch = psz ? strlen(psz) : 0; + cchNewTotal += cch; + + paPairs[i].cch = cch; + paPairs[i].psz = psz; + } + cchNewTotal++; /* '\0' */ + + /* + * Try reallocate the string. + */ + char *pszNew = (char *)RTMemReallocTag(*ppsz, cchNewTotal, pszTag); + if (!pszNew) + return VERR_NO_STR_MEMORY; + + /* + * Do the appending. + */ + size_t off = cchOrg; + for (size_t i = 0; i < cPairs; i++) + { + memcpy(&pszNew[off], paPairs[i].psz, paPairs[i].cch); + off += paPairs[i].cch; + } + Assert(off + 1 == cchNewTotal); + pszNew[off] = '\0'; + + /* done */ + *ppsz = pszNew; + return VINF_SUCCESS; +} +RT_EXPORT_SYMBOL(RTStrAAppendExNVTag); + +#endif + + +RTDECL(int) RTStrATruncateTag(char **ppsz, size_t cchNew, const char *pszTag) +{ + char *pszNew; + char *pszOld = *ppsz; + if (!cchNew) + { + if (pszOld && *pszOld) + { + *pszOld = '\0'; + pszNew = (char *)RTMemReallocTag(pszOld, 1, pszTag); + if (pszNew) + *ppsz = pszNew; + } + } + else + { + char *pszZero; + AssertPtrReturn(pszOld, VERR_OUT_OF_RANGE); + AssertReturn(cchNew < ~(size_t)64, VERR_OUT_OF_RANGE); + pszZero = RTStrEnd(pszOld, cchNew + 63); + AssertReturn(!pszZero || (size_t)(pszZero - pszOld) >= cchNew, VERR_OUT_OF_RANGE); + pszOld[cchNew] = '\0'; + if (!pszZero) + { + pszNew = (char *)RTMemReallocTag(pszOld, cchNew + 1, pszTag); + if (pszNew) + *ppsz = pszNew; + } + } + return VINF_SUCCESS; +} +RT_EXPORT_SYMBOL(RTStrATruncateTag); + -- cgit v1.2.3