![]() ![]() |
![]() |
1 mike 1.1 //%2006//////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c, 2 2000, 2001, 2002 BMC Software; Hewlett-Packard Development 4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. 5 // Copyright (c, 2 2003 BMC Software; Hewlett-Packard Development Company, L.P.; 6 // IBM Corp.; EMC Corporation, The Open Group. 7 // Copyright (c, 2 2004 BMC Software; Hewlett-Packard Development Company, L.P.; 8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. 9 // Copyright (c, 2 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; 10 // EMC Corporation; VERITAS Software Corporation; The Open Group. 11 // Copyright (c, 2 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; 12 // EMC Corporation; Symantec Corporation; The Open Group. 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining a copy 15 // of this software and associated documentation files (the "Software", 2, to 16 // deal in the Software without restriction, including without limitation the 17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 18 // sell copies of the Software, and to permit persons to whom the Software is 19 // furnished to do so, subject to the following conditions: 20 // 21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN 22 mike 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED 23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 // 30 //%///////////////////////////////////////////////////////////////////////////// 31 32 #include "StringConversion.h" 33 | ||
34 kumpf 1.3 #include <errno.h> 35 | ||
36 mike 1.1 PEGASUS_NAMESPACE_BEGIN 37 38 struct Uint32ToStringElement 39 { 40 const char* str; 41 size_t size; 42 }; 43 44 static Uint32ToStringElement _Uint32Strings[] = 45 { 46 { "0", 1 }, 47 { "1", 1 }, 48 { "2", 1 }, 49 { "3", 1 }, 50 { "4", 1 }, 51 { "5", 1 }, 52 { "6", 1 }, 53 { "7", 1 }, 54 { "8", 1 }, 55 { "9", 1 }, 56 { "10", 2 }, 57 mike 1.1 { "11", 2 }, 58 { "12", 2 }, 59 { "13", 2 }, 60 { "14", 2 }, 61 { "15", 2 }, 62 { "16", 2 }, 63 { "17", 2 }, 64 { "18", 2 }, 65 { "19", 2 }, 66 { "20", 2 }, 67 { "21", 2 }, 68 { "22", 2 }, 69 { "23", 2 }, 70 { "24", 2 }, 71 { "25", 2 }, 72 { "26", 2 }, 73 { "27", 2 }, 74 { "28", 2 }, 75 { "29", 2 }, 76 { "30", 2 }, 77 { "31", 2 }, 78 mike 1.1 { "32", 2 }, 79 { "33", 2 }, 80 { "34", 2 }, 81 { "35", 2 }, 82 { "36", 2 }, 83 { "37", 2 }, 84 { "38", 2 }, 85 { "39", 2 }, 86 { "40", 2 }, 87 { "41", 2 }, 88 { "42", 2 }, 89 { "43", 2 }, 90 { "44", 2 }, 91 { "45", 2 }, 92 { "46", 2 }, 93 { "47", 2 }, 94 { "48", 2 }, 95 { "49", 2 }, 96 { "50", 2 }, 97 { "51", 2 }, 98 { "52", 2 }, 99 mike 1.1 { "53", 2 }, 100 { "54", 2 }, 101 { "55", 2 }, 102 { "56", 2 }, 103 { "57", 2 }, 104 { "58", 2 }, 105 { "59", 2 }, 106 { "60", 2 }, 107 { "61", 2 }, 108 { "62", 2 }, 109 { "63", 2 }, 110 { "64", 2 }, 111 { "65", 2 }, 112 { "66", 2 }, 113 { "67", 2 }, 114 { "68", 2 }, 115 { "69", 2 }, 116 { "70", 2 }, 117 { "71", 2 }, 118 { "72", 2 }, 119 { "73", 2 }, 120 mike 1.1 { "74", 2 }, 121 { "75", 2 }, 122 { "76", 2 }, 123 { "77", 2 }, 124 { "78", 2 }, 125 { "79", 2 }, 126 { "80", 2 }, 127 { "81", 2 }, 128 { "82", 2 }, 129 { "83", 2 }, 130 { "84", 2 }, 131 { "85", 2 }, 132 { "86", 2 }, 133 { "87", 2 }, 134 { "88", 2 }, 135 { "89", 2 }, 136 { "90", 2 }, 137 { "91", 2 }, 138 { "92", 2 }, 139 { "93", 2 }, 140 { "94", 2 }, 141 mike 1.1 { "95", 2 }, 142 { "96", 2 }, 143 { "97", 2 }, 144 { "98", 2 }, 145 { "99", 2 }, 146 { "100", 3 }, 147 { "101", 3 }, 148 { "102", 3 }, 149 { "103", 3 }, 150 { "104", 3 }, 151 { "105", 3 }, 152 { "106", 3 }, 153 { "107", 3 }, 154 { "108", 3 }, 155 { "109", 3 }, 156 { "110", 3 }, 157 { "111", 3 }, 158 { "112", 3 }, 159 { "113", 3 }, 160 { "114", 3 }, 161 { "115", 3 }, 162 mike 1.1 { "116", 3 }, 163 { "117", 3 }, 164 { "118", 3 }, 165 { "119", 3 }, 166 { "120", 3 }, 167 { "121", 3 }, 168 { "122", 3 }, 169 { "123", 3 }, 170 { "124", 3 }, 171 { "125", 3 }, 172 { "126", 3 }, 173 { "127", 3 }, 174 }; 175 176 template<class S, class U> 177 struct Converter 178 { 179 static inline const char* uintToString(char buffer[22], U x, Uint32& size) 180 { 181 if (x < 128) 182 { 183 mike 1.1 size = _Uint32Strings[x].size; 184 return _Uint32Strings[x].str; 185 } 186 187 char* p = &buffer[21]; 188 *p = '\0'; 189 190 do 191 { 192 *--p = '0' + (x % 10); 193 x = x / 10; 194 } 195 while (x); 196 197 size = &buffer[21] - p; 198 return p; 199 } 200 201 static inline const char* sintToString(char buffer[22], S x, Uint32& size) 202 { 203 if (x < 0) 204 mike 1.1 { 205 char* p = &buffer[21]; 206 *p = '\0'; 207 208 U t = U(-x); 209 210 do 211 { 212 *--p = '0' + (t % 10); 213 t = t / 10; 214 } 215 while (t); 216 217 *--p = '-'; 218 219 size = &buffer[21] - p; 220 return p; 221 } 222 else 223 return Converter<S, U>::uintToString(buffer, U(x), size); 224 } 225 mike 1.1 }; 226 227 const char* Uint8ToString(char buffer[22], Uint8 x, Uint32& size) 228 { 229 return Converter<Sint8, Uint8>::uintToString(buffer, x, size); 230 } 231 232 const char* Uint16ToString(char buffer[22], Uint16 x, Uint32& size) 233 { 234 return Converter<Sint16, Uint16>::uintToString(buffer, x, size); 235 } 236 237 const char* Uint32ToString(char buffer[22], Uint32 x, Uint32& size) 238 { 239 return Converter<Sint32, Uint32>::uintToString(buffer, x, size); 240 } 241 242 const char* Uint64ToString(char buffer[22], Uint64 x, Uint32& size) 243 { 244 return Converter<Sint64, Uint64>::uintToString(buffer, x, size); 245 } 246 mike 1.1 247 const char* Sint8ToString(char buffer[22], Sint8 x, Uint32& size) 248 { 249 return Converter<Sint8, Uint8>::sintToString(buffer, x, size); 250 } 251 252 const char* Sint16ToString(char buffer[22], Sint16 x, Uint32& size) 253 { 254 return Converter<Sint16, Uint16>::sintToString(buffer, x, size); 255 } 256 257 const char* Sint32ToString(char buffer[22], Sint32 x, Uint32& size) 258 { 259 return Converter<Sint32, Uint32>::sintToString(buffer, x, size); 260 } 261 262 const char* Sint64ToString(char buffer[22], Sint64 x, Uint32& size) 263 { 264 return Converter<Sint64, Uint64>::sintToString(buffer, x, size); 265 } 266 | ||
267 kumpf 1.2 //------------------------------------------------------------------------------ 268 // 269 // decimalStringToUint64 270 // 271 // ( positiveDecimalDigit *decimalDigit | "0" ) 272 // 273 //------------------------------------------------------------------------------ 274 275 Boolean StringConversion::decimalStringToUint64( 276 const char* stringValue, 277 Uint64& x) 278 { 279 x = 0; 280 const char* p = stringValue; 281 282 if (!p || !*p) 283 { 284 return false; 285 } 286 287 if (*p == '0') 288 kumpf 1.2 { 289 // A decimal string that starts with '0' must be exactly "0". 290 return p[1] == '\0'; 291 } 292 293 // Add on each digit, checking for overflow errors 294 while (isdigit(*p)) 295 { 296 // Make sure we won't overflow when we multiply by 10 297 if (x > PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)/10) 298 { 299 return false; 300 } 301 x = 10 * x; 302 303 // Make sure we won't overflow when we add the next digit 304 Uint64 newDigit = (*p++ - '0'); 305 if (PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF) - x < newDigit) 306 { 307 return false; 308 } 309 kumpf 1.2 x = x + newDigit; 310 } 311 312 // If we found a non-decimal digit, report an error 313 return (!*p); 314 } 315 316 //------------------------------------------------------------------------------ 317 // 318 // hexStringToUint64 319 // 320 // ( "0x" | "0X" ) 1*hexDigit 321 // 322 //------------------------------------------------------------------------------ 323 324 Boolean StringConversion::hexStringToUint64( 325 const char* stringValue, 326 Uint64& x) 327 { 328 x = 0; 329 const char* p = stringValue; 330 kumpf 1.2 331 if (!p || !*p) 332 { 333 return false; 334 } 335 336 if ((p[0] != '0') || ((p[1] != 'x') && (p[1] != 'X'))) 337 { 338 return false; 339 } 340 341 // Skip over the "0x" 342 p+=2; 343 344 // At least one hexadecimal digit is required 345 if (!*p) 346 { 347 return false; 348 } 349 350 // Add on each digit, checking for overflow errors 351 kumpf 1.2 while (isxdigit(*p)) 352 { 353 // Make sure we won't overflow when we multiply by 16 | ||
354 kumpf 1.3 if (x & PEGASUS_UINT64_LITERAL(0xF000000000000000)) | ||
355 kumpf 1.2 { 356 return false; 357 } 358 359 x = (x << 4) + Uint64(hexCharToNumeric(*p++)); 360 } 361 362 // If we found a non-hexadecimal digit, report an error 363 return (!*p); 364 } 365 366 //------------------------------------------------------------------------------ 367 // 368 // octalStringToUint64 369 // 370 // "0" 1*octalDigit 371 // 372 //------------------------------------------------------------------------------ 373 374 Boolean StringConversion::octalStringToUint64( 375 const char* stringValue, 376 kumpf 1.2 Uint64& x) 377 { 378 x = 0; 379 const char* p = stringValue; 380 381 if (!p || !*p) 382 { 383 return false; 384 } 385 386 if (*p++ != '0') 387 { 388 return false; 389 } 390 391 // At least one octal digit is required 392 if (!*p) 393 { 394 return false; 395 } 396 397 kumpf 1.2 // Add on each digit, checking for overflow errors 398 while ((*p >= '0') && (*p <= '7')) 399 { 400 // Make sure we won't overflow when we multiply by 8 | ||
401 kumpf 1.3 if (x & PEGASUS_UINT64_LITERAL(0xE000000000000000)) | ||
402 kumpf 1.2 { 403 return false; 404 } 405 406 x = (x << 3) + Uint64(*p++ - '0'); 407 } 408 409 // If we found a non-octal digit, report an error 410 return (!*p); 411 } 412 413 //------------------------------------------------------------------------------ 414 // 415 // binaryStringToUint64 416 // 417 // 1*binaryDigit ( "b" | "B" ) 418 // 419 //------------------------------------------------------------------------------ 420 421 Boolean StringConversion::binaryStringToUint64( 422 const char* stringValue, 423 kumpf 1.2 Uint64& x) 424 { 425 x = 0; 426 const char* p = stringValue; 427 428 if (!p || !*p) 429 { 430 return false; 431 } 432 433 // At least two characters are required 434 if (!*(p+1)) 435 { 436 return false; 437 } 438 439 // Add on each digit, checking for overflow errors 440 while ((*p == '0') || (*p == '1')) 441 { 442 // Make sure we won't overflow when we multiply by 2 | ||
443 kumpf 1.3 if (x & PEGASUS_UINT64_LITERAL(0x8000000000000000)) | ||
444 kumpf 1.2 { 445 return false; 446 } 447 448 // We can't overflow when we add the next digit 449 x = (x << 1) + Uint64(*p++ - '0'); 450 } 451 452 if ((*p != 'b') && (*p != 'B')) 453 { 454 return false; 455 } 456 457 // No additional characters are permitted 458 return (!*++p); 459 } 460 461 Boolean StringConversion::checkUintBounds( 462 Uint64 x, 463 CIMType type) 464 { 465 kumpf 1.2 switch (type) 466 { 467 case CIMTYPE_UINT8: 468 return !(x & PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFF00)); 469 case CIMTYPE_UINT16: 470 return !(x & PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFF0000)); 471 case CIMTYPE_UINT32: 472 return !(x & PEGASUS_UINT64_LITERAL(0xFFFFFFFF00000000)); 473 case CIMTYPE_UINT64: 474 return true; | ||
475 kumpf 1.3 default: 476 break; | ||
477 kumpf 1.2 } 478 479 return false; 480 } 481 482 //------------------------------------------------------------------------------ 483 // 484 // stringToSint64 485 // 486 // [ "+" | "-" ] (unsigned integer format) 487 // 488 //------------------------------------------------------------------------------ 489 490 Boolean StringConversion::stringToSint64( 491 const char* stringValue, 492 Boolean (*uint64Converter)(const char*, Uint64&), 493 Sint64& x) 494 { 495 x = 0; 496 497 if (!stringValue) 498 kumpf 1.2 { 499 return false; 500 } 501 502 // Skip optional sign 503 504 Boolean negative = *stringValue == '-'; 505 506 if (negative || *stringValue == '+') 507 { 508 stringValue++; 509 } 510 511 // Convert the remaining unsigned integer 512 513 Uint64 uint64Value = 0; 514 if (!(uint64Converter(stringValue, uint64Value))) 515 { 516 return false; 517 } 518 519 kumpf 1.2 // Convert the unsigned integer to a signed integer 520 521 if (negative) 522 { 523 if (uint64Value > PEGASUS_UINT64_LITERAL(0x8000000000000000)) 524 { 525 return false; 526 } 527 x = -Sint64(uint64Value); 528 } 529 else 530 { 531 if (uint64Value > PEGASUS_UINT64_LITERAL(0x7FFFFFFFFFFFFFFF)) 532 { 533 return false; 534 } 535 x = Sint64(uint64Value); 536 } 537 538 return true; 539 } 540 kumpf 1.2 541 Boolean StringConversion::checkSintBounds( 542 Sint64 x, 543 CIMType type) 544 { 545 switch (type) 546 { 547 case CIMTYPE_SINT8: 548 return (((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFFFF80)) == 0) || 549 ((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFFFF80)) == 550 PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFFFF80))); 551 case CIMTYPE_SINT16: 552 return (((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFF8000)) == 0) || 553 ((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFF8000)) == 554 PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFF8000))); 555 case CIMTYPE_SINT32: 556 return (((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFF80000000)) == 0) || 557 ((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFF80000000)) == 558 PEGASUS_SINT64_LITERAL(0xFFFFFFFF80000000))); 559 case CIMTYPE_SINT64: 560 return true; | ||
561 kumpf 1.3 default: 562 break; | ||
563 kumpf 1.2 } 564 565 return false; 566 } 567 568 //------------------------------------------------------------------------------ 569 // 570 // stringToReal64 571 // 572 // [ "+" | "-" ] *decimalDigit "." 1*decimalDigit 573 // [ ( "e" | "E" ) [ "+" | "-" ] 1*decimalDigit ] 574 // 575 //------------------------------------------------------------------------------ 576 577 Boolean StringConversion::stringToReal64( 578 const char* stringValue, 579 Real64& x) 580 { 581 // 582 // Check the string against the DMTF-defined grammar 583 // 584 kumpf 1.2 const char* p = stringValue; 585 586 if (!p || !*p) 587 return false; 588 589 // Skip optional sign: 590 591 if (*p == '+' || *p == '-') 592 p++; 593 594 // Skip optional first set of digits: 595 596 while (isdigit(*p)) 597 p++; 598 599 // Test required dot: 600 601 if (*p++ != '.') 602 return false; 603 604 // One or more digits required: 605 kumpf 1.2 606 if (!isdigit(*p++)) 607 return false; 608 609 while (isdigit(*p)) 610 p++; 611 612 // If there is an exponent now: 613 614 if (*p) 615 { 616 // Test exponent: 617 618 if (*p != 'e' && *p != 'E') 619 return false; 620 621 p++; 622 623 // Skip optional sign: 624 625 if (*p == '+' || *p == '-') 626 kumpf 1.2 p++; 627 628 // One or more digits required: 629 630 if (!isdigit(*p++)) 631 return false; 632 633 while (isdigit(*p)) 634 p++; 635 } 636 637 if (*p) 638 return false; 639 640 // 641 // Do the conversion 642 // 643 char* end; 644 645 errno = 0; 646 x = strtod(stringValue, &end); 647 kumpf 1.2 648 return (!*end && (errno != ERANGE)); 649 } 650 | ||
651 mike 1.1 PEGASUS_NAMESPACE_END |
No CVS admin address has been configured |
Powered by ViewCVS 0.9.2 |