Changes in uspace/lib/c/generic/str.c [1737bfb:933cadf] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
r1737bfb r933cadf 2 2 * Copyright (c) 2005 Martin Decky 3 3 * Copyright (c) 2008 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha5 * Copyright (c) 2011 Oleg Romanenko6 4 * All rights reserved. 7 5 * … … 542 540 543 541 dstr_size = str_size(dest); 544 if (dstr_size >= size)545 return;546 547 542 str_cpy(dest + dstr_size, size - dstr_size, src); 548 }549 550 /** Convert space-padded ASCII to string.551 *552 * Common legacy text encoding in hardware is 7-bit ASCII fitted into553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces554 * (ASCII 0x20). Convert space-padded ascii to string representation.555 *556 * If the text does not fit into the destination buffer, the function converts557 * as many characters as possible and returns EOVERFLOW.558 *559 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is560 * converted anyway and invalid characters are replaced with question marks561 * (U_SPECIAL) and the function returns EIO.562 *563 * Regardless of return value upon return @a dest will always be well-formed.564 *565 * @param dest Destination buffer566 * @param size Size of destination buffer567 * @param src Space-padded ASCII.568 * @param n Size of the source buffer in bytes.569 *570 * @return EOK on success, EOVERFLOW if the text does not fit571 * destination buffer, EIO if the text contains572 * non-ASCII bytes.573 */574 int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)575 {576 size_t sidx;577 size_t didx;578 size_t dlast;579 uint8_t byte;580 int rc;581 int result;582 583 /* There must be space for a null terminator in the buffer. */584 assert(size > 0);585 result = EOK;586 587 didx = 0;588 dlast = 0;589 for (sidx = 0; sidx < n; ++sidx) {590 byte = src[sidx];591 if (!ascii_check(byte)) {592 byte = U_SPECIAL;593 result = EIO;594 }595 596 rc = chr_encode(byte, dest, &didx, size - 1);597 if (rc != EOK) {598 assert(rc == EOVERFLOW);599 dest[didx] = '\0';600 return rc;601 }602 603 /* Remember dest index after last non-empty character */604 if (byte != 0x20)605 dlast = didx;606 }607 608 /* Terminate string after last non-empty character */609 dest[dlast] = '\0';610 return result;611 543 } 612 544 … … 640 572 dest[dest_off] = '\0'; 641 573 } 642 643 /** Convert UTF16 string to string.644 *645 * Convert utf16 string @a src to string. The output is written to the buffer646 * specified by @a dest and @a size. @a size must be non-zero and the string647 * 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 else673 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 574 721 575 /** Convert wide string to new string. … … 800 654 } 801 655 802 /** Convert string to wide string.803 *804 * Convert string @a src to wide string. A new wide NULL-terminated805 * string will be allocated on the heap.806 *807 * @param src Source string.808 */809 wchar_t *str_to_awstr(const char *str)810 {811 size_t len = str_length(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);818 return wstr;819 }820 821 656 /** Find first occurence of character in string. 822 657 * … … 839 674 840 675 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 else887 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 }895 676 } 896 677 … … 1169 950 return dest; 1170 951 } 952 1171 953 1172 954 /** Convert initial part of string to unsigned long according to given base. … … 1345 1127 } 1346 1128 1347 /** Convert string to uint8_t.1348 *1349 * @param nptr Pointer to string.1350 * @param endptr If not NULL, pointer to the first invalid character1351 * 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 of1380 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 character1398 * 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 of1427 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 character1445 * 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 of1474 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 1488 1129 /** Convert string to uint64_t. 1489 1130 *
Note:
See TracChangeset
for help on using the changeset viewer.