VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/strtonum.cpp@ 16383

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

Give VWRN_NUMBER_TOO_BIG highest priority among the warnings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 27.6 KB
Line 
1/* $Id: strtonum.cpp 8279 2008-04-22 12:13:16Z vboxsync $ */
2/** @file
3 * IPRT - String To Number Convertion.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/string.h>
36#include <iprt/err.h>
37
38
39/*******************************************************************************
40* Global Variables *
41*******************************************************************************/
42/** 8-bit char -> digit. */
43static const unsigned char g_auchDigits[256] =
44{
45 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
46 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255,
47 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
48 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
49 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
50 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
51 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
52 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
53};
54/** Approximated overflow shift checks. */
55static const char g_auchShift[36] =
56{
57 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 */
58 64, 64, 63, 63, 62, 62, 62, 62, 61, 61, 61, 61, 61, 61, 61, 61, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 59, 59, 59, 59
59};
60
61/*
62#include <stdio.h>
63int main()
64{
65 int i;
66 printf("static const unsigned char g_auchDigits[256] =\n"
67 "{");
68 for (i = 0; i < 256; i++)
69 {
70 int ch = 255;
71 if (i >= '0' && i <= '9')
72 ch = i - '0';
73 else if (i >= 'a' && i <= 'z')
74 ch = i - 'a' + 10;
75 else if (i >= 'A' && i <= 'Z')
76 ch = i - 'A' + 10;
77 if (i == 0)
78 printf("\n %3d", ch);
79 else if ((i % 32) == 0)
80 printf(",\n %3d", ch);
81 else
82 printf(",%3d", ch);
83 }
84 printf("\n"
85 "};\n");
86 return 0;
87}
88*/
89
90
91
92/**
93 * Converts a string representation of a number to a 64-bit unsigned number.
94 *
95 * @returns iprt status code.
96 * Warnings are used to indicate convertion problems.
97 * @retval VWRN_NUMBER_TOO_BIG
98 * @retval VWRN_NEGATIVE_UNSIGNED
99 * @retval VWRN_TRAILING_CHARS
100 * @retval VWRN_TRAILING_SPACES
101 * @retval VINF_SUCCESS
102 * @retval VERR_NO_DIGITS
103 *
104 * @param pszValue Pointer to the string value.
105 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
106 * @param uBase The base of the representation used.
107 * If the function will look for known prefixes before defaulting to 10.
108 * @param pu64 Where to store the converted number. (optional)
109 */
110RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint64_t *pu64)
111{
112 const char *psz = pszValue;
113 int iShift;
114 int rc;
115 uint64_t u64;
116 unsigned char uch;
117
118 /*
119 * Positive/Negative stuff.
120 */
121 bool fPositive = true;
122 for (;; psz++)
123 {
124 if (*psz == '+')
125 fPositive = true;
126 else if (*psz == '-')
127 fPositive = !fPositive;
128 else
129 break;
130 }
131
132 /*
133 * Check for hex prefix.
134 */
135 if (!uBase)
136 {
137 if ( psz[0] == '0'
138 && (psz[1] == 'x' || psz[1] == 'X')
139 && g_auchDigits[(unsigned char)psz[2]] < 16)
140 {
141 uBase = 16;
142 psz += 2;
143 }
144 else if ( psz[0] == '0'
145 && g_auchDigits[(unsigned char)psz[1]] < 8)
146 {
147 uBase = 8;
148 psz++;
149 }
150 else
151 uBase = 10;
152 }
153 else if ( uBase == 16
154 && psz[0] == '0'
155 && (psz[1] == 'x' || psz[1] == 'X')
156 && g_auchDigits[(unsigned char)psz[2]] < 16)
157 psz += 2;
158
159 /*
160 * Interpret the value.
161 * Note: We only support ascii digits at this time... :-)
162 */
163 iShift = g_auchShift[uBase];
164 pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
165 rc = VINF_SUCCESS;
166 u64 = 0;
167 while ((uch = (unsigned char)*psz) != 0)
168 {
169 unsigned char chDigit = g_auchDigits[uch];
170 uint64_t u64Prev;
171
172 if (chDigit >= uBase)
173 break;
174
175 u64Prev = u64;
176 u64 *= uBase;
177 u64 += chDigit;
178 if (u64Prev > u64 || (u64Prev >> iShift))
179 rc = VWRN_NUMBER_TOO_BIG;
180 psz++;
181 }
182
183 if (!fPositive)
184 {
185 if (rc == VINF_SUCCESS)
186 rc = VWRN_NEGATIVE_UNSIGNED;
187 u64 = -(int64_t)u64;
188 }
189
190 if (pu64)
191 *pu64 = u64;
192
193 if (psz == pszValue)
194 rc = VERR_NO_DIGITS;
195
196 if (ppszNext)
197 *ppszNext = (char *)psz;
198
199 /*
200 * Warn about trailing chars/spaces.
201 */
202 if ( rc == VINF_SUCCESS
203 && *psz)
204 {
205 while (*psz == ' ' || *psz == '\t')
206 psz++;
207 rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
208 }
209
210 return rc;
211}
212
213
214/**
215 * Converts a string representation of a number to a 64-bit unsigned number,
216 * making sure the full string is converted.
217 *
218 * @returns iprt status code.
219 * Warnings are used to indicate convertion problems.
220 * @retval VWRN_NUMBER_TOO_BIG
221 * @retval VWRN_NEGATIVE_UNSIGNED
222 * @retval VINF_SUCCESS
223 * @retval VERR_NO_DIGITS
224 * @retval VERR_TRAILING_SPACES
225 * @retval VERR_TRAILING_CHARS
226 *
227 * @param pszValue Pointer to the string value.
228 * @param uBase The base of the representation used.
229 * If the function will look for known prefixes before defaulting to 10.
230 * @param pu64 Where to store the converted number. (optional)
231 */
232RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBase, uint64_t *pu64)
233{
234 char *psz;
235 int rc = RTStrToUInt64Ex(pszValue, &psz, uBase, pu64);
236 if (RT_SUCCESS(rc) && *psz)
237 {
238 if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
239 rc = -rc;
240 else
241 {
242 while (*psz == ' ' || *psz == '\t')
243 psz++;
244 rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
245 }
246 }
247 return rc;
248}
249
250
251/**
252 * Converts a string representation of a number to a 64-bit unsigned number.
253 * The base is guessed.
254 *
255 * @returns 64-bit unsigned number on success.
256 * @returns 0 on failure.
257 * @param pszValue Pointer to the string value.
258 */
259RTDECL(uint64_t) RTStrToUInt64(const char *pszValue)
260{
261 uint64_t u64;
262 int rc = RTStrToUInt64Ex(pszValue, NULL, 0, &u64);
263 if (RT_SUCCESS(rc))
264 return u64;
265 return 0;
266}
267
268
269/**
270 * Converts a string representation of a number to a 32-bit unsigned number.
271 *
272 * @returns iprt status code.
273 * Warnings are used to indicate convertion problems.
274 * @retval VWRN_NUMBER_TOO_BIG
275 * @retval VWRN_NEGATIVE_UNSIGNED
276 * @retval VWRN_TRAILING_CHARS
277 * @retval VWRN_TRAILING_SPACES
278 * @retval VINF_SUCCESS
279 * @retval VERR_NO_DIGITS
280 *
281 * @param pszValue Pointer to the string value.
282 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
283 * @param uBase The base of the representation used.
284 * If the function will look for known prefixes before defaulting to 10.
285 * @param pu32 Where to store the converted number. (optional)
286 */
287RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32)
288{
289 uint64_t u64;
290 int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
291 if (RT_SUCCESS(rc))
292 {
293 if (u64 & ~0xffffffffULL)
294 rc = VWRN_NUMBER_TOO_BIG;
295 }
296 if (pu32)
297 *pu32 = (uint32_t)u64;
298 return rc;
299}
300
301
302/**
303 * Converts a string representation of a number to a 32-bit unsigned number,
304 * making sure the full string is converted.
305 *
306 * @returns iprt status code.
307 * Warnings are used to indicate convertion problems.
308 * @retval VWRN_NUMBER_TOO_BIG
309 * @retval VWRN_NEGATIVE_UNSIGNED
310 * @retval VINF_SUCCESS
311 * @retval VERR_NO_DIGITS
312 * @retval VERR_TRAILING_SPACES
313 * @retval VERR_TRAILING_CHARS
314 *
315 * @param pszValue Pointer to the string value.
316 * @param uBase The base of the representation used.
317 * If the function will look for known prefixes before defaulting to 10.
318 * @param pu32 Where to store the converted number. (optional)
319 */
320RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32)
321{
322 uint64_t u64;
323 int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
324 if (RT_SUCCESS(rc))
325 {
326 if (u64 & ~0xffffffffULL)
327 rc = VWRN_NUMBER_TOO_BIG;
328 }
329 if (pu32)
330 *pu32 = (uint32_t)u64;
331 return rc;
332}
333
334
335/**
336 * Converts a string representation of a number to a 64-bit unsigned number.
337 * The base is guessed.
338 *
339 * @returns 32-bit unsigned number on success.
340 * @returns 0 on failure.
341 * @param pszValue Pointer to the string value.
342 */
343RTDECL(uint32_t) RTStrToUInt32(const char *pszValue)
344{
345 uint32_t u32;
346 int rc = RTStrToUInt32Ex(pszValue, NULL, 0, &u32);
347 if (RT_SUCCESS(rc))
348 return u32;
349 return 0;
350}
351
352
353/**
354 * Converts a string representation of a number to a 16-bit unsigned number.
355 *
356 * @returns iprt status code.
357 * Warnings are used to indicate convertion problems.
358 * @retval VWRN_NUMBER_TOO_BIG
359 * @retval VWRN_NEGATIVE_UNSIGNED
360 * @retval VWRN_TRAILING_CHARS
361 * @retval VWRN_TRAILING_SPACES
362 * @retval VINF_SUCCESS
363 * @retval VERR_NO_DIGITS
364 *
365 * @param pszValue Pointer to the string value.
366 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
367 * @param uBase The base of the representation used.
368 * If the function will look for known prefixes before defaulting to 10.
369 * @param pu16 Where to store the converted number. (optional)
370 */
371RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint16_t *pu16)
372{
373 uint64_t u64;
374 int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
375 if (RT_SUCCESS(rc))
376 {
377 if (u64 & ~0xffffULL)
378 rc = VWRN_NUMBER_TOO_BIG;
379 }
380 if (pu16)
381 *pu16 = (uint16_t)u64;
382 return rc;
383}
384
385
386/**
387 * Converts a string representation of a number to a 16-bit unsigned number,
388 * making sure the full string is converted.
389 *
390 * @returns iprt status code.
391 * Warnings are used to indicate convertion problems.
392 * @retval VWRN_NUMBER_TOO_BIG
393 * @retval VWRN_NEGATIVE_UNSIGNED
394 * @retval VINF_SUCCESS
395 * @retval VERR_NO_DIGITS
396 * @retval VERR_TRAILING_SPACES
397 * @retval VERR_TRAILING_CHARS
398 *
399 * @param pszValue Pointer to the string value.
400 * @param uBase The base of the representation used.
401 * If the function will look for known prefixes before defaulting to 10.
402 * @param pu16 Where to store the converted number. (optional)
403 */
404RTDECL(int) RTStrToUInt16Full(const char *pszValue, unsigned uBase, uint16_t *pu16)
405{
406 uint64_t u64;
407 int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
408 if (RT_SUCCESS(rc))
409 {
410 if (u64 & ~0xffffULL)
411 rc = VWRN_NUMBER_TOO_BIG;
412 }
413 if (pu16)
414 *pu16 = (uint16_t)u64;
415 return rc;
416}
417
418
419/**
420 * Converts a string representation of a number to a 16-bit unsigned number.
421 * The base is guessed.
422 *
423 * @returns 16-bit unsigned number on success.
424 * @returns 0 on failure.
425 * @param pszValue Pointer to the string value.
426 */
427RTDECL(uint16_t) RTStrToUInt16(const char *pszValue)
428{
429 uint16_t u16;
430 int rc = RTStrToUInt16Ex(pszValue, NULL, 0, &u16);
431 if (RT_SUCCESS(rc))
432 return u16;
433 return 0;
434}
435
436
437/**
438 * Converts a string representation of a number to a 8-bit unsigned number.
439 *
440 * @returns iprt status code.
441 * Warnings are used to indicate convertion problems.
442 * @retval VWRN_NUMBER_TOO_BIG
443 * @retval VWRN_NEGATIVE_UNSIGNED
444 * @retval VWRN_TRAILING_CHARS
445 * @retval VWRN_TRAILING_SPACES
446 * @retval VINF_SUCCESS
447 * @retval VERR_NO_DIGITS
448 *
449 * @param pszValue Pointer to the string value.
450 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
451 * @param uBase The base of the representation used.
452 * If the function will look for known prefixes before defaulting to 10.
453 * @param pu8 Where to store the converted number. (optional)
454 */
455RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint8_t *pu8)
456{
457 uint64_t u64;
458 int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
459 if (RT_SUCCESS(rc))
460 {
461 if (u64 & ~0xffULL)
462 rc = VWRN_NUMBER_TOO_BIG;
463 }
464 if (pu8)
465 *pu8 = (uint8_t)u64;
466 return rc;
467}
468
469
470/**
471 * Converts a string representation of a number to a 8-bit unsigned number,
472 * making sure the full string is converted.
473 *
474 * @returns iprt status code.
475 * Warnings are used to indicate convertion problems.
476 * @retval VWRN_NUMBER_TOO_BIG
477 * @retval VWRN_NEGATIVE_UNSIGNED
478 * @retval VINF_SUCCESS
479 * @retval VERR_NO_DIGITS
480 * @retval VERR_TRAILING_SPACES
481 * @retval VERR_TRAILING_CHARS
482 *
483 * @param pszValue Pointer to the string value.
484 * @param uBase The base of the representation used.
485 * If the function will look for known prefixes before defaulting to 10.
486 * @param pu8 Where to store the converted number. (optional)
487 */
488RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBase, uint8_t *pu8)
489{
490 uint64_t u64;
491 int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
492 if (RT_SUCCESS(rc))
493 {
494 if (u64 & ~0xffULL)
495 rc = VWRN_NUMBER_TOO_BIG;
496 }
497 if (pu8)
498 *pu8 = (uint8_t)u64;
499 return rc;
500}
501
502
503/**
504 * Converts a string representation of a number to a 8-bit unsigned number.
505 * The base is guessed.
506 *
507 * @returns 8-bit unsigned number on success.
508 * @returns 0 on failure.
509 * @param pszValue Pointer to the string value.
510 */
511RTDECL(uint8_t) RTStrToUInt8(const char *pszValue)
512{
513 uint8_t u8;
514 int rc = RTStrToUInt8Ex(pszValue, NULL, 0, &u8);
515 if (RT_SUCCESS(rc))
516 return u8;
517 return 0;
518}
519
520
521
522
523
524
525
526/**
527 * Converts a string representation of a number to a 64-bit signed number.
528 *
529 * @returns iprt status code.
530 * Warnings are used to indicate convertion problems.
531 * @retval VWRN_NUMBER_TOO_BIG
532 * @retval VWRN_TRAILING_CHARS
533 * @retval VWRN_TRAILING_SPACES
534 * @retval VINF_SUCCESS
535 * @retval VERR_NO_DIGITS
536 *
537 * @param pszValue Pointer to the string value.
538 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
539 * @param uBase The base of the representation used.
540 * If the function will look for known prefixes before defaulting to 10.
541 * @param pi64 Where to store the converted number. (optional)
542 */
543RTDECL(int) RTStrToInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, int64_t *pi64)
544{
545 const char *psz = pszValue;
546 int iShift;
547 int rc;
548 int64_t i64;
549 unsigned char uch;
550
551 /*
552 * Positive/Negative stuff.
553 */
554 bool fPositive = true;
555 for (;; psz++)
556 {
557 if (*psz == '+')
558 fPositive = true;
559 else if (*psz == '-')
560 fPositive = !fPositive;
561 else
562 break;
563 }
564
565 /*
566 * Check for hex prefix.
567 */
568 if (!uBase)
569 {
570 if ( *psz == '0'
571 && (psz[1] == 'x' || psz[1] == 'X')
572 && g_auchDigits[(unsigned char)psz[2]] < 16)
573 {
574 uBase = 16;
575 psz += 2;
576 }
577 else if ( *psz == '0'
578 && g_auchDigits[(unsigned char)psz[1]] < 8)
579 {
580 uBase = 8;
581 psz++;
582 }
583 else
584 uBase = 10;
585 }
586 else if ( uBase == 16
587 && *psz == '0'
588 && (psz[1] == 'x' || psz[1] == 'X')
589 && g_auchDigits[(unsigned char)psz[2]] < 16)
590 psz += 2;
591
592 /*
593 * Interpret the value.
594 * Note: We only support ascii digits at this time... :-)
595 */
596 iShift = g_auchShift[uBase]; /** @todo test this, it's probably not 100% right yet. */
597 pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
598 rc = VINF_SUCCESS;
599 i64 = 0;
600 while ((uch = (unsigned char)*psz) != 0)
601 {
602 unsigned char chDigit = g_auchDigits[uch];
603 int64_t i64Prev;
604
605 if (chDigit >= uBase)
606 break;
607
608 i64Prev = i64;
609 i64 *= uBase;
610 i64 += chDigit;
611 if (i64Prev > i64 || (i64Prev >> iShift))
612 rc = VWRN_NUMBER_TOO_BIG;
613 psz++;
614 }
615
616 if (!fPositive)
617 i64 = -i64;
618
619 if (pi64)
620 *pi64 = i64;
621
622 if (psz == pszValue)
623 rc = VERR_NO_DIGITS;
624
625 if (ppszNext)
626 *ppszNext = (char *)psz;
627
628 /*
629 * Warn about trailing chars/spaces.
630 */
631 if ( rc == VINF_SUCCESS
632 && *psz)
633 {
634 while (*psz == ' ' || *psz == '\t')
635 psz++;
636 rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
637 }
638
639 return rc;
640}
641
642
643/**
644 * Converts a string representation of a number to a 64-bit signed number,
645 * making sure the full string is converted.
646 *
647 * @returns iprt status code.
648 * Warnings are used to indicate convertion problems.
649 * @retval VWRN_NUMBER_TOO_BIG
650 * @retval VINF_SUCCESS
651 * @retval VERR_TRAILING_CHARS
652 * @retval VERR_TRAILING_SPACES
653 * @retval VERR_NO_DIGITS
654 *
655 * @param pszValue Pointer to the string value.
656 * @param uBase The base of the representation used.
657 * If the function will look for known prefixes before defaulting to 10.
658 * @param pi64 Where to store the converted number. (optional)
659 */
660RTDECL(int) RTStrToInt64Full(const char *pszValue, unsigned uBase, int64_t *pi64)
661{
662 char *psz;
663 int rc = RTStrToInt64Ex(pszValue, &psz, uBase, pi64);
664 if (RT_SUCCESS(rc) && *psz)
665 {
666 if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
667 rc = -rc;
668 else
669 {
670 while (*psz == ' ' || *psz == '\t')
671 psz++;
672 rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
673 }
674 }
675 return rc;
676}
677
678
679/**
680 * Converts a string representation of a number to a 64-bit signed number.
681 * The base is guessed.
682 *
683 * @returns 64-bit signed number on success.
684 * @returns 0 on failure.
685 * @param pszValue Pointer to the string value.
686 */
687RTDECL(int64_t) RTStrToInt64(const char *pszValue)
688{
689 int64_t i64;
690 int rc = RTStrToInt64Ex(pszValue, NULL, 0, &i64);
691 if (RT_SUCCESS(rc))
692 return i64;
693 return 0;
694}
695
696
697/**
698 * Converts a string representation of a number to a 32-bit signed number.
699 *
700 * @returns iprt status code.
701 * Warnings are used to indicate convertion problems.
702 * @retval VWRN_NUMBER_TOO_BIG
703 * @retval VWRN_TRAILING_CHARS
704 * @retval VWRN_TRAILING_SPACES
705 * @retval VINF_SUCCESS
706 * @retval VERR_NO_DIGITS
707 *
708 * @param pszValue Pointer to the string value.
709 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
710 * @param uBase The base of the representation used.
711 * If the function will look for known prefixes before defaulting to 10.
712 * @param pi32 Where to store the converted number. (optional)
713 */
714RTDECL(int) RTStrToInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, int32_t *pi32)
715{
716 int64_t i64;
717 int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
718 if (RT_SUCCESS(rc))
719 {
720 int32_t i32 = (int32_t)i64;
721 if (i64 != (int64_t)i32)
722 rc = VWRN_NUMBER_TOO_BIG;
723 }
724 if (pi32)
725 *pi32 = (int32_t)i64;
726 return rc;
727}
728
729
730/**
731 * Converts a string representation of a number to a 32-bit signed number,
732 * making sure the full string is converted.
733 *
734 * @returns iprt status code.
735 * Warnings are used to indicate convertion problems.
736 * @retval VWRN_NUMBER_TOO_BIG
737 * @retval VINF_SUCCESS
738 * @retval VERR_TRAILING_CHARS
739 * @retval VERR_TRAILING_SPACES
740 * @retval VERR_NO_DIGITS
741 *
742 * @param pszValue Pointer to the string value.
743 * @param uBase The base of the representation used.
744 * If the function will look for known prefixes before defaulting to 10.
745 * @param pi32 Where to store the converted number. (optional)
746 */
747RTDECL(int) RTStrToInt32Full(const char *pszValue, unsigned uBase, int32_t *pi32)
748{
749 int64_t i64;
750 int rc = RTStrToInt64Full(pszValue, uBase, &i64);
751 if (RT_SUCCESS(rc))
752 {
753 int32_t i32 = (int32_t)i64;
754 if (i64 != (int64_t)i32)
755 rc = VWRN_NUMBER_TOO_BIG;
756 }
757 if (pi32)
758 *pi32 = (int32_t)i64;
759 return rc;
760}
761
762
763/**
764 * Converts a string representation of a number to a 32-bit signed number.
765 * The base is guessed.
766 *
767 * @returns 32-bit signed number on success.
768 * @returns 0 on failure.
769 * @param pszValue Pointer to the string value.
770 */
771RTDECL(int32_t) RTStrToInt32(const char *pszValue)
772{
773 int32_t i32;
774 int rc = RTStrToInt32Ex(pszValue, NULL, 0, &i32);
775 if (RT_SUCCESS(rc))
776 return i32;
777 return 0;
778}
779
780
781/**
782 * Converts a string representation of a number to a 16-bit signed number.
783 *
784 * @returns iprt status code.
785 * Warnings are used to indicate convertion problems.
786 * @retval VWRN_NUMBER_TOO_BIG
787 * @retval VWRN_TRAILING_CHARS
788 * @retval VWRN_TRAILING_SPACES
789 * @retval VINF_SUCCESS
790 * @retval VERR_NO_DIGITS
791 *
792 * @param pszValue Pointer to the string value.
793 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
794 * @param uBase The base of the representation used.
795 * If the function will look for known prefixes before defaulting to 10.
796 * @param pi16 Where to store the converted number. (optional)
797 */
798RTDECL(int) RTStrToInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, int16_t *pi16)
799{
800 int64_t i64;
801 int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
802 if (RT_SUCCESS(rc))
803 {
804 int16_t i16 = (int16_t)i64;
805 if (i64 != (int64_t)i16)
806 rc = VWRN_NUMBER_TOO_BIG;
807 }
808 if (pi16)
809 *pi16 = (int16_t)i64;
810 return rc;
811}
812
813
814/**
815 * Converts a string representation of a number to a 16-bit signed number,
816 * making sure the full string is converted.
817 *
818 * @returns iprt status code.
819 * Warnings are used to indicate convertion problems.
820 * @retval VWRN_NUMBER_TOO_BIG
821 * @retval VINF_SUCCESS
822 * @retval VERR_TRAILING_CHARS
823 * @retval VERR_TRAILING_SPACES
824 * @retval VERR_NO_DIGITS
825 *
826 * @param pszValue Pointer to the string value.
827 * @param uBase The base of the representation used.
828 * If the function will look for known prefixes before defaulting to 10.
829 * @param pi16 Where to store the converted number. (optional)
830 */
831RTDECL(int) RTStrToInt16Full(const char *pszValue, unsigned uBase, int16_t *pi16)
832{
833 int64_t i64;
834 int rc = RTStrToInt64Full(pszValue, uBase, &i64);
835 if (RT_SUCCESS(rc))
836 {
837 int16_t i16 = (int16_t)i64;
838 if (i64 != (int64_t)i16)
839 rc = VWRN_NUMBER_TOO_BIG;
840 }
841 if (pi16)
842 *pi16 = (int16_t)i64;
843 return rc;
844}
845
846
847/**
848 * Converts a string representation of a number to a 16-bit signed number.
849 * The base is guessed.
850 *
851 * @returns 16-bit signed number on success.
852 * @returns 0 on failure.
853 * @param pszValue Pointer to the string value.
854 */
855RTDECL(int16_t) RTStrToInt16(const char *pszValue)
856{
857 int16_t i16;
858 int rc = RTStrToInt16Ex(pszValue, NULL, 0, &i16);
859 if (RT_SUCCESS(rc))
860 return i16;
861 return 0;
862}
863
864
865/**
866 * Converts a string representation of a number to a 8-bit signed number.
867 *
868 * @returns iprt status code.
869 * Warnings are used to indicate convertion problems.
870 * @retval VWRN_NUMBER_TOO_BIG
871 * @retval VWRN_TRAILING_CHARS
872 * @retval VWRN_TRAILING_SPACES
873 * @retval VINF_SUCCESS
874 * @retval VERR_NO_DIGITS
875 *
876 * @param pszValue Pointer to the string value.
877 * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
878 * @param uBase The base of the representation used.
879 * If the function will look for known prefixes before defaulting to 10.
880 * @param pi8 Where to store the converted number. (optional)
881 */
882RTDECL(int) RTStrToInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, int8_t *pi8)
883{
884 int64_t i64;
885 int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
886 if (RT_SUCCESS(rc))
887 {
888 int8_t i8 = (int8_t)i64;
889 if (i64 != (int64_t)i8)
890 rc = VWRN_NUMBER_TOO_BIG;
891 }
892 if (pi8)
893 *pi8 = (int8_t)i64;
894 return rc;
895}
896
897
898/**
899 * Converts a string representation of a number to a 8-bit signed number,
900 * making sure the full string is converted.
901 *
902 * @returns iprt status code.
903 * Warnings are used to indicate convertion problems.
904 * @retval VWRN_NUMBER_TOO_BIG
905 * @retval VINF_SUCCESS
906 * @retval VERR_TRAILING_CHARS
907 * @retval VERR_TRAILING_SPACES
908 * @retval VERR_NO_DIGITS
909 *
910 * @param pszValue Pointer to the string value.
911 * @param uBase The base of the representation used.
912 * If the function will look for known prefixes before defaulting to 10.
913 * @param pi8 Where to store the converted number. (optional)
914 */
915RTDECL(int) RTStrToInt8Full(const char *pszValue, unsigned uBase, int8_t *pi8)
916{
917 int64_t i64;
918 int rc = RTStrToInt64Full(pszValue, uBase, &i64);
919 if (RT_SUCCESS(rc))
920 {
921 int8_t i8 = (int8_t)i64;
922 if (i64 != (int64_t)i8)
923 rc = VWRN_NUMBER_TOO_BIG;
924 }
925 if (pi8)
926 *pi8 = (int8_t)i64;
927 return rc;
928}
929
930
931/**
932 * Converts a string representation of a number to a 8-bit signed number.
933 * The base is guessed.
934 *
935 * @returns 8-bit signed number on success.
936 * @returns 0 on failure.
937 * @param pszValue Pointer to the string value.
938 */
939RTDECL(int8_t) RTStrToInt8(const char *pszValue)
940{
941 int8_t i8;
942 int rc = RTStrToInt8Ex(pszValue, NULL, 0, &i8);
943 if (RT_SUCCESS(rc))
944 return i8;
945 return 0;
946}
947
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