VirtualBox

source: vbox/trunk/include/iprt/cpp/path.h@ 78100

Last change on this file since 78100 was 78100, checked in by vboxsync, 6 years ago

iprt/cpp/path.h: Added RTPathAbsExCxx wrappers and made the existing RTPathAbCxx ones use RTPathAbsEx and handle stuff larger than RTPATH_MAX. Untested. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/** @file
2 * IPRT - C++ path utilities.
3 */
4
5/*
6 * Copyright (C) 2017-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_cpp_path_h
27#define IPRT_INCLUDED_cpp_path_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/assert.h>
33#include <iprt/errcore.h>
34#include <iprt/path.h>
35#include <iprt/cpp/ministring.h>
36
37
38/** @defgroup grp_rt_cpp_path C++ Path Utilities
39 * @ingroup grp_rt_cpp
40 * @{
41 */
42
43/**
44 * RTPathAbs() wrapper for working directly on a RTCString instance.
45 *
46 * @returns IPRT status code.
47 * @param rStrAbs Reference to the destination string.
48 * @param pszRelative The relative source string.
49 */
50DECLINLINE(int) RTPathAbsCxx(RTCString &rStrAbs, const char *pszRelative)
51{
52 Assert(rStrAbs.c_str() != pszRelative);
53 int rc = rStrAbs.reserveNoThrow(RTPATH_MAX);
54 if (RT_SUCCESS(rc))
55 {
56 unsigned cTries = 8;
57 for (;;)
58 {
59 char *pszDst = rStrAbs.mutableRaw();
60 size_t cbCap = rStrAbs.capacity();
61 rc = RTPathAbsEx(NULL, pszRelative, RTPATH_STR_F_STYLE_HOST, pszDst, &cbCap);
62 if (RT_SUCCESS(rc))
63 break;
64 *pszDst = '\0';
65 if (rc != VERR_BUFFER_OVERFLOW)
66 break;
67 if (--cTries == 0)
68 break;
69 rc = rStrAbs.reserveNoThrow(RT_MIN(RT_ALIGN_Z(cbCap, 64), RTPATH_MAX));
70 if (RT_FAILURE(rc))
71 break;
72 }
73 rStrAbs.jolt();
74 }
75 return rc;
76}
77
78
79/**
80 * RTPathAbs() wrapper for working directly on a RTCString instance.
81 *
82 * @returns IPRT status code.
83 * @param rStrAbs Reference to the destination string.
84 * @param rStrRelative Reference to the relative source string.
85 */
86DECLINLINE(int) RTPathAbsCxx(RTCString &rStrAbs, RTCString const &rStrRelative)
87{
88 return RTPathAbsCxx(rStrAbs, rStrRelative.c_str());
89}
90
91
92
93/**
94 * RTPathAbsEx() wrapper for working directly on a RTCString instance.
95 *
96 * @returns IPRT status code.
97 * @param rStrAbs Reference to the destination string.
98 * @param pszBase The base path, optional.
99 * @param pszRelative The relative source string.
100 * @param fFlags RTPATH_STR_F_STYLE_XXX and RTPATHABS_F_XXX flags.
101 */
102DECLINLINE(int) RTPathAbsExCxx(RTCString &rStrAbs, const char *pszBase, const char *pszRelative, uint32_t fFlags = RTPATH_STR_F_STYLE_HOST)
103{
104 Assert(rStrAbs.c_str() != pszRelative);
105 int rc = rStrAbs.reserveNoThrow(RTPATH_MAX);
106 if (RT_SUCCESS(rc))
107 {
108 unsigned cTries = 8;
109 for (;;)
110 {
111 char *pszDst = rStrAbs.mutableRaw();
112 size_t cbCap = rStrAbs.capacity();
113 rc = RTPathAbsEx(pszBase, pszRelative, fFlags, pszDst, &cbCap);
114 if (RT_SUCCESS(rc))
115 break;
116 *pszDst = '\0';
117 if (rc != VERR_BUFFER_OVERFLOW)
118 break;
119 if (--cTries == 0)
120 break;
121 rc = rStrAbs.reserveNoThrow(RT_MIN(RT_ALIGN_Z(cbCap, 64), RTPATH_MAX));
122 if (RT_FAILURE(rc))
123 break;
124 }
125 rStrAbs.jolt();
126 }
127 return rc;
128}
129
130
131DECLINLINE(int) RTPathAbsExCxx(RTCString &rStrAbs, RTCString const &rStrBase, RTCString const &rStrRelative, uint32_t fFlags = RTPATH_STR_F_STYLE_HOST)
132{
133 return RTPathAbsExCxx(rStrAbs, rStrBase.c_str(), rStrRelative.c_str(), fFlags);
134}
135
136
137DECLINLINE(int) RTPathAbsExCxx(RTCString &rStrAbs, const char *pszBase, RTCString const &rStrRelative, uint32_t fFlags = RTPATH_STR_F_STYLE_HOST)
138{
139 return RTPathAbsExCxx(rStrAbs, pszBase, rStrRelative.c_str(), fFlags);
140}
141
142
143DECLINLINE(int) RTPathAbsExCxx(RTCString &rStrAbs, RTCString const &rStrBase, const char *pszRelative, uint32_t fFlags = RTPATH_STR_F_STYLE_HOST)
144{
145 return RTPathAbsExCxx(rStrAbs, rStrBase.c_str(), pszRelative, fFlags);
146}
147
148
149
150/**
151 * RTPathAppPrivateNoArch() wrapper for working directly on a RTCString instance.
152 *
153 * @returns IPRT status code.
154 * @param rStrDst Reference to the destination string.
155 */
156DECLINLINE(int) RTPathAppPrivateNoArchCxx(RTCString &rStrDst)
157{
158 int rc = rStrDst.reserveNoThrow(RTPATH_MAX);
159 if (RT_SUCCESS(rc))
160 {
161 char *pszDst = rStrDst.mutableRaw();
162 rc = RTPathAppPrivateNoArch(pszDst, rStrDst.capacity());
163 if (RT_FAILURE(rc))
164 *pszDst = '\0';
165 rStrDst.jolt();
166 }
167 return rc;
168
169}
170
171
172/**
173 * RTPathAppend() wrapper for working directly on a RTCString instance.
174 *
175 * @returns IPRT status code.
176 * @param rStrDst Reference to the destination string.
177 * @param pszAppend One or more components to append to the path already
178 * present in @a rStrDst.
179 */
180DECLINLINE(int) RTPathAppendCxx(RTCString &rStrDst, const char *pszAppend)
181{
182 Assert(rStrDst.c_str() != pszAppend);
183 size_t cbEstimate = rStrDst.length() + 1 + strlen(pszAppend) + 1;
184 int rc;
185 if (rStrDst.capacity() >= cbEstimate)
186 rc = VINF_SUCCESS;
187 else
188 rc = rStrDst.reserveNoThrow(RT_ALIGN_Z(cbEstimate, 8));
189 if (RT_SUCCESS(rc))
190 {
191 rc = RTPathAppend(rStrDst.mutableRaw(), rStrDst.capacity(), pszAppend);
192 if (rc == VERR_BUFFER_OVERFLOW)
193 {
194 rc = rStrDst.reserveNoThrow(RTPATH_MAX);
195 if (RT_SUCCESS(rc))
196 rc = RTPathAppend(rStrDst.mutableRaw(), rStrDst.capacity(), pszAppend);
197 }
198 rStrDst.jolt();
199 }
200 return rc;
201}
202
203
204/**
205 * RTPathAppend() wrapper for working directly on a RTCString instance.
206 *
207 * @returns IPRT status code.
208 * @param rStrDst Reference to the destination string.
209 * @param rStrAppend One or more components to append to the path already
210 * present in @a rStrDst.
211 */
212DECLINLINE(int) RTPathAppendCxx(RTCString &rStrDst, RTCString const &rStrAppend)
213{
214 Assert(&rStrDst != &rStrAppend);
215 size_t cbEstimate = rStrDst.length() + 1 + rStrAppend.length() + 1;
216 int rc;
217 if (rStrDst.capacity() >= cbEstimate)
218 rc = VINF_SUCCESS;
219 else
220 rc = rStrDst.reserveNoThrow(RT_ALIGN_Z(cbEstimate, 8));
221 if (RT_SUCCESS(rc))
222 {
223 rc = RTPathAppend(rStrDst.mutableRaw(), rStrDst.capacity(), rStrAppend.c_str());
224 if (rc == VERR_BUFFER_OVERFLOW)
225 {
226 rc = rStrDst.reserveNoThrow(RTPATH_MAX);
227 if (RT_SUCCESS(rc))
228 rc = RTPathAppend(rStrDst.mutableRaw(), rStrDst.capacity(), rStrAppend.c_str());
229 }
230 rStrDst.jolt();
231 }
232 return rc;
233}
234
235
236/** @} */
237
238#endif /* !IPRT_INCLUDED_cpp_path_h */
239
Note: See TracBrowser for help on using the repository browser.

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