VirtualBox

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

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

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.1 KB
Line 
1/* $Id: RTFileModeToFlags.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT - RTFileModeToFlags.
4 */
5
6/*
7 * Copyright (C) 2013-2019 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 '+':
223 {
224 switch (chPrev)
225 {
226 case 'w':
227 /* Also use read access in write mode. */
228 fMode |= RTFILE_O_READ;
229 break;
230
231 case 'r':
232 /* Also use write access in read mode. */
233 fMode |= RTFILE_O_WRITE;
234 break;
235
236 case 'b':
237 case 't':
238 /* Silently eat skipped parameters. */
239 fSkip = true;
240 break;
241
242 case 0: /* No previous character yet. */
243 case '+':
244 /* Eat plusses which don't belong to a command. */
245 fSkip = true;
246 break;
247
248 default:
249 return VERR_INVALID_PARAMETER;
250 }
251
252 break;
253 }
254
255 default:
256 return VERR_INVALID_PARAMETER;
257 }
258
259 if (!fSkip)
260 chPrev = *pszCur;
261 pszCur++;
262 }
263
264 /*
265 * Handle disposition.
266 */
267 pszCur = pszDisposition;
268
269 /* Create a new file, always, overwrite an existing file. */
270 if ( !RTStrCmp(pszCur, "ca")
271 || !RTStrCmp(pszCur, "create-replace"))
272 fMode |= RTFILE_O_CREATE_REPLACE;
273 /* Create a new file if it does not exist, fail if exist. */
274 else if ( !RTStrCmp(pszCur, "ce")
275 || !RTStrCmp(pszCur, "create"))
276 fMode |= RTFILE_O_CREATE;
277 /* Open existing file, create file if does not exist. */
278 else if ( !RTStrCmp(pszCur, "oc")
279 || !RTStrCmp(pszCur, "open-create"))
280 fMode |= RTFILE_O_OPEN_CREATE;
281 /* Open existing file and place the file pointer at
282 * the end of the file, if opened with write access.
283 * Create the file if does not exist. */
284 else if ( !RTStrCmp(pszCur, "oa")
285 || !RTStrCmp(pszCur, "open-append"))
286 fMode |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND;
287 /* Open existing, fail if does not exist. */
288 else if ( !RTStrCmp(pszCur, "oe")
289 || !RTStrCmp(pszCur, "open"))
290 fMode |= RTFILE_O_OPEN;
291 /* Open and truncate existing, fail of not exist. */
292 else if ( !RTStrCmp(pszCur, "ot")
293 || !RTStrCmp(pszCur, "open-truncate"))
294 fMode |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
295 else
296 return VERR_INVALID_PARAMETER;
297
298 /* No action mask set? */
299 if ((fMode & RTFILE_O_ACTION_MASK) == 0)
300 return VERR_INVALID_PARAMETER;
301
302 /*
303 * Sharing mode.
304 */
305 if (!pszSharing || !*pszSharing)
306 fMode |= RTFILE_O_DENY_NONE;
307 else
308 {
309 do
310 {
311 if (pszSharing[0] == 'n')
312 {
313 if (pszSharing[1] == 'r') /* nr (no other readers) */
314 {
315 if (pszSharing[2] == 'w') /* nrw (no other readers or writers) */
316 {
317 fMode |= RTFILE_O_DENY_READWRITE;
318 pszSharing += 3;
319 }
320 else
321 {
322 fMode |= RTFILE_O_DENY_READ;
323 pszSharing += 2;
324 }
325 }
326 else if (pszSharing[1] == 'w') /* nw (no other writers) */
327 {
328 fMode |= RTFILE_O_DENY_WRITE;
329 pszSharing += 2;
330 }
331 else
332 return VERR_INVALID_PARAMETER;
333 }
334 else if (pszSharing[0] == 'd') /* d (don't deny delete) */
335 {
336 fMode |= RTFILE_O_DENY_WRITE;
337 pszSharing++;
338 }
339 else
340 return VERR_INVALID_PARAMETER;
341 } while (*pszSharing != '\0');
342 }
343
344 /* Return. */
345 *pfMode = fMode;
346 return VINF_SUCCESS;
347}
348RT_EXPORT_SYMBOL(RTFileModeToFlagsEx);
349
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