Changeset 00aece0 in mainline for uspace/lib/c/generic/str.c
- Timestamp:
- 2012-02-18T16:47:38Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4449c6c
- Parents:
- bd5f3b7 (diff), f943dd3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
rbd5f3b7 r00aece0 3 3 * Copyright (c) 2008 Jiri Svoboda 4 4 * Copyright (c) 2011 Martin Sucha 5 * Copyright (c) 2011 Oleg Romanenko 5 6 * All rights reserved. 6 7 * … … 550 551 * 551 552 * Common legacy text encoding in hardware is 7-bit ASCII fitted into 552 * a fixed-wi th byte buffer (bit 7 always zero), right-padded with spaces553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces 553 554 * (ASCII 0x20). Convert space-padded ascii to string representation. 554 555 * … … 640 641 } 641 642 643 /** Convert UTF16 string to string. 644 * 645 * Convert utf16 string @a src to string. The output is written to the buffer 646 * specified by @a dest and @a size. @a size must be non-zero and the string 647 * written will always be well-formed. Surrogate pairs also supported. 648 * 649 * @param dest Destination buffer. 650 * @param size Size of the destination buffer. 651 * @param src Source utf16 string. 652 * 653 * @return EOK, if success, negative otherwise. 654 */ 655 int utf16_to_str(char *dest, size_t size, const uint16_t *src) 656 { 657 size_t idx = 0, dest_off = 0; 658 wchar_t ch; 659 int rc = EOK; 660 661 /* There must be space for a null terminator in the buffer. */ 662 assert(size > 0); 663 664 while (src[idx]) { 665 if ((src[idx] & 0xfc00) == 0xd800) { 666 if (src[idx + 1] && (src[idx + 1] & 0xfc00) == 0xdc00) { 667 ch = 0x10000; 668 ch += (src[idx] & 0x03FF) << 10; 669 ch += (src[idx + 1] & 0x03FF); 670 idx += 2; 671 } 672 else 673 break; 674 } else { 675 ch = src[idx]; 676 idx++; 677 } 678 rc = chr_encode(ch, dest, &dest_off, size - 1); 679 if (rc != EOK) 680 break; 681 } 682 dest[dest_off] = '\0'; 683 return rc; 684 } 685 686 int str_to_utf16(uint16_t *dest, size_t size, const char *src) 687 { 688 int rc = EOK; 689 size_t offset = 0; 690 size_t idx = 0; 691 wchar_t c; 692 693 assert(size > 0); 694 695 while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) { 696 if (c > 0x10000) { 697 if (idx + 2 >= size - 1) { 698 rc = EOVERFLOW; 699 break; 700 } 701 c = (c - 0x10000); 702 dest[idx] = 0xD800 | (c >> 10); 703 dest[idx + 1] = 0xDC00 | (c & 0x3FF); 704 idx++; 705 } else { 706 dest[idx] = c; 707 } 708 709 idx++; 710 if (idx >= size - 1) { 711 rc = EOVERFLOW; 712 break; 713 } 714 } 715 716 dest[idx] = '\0'; 717 return rc; 718 } 719 720 642 721 /** Convert wide string to new string. 643 722 * … … 731 810 { 732 811 size_t len = str_length(str); 733 wchar_t *wstr = calloc(len+1, sizeof(wchar_t)); 734 if (wstr == NULL) { 735 return NULL; 736 } 737 str_to_wstr(wstr, len+1, str); 812 813 wchar_t *wstr = calloc(len+1, sizeof(wchar_t)); 814 if (wstr == NULL) 815 return NULL; 816 817 str_to_wstr(wstr, len + 1, str); 738 818 return wstr; 739 819 } … … 759 839 760 840 return NULL; 841 } 842 843 /** Removes specified trailing characters from a string. 844 * 845 * @param str String to remove from. 846 * @param ch Character to remove. 847 */ 848 void str_rtrim(char *str, wchar_t ch) 849 { 850 size_t off = 0; 851 size_t pos = 0; 852 wchar_t c; 853 bool update_last_chunk = true; 854 char *last_chunk = NULL; 855 856 while ((c = str_decode(str, &off, STR_NO_LIMIT))) { 857 if (c != ch) { 858 update_last_chunk = true; 859 last_chunk = NULL; 860 } else if (update_last_chunk) { 861 update_last_chunk = false; 862 last_chunk = (str + pos); 863 } 864 pos = off; 865 } 866 867 if (last_chunk) 868 *last_chunk = '\0'; 869 } 870 871 /** Removes specified leading characters from a string. 872 * 873 * @param str String to remove from. 874 * @param ch Character to remove. 875 */ 876 void str_ltrim(char *str, wchar_t ch) 877 { 878 wchar_t acc; 879 size_t off = 0; 880 size_t pos = 0; 881 size_t str_sz = str_size(str); 882 883 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { 884 if (acc != ch) 885 break; 886 else 887 pos = off; 888 } 889 890 if (pos > 0) { 891 memmove(str, &str[pos], str_sz - pos); 892 pos = str_sz - pos; 893 str[str_sz - pos] = '\0'; 894 } 761 895 } 762 896 … … 1035 1169 return dest; 1036 1170 } 1037 1038 1171 1039 1172 /** Convert initial part of string to unsigned long according to given base. … … 1212 1345 } 1213 1346 1347 /** Convert string to uint8_t. 1348 * 1349 * @param nptr Pointer to string. 1350 * @param endptr If not NULL, pointer to the first invalid character 1351 * is stored here. 1352 * @param base Zero or number between 2 and 36 inclusive. 1353 * @param strict Do not allow any trailing characters. 1354 * @param result Result of the conversion. 1355 * 1356 * @return EOK if conversion was successful. 1357 * 1358 */ 1359 int str_uint8_t(const char *nptr, char **endptr, unsigned int base, 1360 bool strict, uint8_t *result) 1361 { 1362 assert(result != NULL); 1363 1364 bool neg; 1365 char *lendptr; 1366 uint64_t res; 1367 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1368 1369 if (endptr != NULL) 1370 *endptr = (char *) lendptr; 1371 1372 if (ret != EOK) 1373 return ret; 1374 1375 /* Do not allow negative values */ 1376 if (neg) 1377 return EINVAL; 1378 1379 /* Check whether we are at the end of 1380 the string in strict mode */ 1381 if ((strict) && (*lendptr != 0)) 1382 return EINVAL; 1383 1384 /* Check for overflow */ 1385 uint8_t _res = (uint8_t) res; 1386 if (_res != res) 1387 return EOVERFLOW; 1388 1389 *result = _res; 1390 1391 return EOK; 1392 } 1393 1394 /** Convert string to uint16_t. 1395 * 1396 * @param nptr Pointer to string. 1397 * @param endptr If not NULL, pointer to the first invalid character 1398 * is stored here. 1399 * @param base Zero or number between 2 and 36 inclusive. 1400 * @param strict Do not allow any trailing characters. 1401 * @param result Result of the conversion. 1402 * 1403 * @return EOK if conversion was successful. 1404 * 1405 */ 1406 int str_uint16_t(const char *nptr, char **endptr, unsigned int base, 1407 bool strict, uint16_t *result) 1408 { 1409 assert(result != NULL); 1410 1411 bool neg; 1412 char *lendptr; 1413 uint64_t res; 1414 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1415 1416 if (endptr != NULL) 1417 *endptr = (char *) lendptr; 1418 1419 if (ret != EOK) 1420 return ret; 1421 1422 /* Do not allow negative values */ 1423 if (neg) 1424 return EINVAL; 1425 1426 /* Check whether we are at the end of 1427 the string in strict mode */ 1428 if ((strict) && (*lendptr != 0)) 1429 return EINVAL; 1430 1431 /* Check for overflow */ 1432 uint16_t _res = (uint16_t) res; 1433 if (_res != res) 1434 return EOVERFLOW; 1435 1436 *result = _res; 1437 1438 return EOK; 1439 } 1440 1441 /** Convert string to uint32_t. 1442 * 1443 * @param nptr Pointer to string. 1444 * @param endptr If not NULL, pointer to the first invalid character 1445 * is stored here. 1446 * @param base Zero or number between 2 and 36 inclusive. 1447 * @param strict Do not allow any trailing characters. 1448 * @param result Result of the conversion. 1449 * 1450 * @return EOK if conversion was successful. 1451 * 1452 */ 1453 int str_uint32_t(const char *nptr, char **endptr, unsigned int base, 1454 bool strict, uint32_t *result) 1455 { 1456 assert(result != NULL); 1457 1458 bool neg; 1459 char *lendptr; 1460 uint64_t res; 1461 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1462 1463 if (endptr != NULL) 1464 *endptr = (char *) lendptr; 1465 1466 if (ret != EOK) 1467 return ret; 1468 1469 /* Do not allow negative values */ 1470 if (neg) 1471 return EINVAL; 1472 1473 /* Check whether we are at the end of 1474 the string in strict mode */ 1475 if ((strict) && (*lendptr != 0)) 1476 return EINVAL; 1477 1478 /* Check for overflow */ 1479 uint32_t _res = (uint32_t) res; 1480 if (_res != res) 1481 return EOVERFLOW; 1482 1483 *result = _res; 1484 1485 return EOK; 1486 } 1487 1214 1488 /** Convert string to uint64_t. 1215 1489 *
Note:
See TracChangeset
for help on using the changeset viewer.