VirtualBox

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

Last change on this file since 21337 was 21337, checked in by vboxsync, 15 years ago

IPRT,HostDrv,AddDrv: Export public IPRT symbols for the linux kernel (pain).

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