VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/misc/RTFileModeToFlags.cpp@ 87182

Last change on this file since 87182 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/* $Id: RTFileModeToFlags.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * IPRT - RTFileModeToFlags.
4 */
5
6/*
7 * Copyright (C) 2013-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/assert.h>
32#include <iprt/errcore.h>
33#include <iprt/file.h>
34#include <iprt/string.h>
35#include "internal/iprt.h"
36
37
38RTR3DECL(int) RTFileModeToFlags(const char *pszMode, uint64_t *pfMode)
39{
40 AssertPtrReturn(pszMode, VERR_INVALID_POINTER);
41 AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
42
43 const char *pszCur = pszMode;
44 if (*pszCur == '\0')
45 return VERR_INVALID_PARAMETER;
46
47 uint64_t fMode = 0;
48 char chPrev = '\0';
49 while ( pszCur
50 && *pszCur != '\0')
51 {
52 bool fSkip = false;
53 switch (*pszCur)
54 {
55 /* Opens an existing file for writing and places the
56 * file pointer at the end of the file. The file is
57 * created if it does not exist. */
58 case 'a':
59 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
60 fMode |= RTFILE_O_OPEN_CREATE
61 | RTFILE_O_WRITE
62 | RTFILE_O_APPEND;
63 else
64 return VERR_INVALID_PARAMETER;
65 break;
66
67 case 'b': /* Binary mode. */
68 /* Just skip as being valid. */
69 fSkip = true;
70 break;
71
72 /* Creates a file or open an existing one for
73 * writing only. The file pointer will be placed
74 * at the beginning of the file.*/
75 case 'c':
76 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
77 fMode |= RTFILE_O_OPEN_CREATE
78 | RTFILE_O_WRITE;
79 else
80 return VERR_INVALID_PARAMETER;
81 break;
82
83 /* Opens an existing file for reading and places the
84 * file pointer at the beginning of the file. If the
85 * file does not exist an error will be returned. */
86 case 'r':
87 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
88 fMode |= RTFILE_O_OPEN
89 | RTFILE_O_READ;
90 else
91 return VERR_INVALID_PARAMETER;
92 break;
93
94 case 't': /* Text mode. */
95 /* Just skip as being valid. */
96 fSkip = true;
97 break;
98
99 /* Creates a new file or replaces an existing one
100 * for writing. Places the file pointer at the beginning.
101 * An existing file will be truncated to 0 bytes. */
102 case 'w':
103 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
104 fMode |= RTFILE_O_CREATE_REPLACE
105 | RTFILE_O_WRITE
106 | RTFILE_O_TRUNCATE;
107 else
108 return VERR_INVALID_PARAMETER;
109 break;
110
111 /* Creates a new file and opens it for writing. Places
112 * the file pointer at the beginning. If the file
113 * exists an error will be returned. */
114 case 'x':
115 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
116 fMode |= RTFILE_O_CREATE
117 | RTFILE_O_WRITE;
118 else
119 return VERR_INVALID_PARAMETER;
120 break;
121
122 case '+':
123 {
124 switch (chPrev)
125 {
126 case 'a':
127 case 'c':
128 case 'w':
129 case 'x':
130 /* Also open / create file with read access. */
131 fMode |= RTFILE_O_READ;
132 break;
133
134 case 'r':
135 /* Also open / create file with write access. */
136 fMode |= RTFILE_O_WRITE;
137 break;
138
139 case 'b':
140 case 't':
141 /* Silently eat skipped parameters. */
142 fSkip = true;
143 break;
144
145 case 0: /* No previous character yet. */
146 case '+':
147 /* Eat plusses which don't belong to a command. */
148 fSkip = true;
149 break;
150
151 default:
152 return VERR_INVALID_PARAMETER;
153 }
154
155 break;
156 }
157
158 default:
159 return VERR_INVALID_PARAMETER;
160 }
161
162 if (!fSkip)
163 chPrev = *pszCur;
164 pszCur++;
165 }
166
167 /* No action mask set? */
168 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
169 return VERR_INVALID_PARAMETER;
170
171 /** @todo Handle sharing mode */
172 fMode |= RTFILE_O_DENY_NONE;
173
174 /* Return. */
175 *pfMode = fMode;
176 return VINF_SUCCESS;
177}
178RT_EXPORT_SYMBOL(RTFileModeToFlags);
179
180
181RTR3DECL(int) RTFileModeToFlagsEx(const char *pszAccess, const char *pszDisposition,
182 const char *pszSharing, uint64_t *pfMode)
183{
184 AssertPtrReturn(pszAccess, VERR_INVALID_POINTER);
185 AssertPtrReturn(pszDisposition, VERR_INVALID_POINTER);
186 AssertPtrNullReturn(pszSharing, VERR_INVALID_POINTER);
187 AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
188
189 const char *pszCur = pszAccess;
190 if (*pszCur == '\0')
191 return VERR_INVALID_PARAMETER;
192
193 /*
194 * Handle access mode.
195 */
196 uint64_t fMode = 0;
197 char chPrev = '\0';
198 while ( pszCur
199 && *pszCur != '\0')
200 {
201 bool fSkip = false;
202 switch (*pszCur)
203 {
204 case 'b': /* Binary mode. */
205 /* Just skip as being valid. */
206 fSkip = true;
207 break;
208
209 case 'r': /* Read. */
210 fMode |= RTFILE_O_READ;
211 break;
212
213 case 't': /* Text mode. */
214 /* Just skip as being valid. */
215 fSkip = true;
216 break;
217
218 case 'w': /* Write. */
219 fMode |= RTFILE_O_WRITE;
220 break;
221
222 case 'a': /* Append. */
223 fMode |= RTFILE_O_WRITE | RTFILE_O_APPEND;
224 break;
225
226 case '+':
227 {
228 switch (chPrev)
229 {
230 case 'w':
231 case 'a':
232 /* Also use read access in write mode. */
233 fMode |= RTFILE_O_READ;
234 break;
235
236 case 'r':
237 /* Also use write access in read mode. */
238 fMode |= RTFILE_O_WRITE;
239 break;
240
241 case 'b':
242 case 't':
243 /* Silently eat skipped parameters. */
244 fSkip = true;
245 break;
246
247 case 0: /* No previous character yet. */
248 case '+':
249 /* Eat plusses which don't belong to a command. */
250 fSkip = true;
251 break;
252
253 default:
254 return VERR_INVALID_PARAMETER;
255 }
256
257 break;
258 }
259
260 default:
261 return VERR_INVALID_PARAMETER;
262 }
263
264 if (!fSkip)
265 chPrev = *pszCur;
266 pszCur++;
267 }
268
269 /*
270 * Handle disposition.
271 */
272 pszCur = pszDisposition;
273
274 /* Create a new file, always, overwrite an existing file. */
275 if ( !RTStrCmp(pszCur, "ca")
276 || !RTStrCmp(pszCur, "create-replace"))
277 fMode |= RTFILE_O_CREATE_REPLACE;
278 /* Create a new file if it does not exist, fail if exist. */
279 else if ( !RTStrCmp(pszCur, "ce")
280 || !RTStrCmp(pszCur, "create"))
281 fMode |= RTFILE_O_CREATE;
282 /* Open existing file, create file if does not exist. */
283 else if ( !RTStrCmp(pszCur, "oc")
284 || !RTStrCmp(pszCur, "open-create"))
285 fMode |= RTFILE_O_OPEN_CREATE;
286 /* Open existing file and place the file pointer at the end of the file, if
287 * opened with write access. Create the file if does not exist.
288 * Note! This mode is ill conceived as the appending is a accesss mode not open disposition. */
289 else if ( !RTStrCmp(pszCur, "oa")
290 || !RTStrCmp(pszCur, "open-append"))
291 fMode |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND;
292 /* Open existing, fail if does not exist. */
293 else if ( !RTStrCmp(pszCur, "oe")
294 || !RTStrCmp(pszCur, "open"))
295 fMode |= RTFILE_O_OPEN;
296 /* Open and truncate existing, fail of not exist. */
297 else if ( !RTStrCmp(pszCur, "ot")
298 || !RTStrCmp(pszCur, "open-truncate"))
299 fMode |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
300 else
301 return VERR_INVALID_PARAMETER;
302
303 /* No action mask set? */
304 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
305 return VERR_INVALID_PARAMETER;
306
307 /*
308 * Sharing mode.
309 */
310 if (!pszSharing || !*pszSharing)
311 fMode |= RTFILE_O_DENY_NONE;
312 else
313 {
314 do
315 {
316 if (pszSharing[0] == 'n')
317 {
318 if (pszSharing[1] == 'r') /* nr (no other readers) */
319 {
320 if (pszSharing[2] == 'w') /* nrw (no other readers or writers) */
321 {
322 fMode |= RTFILE_O_DENY_READWRITE;
323 pszSharing += 3;
324 }
325 else
326 {
327 fMode |= RTFILE_O_DENY_READ;
328 pszSharing += 2;
329 }
330 }
331 else if (pszSharing[1] == 'w') /* nw (no other writers) */
332 {
333 fMode |= RTFILE_O_DENY_WRITE;
334 pszSharing += 2;
335 }
336 else
337 return VERR_INVALID_PARAMETER;
338 }
339 else if (pszSharing[0] == 'd') /* d (don't deny delete) */
340 {
341 fMode |= RTFILE_O_DENY_WRITE;
342 pszSharing++;
343 }
344 else
345 return VERR_INVALID_PARAMETER;
346 } while (*pszSharing != '\0');
347 }
348
349 /* Return. */
350 *pfMode = fMode;
351 return VINF_SUCCESS;
352}
353RT_EXPORT_SYMBOL(RTFileModeToFlagsEx);
354
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