VirtualBox

source: vbox/trunk/src/VBox/Main/xml/cfgldrhlp.cpp@ 4071

Last change on this file since 4071 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1/** @file
2 *
3 * CFGLDRHLP - Configuration Loader Helpers
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifdef RT_OS_WINDOWS
19# if _MSC_VER < 1400
20/// @todo Without this I cannot get the stuff to
21// link. I don't know where it should come from.
22// bird: This is probably a __declspec(import) type var; thing. So, using the right
23// compiler options (i.e. template) should cure the problem I guess.
24# include <ctype.h>
25extern "C"
26{
27 int __mb_cur_max = 1;
28 int errno;
29}
30# endif
31#endif /* RT_OS_WINDOWS */
32
33#include "cfgldrhlp.h"
34
35#include <VBox/err.h>
36
37#include <stdio.h>
38#include <ctype.h>
39#include <limits.h>
40
41
42inline unsigned char fromhex(RTUCS2 hexdigit)
43{
44 if (hexdigit >= '0' && hexdigit <= '9')
45 return hexdigit - '0';
46 if (hexdigit >= 'A' && hexdigit <= 'F')
47 return hexdigit - 'A' + 0xA;
48 if (hexdigit >= 'a' && hexdigit <= 'f')
49 return hexdigit - 'a' + 0xa;
50
51 return 0xFF; // error indicator
52}
53
54inline char tohex (unsigned char ch)
55{
56 return (ch < 0xA) ? ch + '0' : ch - 0xA + 'A';
57}
58
59static int _strtouint64 (PRTUCS2 puszValue, uint64_t *pvalue)
60{
61 int rc = VINF_SUCCESS;
62
63 PRTUCS2 p = puszValue;
64
65 // skip leading spaces
66 while (*p <= 0xFF && isspace ((char)*p))
67 {
68 p++;
69 }
70
71 // autodetect base
72 unsigned base = 10;
73
74 if (*p == '0')
75 {
76 p++;
77
78 if (*p == 'x' || *p == 'X')
79 {
80 p++;
81 base = 16;
82 }
83 else
84 {
85 base = 8;
86 }
87 }
88
89 // p points to the first character in the string, start conversion
90 uint64_t value = 0;
91
92 while (*p)
93 {
94 unsigned digit;
95
96 // check the unicode character to be within ASCII range
97 if (*p > 0x7F)
98 {
99 rc = VERR_CFG_INVALID_FORMAT;
100 break;
101 }
102
103 if (isdigit ((char)*p))
104 {
105 digit = *p - '0';
106 }
107 else if ('a' <= *p && *p <= 'f')
108 {
109 digit = *p - 'a' + 0xA;
110 }
111 else if ('A' <= *p && *p <= 'F')
112 {
113 digit = *p - 'F' + 0xA;
114 }
115 else
116 {
117 rc = VERR_CFG_INVALID_FORMAT;
118 break;
119 }
120
121 if (digit >= base)
122 {
123 rc = VERR_CFG_INVALID_FORMAT;
124 break;
125 }
126
127 /// @todo overflow check
128 value = value * base + digit;
129
130 p++;
131 }
132
133 if (VBOX_SUCCESS(rc))
134 {
135 *pvalue = value;
136 }
137
138 return rc;
139}
140
141static int _uint64tostr (uint64_t ullValue, char *pszValue, unsigned base)
142{
143 int rc = VINF_SUCCESS;
144
145 char *p = pszValue;
146
147 if (base == 16)
148 {
149 *p++ = '0';
150 *p++ = 'x';
151 }
152
153 // remember start of the digit string
154 char *s = p;
155
156 for (;;)
157 {
158 unsigned digit = (unsigned)ullValue % base;
159
160 if (base == 16)
161 {
162 *p++ = tohex (digit);
163 }
164 else
165 {
166 *p++ = digit + '0';
167 }
168
169 ullValue /= base;
170
171 if (ullValue == 0)
172 {
173 break;
174 }
175 }
176
177 *p = 0;
178
179 // reverse the resulting string
180 p--; // skip trailing nul
181
182 while (s < p)
183 {
184 char tmp = *s;
185 *s++ = *p;
186 *p-- = tmp;
187 }
188
189 return rc;
190}
191
192int cfgldrhlp_strtouint32 (PRTUCS2 puszValue, uint32_t *pvalue)
193{
194 uint64_t intermediate;
195
196 int rc = _strtouint64 (puszValue, &intermediate);
197
198 if (VBOX_SUCCESS(rc))
199 {
200 if (intermediate > (uint64_t)ULONG_MAX)
201 {
202 rc = VERR_CFG_INVALID_FORMAT;
203 }
204 else
205 {
206 *pvalue = (uint32_t)intermediate;
207 }
208 }
209
210 return rc;
211}
212
213int cfgldrhlp_strtouint64 (PRTUCS2 puszValue, uint64_t *pvalue)
214{
215 return _strtouint64 (puszValue, pvalue);
216}
217
218int cfgldrhlp_uint32tostr (uint32_t ulValue, char *pszValue)
219{
220 return _uint64tostr (ulValue, pszValue, 10);
221}
222
223// Note: 64 bit values are converted to hex notation
224int cfgldrhlp_uint64tostr (uint64_t ullValue, char *pszValue)
225{
226 return _uint64tostr (ullValue, pszValue, 16);
227}
228
229// converts a string of hex digits to memory bytes
230int cfgldrhlp_strtobin (PCRTUCS2 puszValue, void *pvValue, unsigned cbValue, unsigned *pcbValue)
231{
232 int rc = VINF_SUCCESS;
233
234 unsigned count = 0; // number of bytes those can be converted successfully from the puszValue
235 unsigned char *dst = (unsigned char *)pvValue;
236
237 while (*puszValue)
238 {
239 unsigned char b = fromhex (*puszValue);
240
241 if (b == 0xFF)
242 {
243 // it was not a valid hex digit
244 rc = VERR_CFG_INVALID_FORMAT;
245 break;
246 }
247
248 if (count < cbValue)
249 {
250 *dst = b;
251 }
252
253 puszValue++;
254
255 if (!*puszValue)
256 {
257 rc = VERR_CFG_INVALID_FORMAT;
258 break;
259 }
260
261 b = fromhex (*puszValue++);
262
263 if (b == 0xFF)
264 {
265 // it was not a valid hex digit
266 rc = VERR_CFG_INVALID_FORMAT;
267 break;
268 }
269
270 if (count < cbValue)
271 {
272 *dst = ((*dst) << 4) + b;
273 dst++;
274 }
275
276 count++;
277 }
278
279 *pcbValue = count;
280
281 return rc;
282}
283
284// convert memory bytes to UTF8 nul terminated string of hex values
285int cfgldrhlp_bintostr (const void *pvValue, unsigned cbValue, char **ppszValue)
286{
287 int rc = VINF_SUCCESS;
288
289 // each byte will produce two hex digits and there will be nul terminator
290 char *pszValue = (char *)RTMemTmpAlloc (cbValue * 2 + 1);
291
292 if (!pszValue)
293 {
294 rc = VERR_NO_MEMORY;
295 }
296 else
297 {
298 unsigned i = 0;
299 unsigned char *src = (unsigned char *)pvValue;
300 char *dst = pszValue;
301
302 for (; i < cbValue; i++, src++)
303 {
304 *dst++ = tohex((*src) >> 4);
305 *dst++ = tohex((*src) & 0xF);
306 }
307
308 *dst = 0;
309
310 *ppszValue = pszValue;
311 }
312
313 return rc;
314}
315
316// releases memory buffer previously allocated by cfgldrhlp_bintostr
317void cfgldrhlp_releasestr (char *pszValue)
318{
319 if (pszValue)
320 {
321 RTMemTmpFree (pszValue);
322 }
323}
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