VirtualBox

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

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

InnoTek -> innotek: all the headers and comments.

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