VirtualBox

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

Last change on this file since 72426 was 69111, checked in by vboxsync, 7 years ago

(C) year

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