Changes in uspace/lib/c/generic/str.c [dcb74c0a:fc97128] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
rdcb74c0a rfc97128 2 2 * Copyright (c) 2005 Martin Decky 3 3 * Copyright (c) 2008 Jiri Svoboda 4 * Copyright (c) 2011 Oleg Romanenko 4 5 * All rights reserved. 5 6 * … … 366 367 } 367 368 369 /** Check whether wide string is plain ASCII. 370 * 371 * @return True if wide string is plain ASCII. 372 * 373 */ 374 bool wstr_is_ascii(const wchar_t *wstr) 375 { 376 while (*wstr && ascii_check(*wstr)) 377 wstr++; 378 return *wstr == 0; 379 } 380 368 381 /** Check whether character is valid 369 382 * … … 540 553 541 554 dstr_size = str_size(dest); 542 if (dstr_size >= size)543 return;544 545 555 str_cpy(dest + dstr_size, size - dstr_size, src); 546 }547 548 /** Convert space-padded ASCII to string.549 *550 * Common legacy text encoding in hardware is 7-bit ASCII fitted into551 * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces552 * (ASCII 0x20). Convert space-padded ascii to string representation.553 *554 * If the text does not fit into the destination buffer, the function converts555 * as many characters as possible and returns EOVERFLOW.556 *557 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is558 * converted anyway and invalid characters are replaced with question marks559 * (U_SPECIAL) and the function returns EIO.560 *561 * Regardless of return value upon return @a dest will always be well-formed.562 *563 * @param dest Destination buffer564 * @param size Size of destination buffer565 * @param src Space-padded ASCII.566 * @param n Size of the source buffer in bytes.567 *568 * @return EOK on success, EOVERFLOW if the text does not fit569 * destination buffer, EIO if the text contains570 * non-ASCII bytes.571 */572 int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)573 {574 size_t sidx;575 size_t didx;576 size_t dlast;577 uint8_t byte;578 int rc;579 int result;580 581 /* There must be space for a null terminator in the buffer. */582 assert(size > 0);583 result = EOK;584 585 didx = 0;586 dlast = 0;587 for (sidx = 0; sidx < n; ++sidx) {588 byte = src[sidx];589 if (!ascii_check(byte)) {590 byte = U_SPECIAL;591 result = EIO;592 }593 594 rc = chr_encode(byte, dest, &didx, size - 1);595 if (rc != EOK) {596 assert(rc == EOVERFLOW);597 dest[didx] = '\0';598 return rc;599 }600 601 /* Remember dest index after last non-empty character */602 if (byte != 0x20)603 dlast = didx;604 }605 606 /* Terminate string after last non-empty character */607 dest[dlast] = '\0';608 return result;609 556 } 610 557 … … 618 565 * @param size Size of the destination buffer. 619 566 * @param src Source wide string. 620 */ 621 void wstr_to_str(char *dest, size_t size, const wchar_t *src) 622 { 567 * 568 * @return EOK, if success, negative otherwise. 569 */ 570 int wstr_to_str(char *dest, size_t size, const wchar_t *src) 571 { 572 int rc; 623 573 wchar_t ch; 624 574 size_t src_idx; … … 632 582 633 583 while ((ch = src[src_idx++]) != 0) { 634 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) 584 rc = chr_encode(ch, dest, &dest_off, size - 1); 585 if (rc != EOK) 635 586 break; 636 587 } 637 588 638 589 dest[dest_off] = '\0'; 639 } 590 return rc; 591 } 592 593 /** Convert UTF16 string to string. 594 * 595 * Convert utf16 string @a src to string. The output is written to the buffer 596 * specified by @a dest and @a size. @a size must be non-zero and the string 597 * written will always be well-formed. Surrogate pairs also supported. 598 * 599 * @param dest Destination buffer. 600 * @param size Size of the destination buffer. 601 * @param src Source utf16 string. 602 * 603 * @return EOK, if success, negative otherwise. 604 */ 605 int utf16_to_str(char *dest, size_t size, const uint16_t *src) 606 { 607 size_t idx=0, dest_off=0; 608 wchar_t ch; 609 int rc = EOK; 610 611 /* There must be space for a null terminator in the buffer. */ 612 assert(size > 0); 613 614 while (src[idx]) { 615 if ((src[idx] & 0xfc00) == 0xd800) { 616 if (src[idx+1] && (src[idx+1] & 0xfc00) == 0xdc00) { 617 ch = 0x10000; 618 ch += (src[idx] & 0x03FF) << 10; 619 ch += (src[idx+1] & 0x03FF); 620 idx += 2; 621 } 622 else 623 break; 624 } else { 625 ch = src[idx]; 626 idx++; 627 } 628 rc = chr_encode(ch, dest, &dest_off, size-1); 629 if (rc != EOK) 630 break; 631 } 632 dest[dest_off] = '\0'; 633 return rc; 634 } 635 636 int str_to_utf16(uint16_t *dest, size_t size, const char *src) 637 { 638 int rc=EOK; 639 size_t offset=0; 640 size_t idx=0; 641 wchar_t c; 642 643 assert(size > 0); 644 645 while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) { 646 if (c > 0x10000) { 647 if (idx+2 >= size-1) { 648 rc=EOVERFLOW; 649 break; 650 } 651 c = (c - 0x10000); 652 dest[idx] = 0xD800 | (c >> 10); 653 dest[idx+1] = 0xDC00 | (c & 0x3FF); 654 idx++; 655 } else { 656 dest[idx] = c; 657 } 658 659 idx++; 660 if (idx >= size-1) { 661 rc=EOVERFLOW; 662 break; 663 } 664 } 665 666 dest[idx] = '\0'; 667 return rc; 668 } 669 640 670 641 671 /** Convert wide string to new string. … … 697 727 * @param dlen Length of destination buffer (number of wchars). 698 728 * @param src Source string. 699 */ 700 void str_to_wstr(wchar_t *dest, size_t dlen, const char *src) 701 { 729 * 730 * @return EOK, if success, negative otherwise. 731 */ 732 int str_to_wstr(wchar_t *dest, size_t dlen, const char *src) 733 { 734 int rc=EOK; 702 735 size_t offset; 703 736 size_t di; … … 710 743 711 744 do { 712 if (di >= dlen - 1) 745 if (di >= dlen - 1) { 746 rc = EOVERFLOW; 713 747 break; 748 } 714 749 715 750 c = str_decode(src, &offset, STR_NO_LIMIT); … … 718 753 719 754 dest[dlen - 1] = '\0'; 755 return rc; 720 756 } 721 757 … … 763 799 764 800 return (char *) res; 801 } 802 803 /** Find first occurence of character in wide string. 804 * 805 * @param wstr String to search. 806 * @param ch Character to look for. 807 * 808 * @return Pointer to character in @a wstr or NULL if not found. 809 */ 810 wchar_t *wstr_chr(const wchar_t *wstr, wchar_t ch) 811 { 812 while (*wstr && *wstr != ch) 813 wstr++; 814 if (*wstr) 815 return (wchar_t *) wstr; 816 else 817 return NULL; 818 } 819 820 /** Find last occurence of character in wide string. 821 * 822 * @param wstr String to search. 823 * @param ch Character to look for. 824 * 825 * @return Pointer to character in @a wstr or NULL if not found. 826 */ 827 wchar_t *wstr_rchr(const wchar_t *wstr, wchar_t ch) 828 { 829 const wchar_t *res = NULL; 830 while (*wstr) { 831 if (*wstr == ch) 832 res = wstr; 833 wstr++; 834 } 835 return (wchar_t *) res; 765 836 } 766 837 … … 1017 1088 } 1018 1089 1090 void str_reverse(char* begin, char* end) 1091 { 1092 char aux; 1093 while(end>begin) 1094 aux=*end, *end--=*begin, *begin++=aux; 1095 } 1096 1097 int size_t_str(size_t value, int base, char* str, size_t size) 1098 { 1099 static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 1100 char* wstr=str; 1101 1102 if (size == 0) 1103 return EINVAL; 1104 if (base<2 || base>35) { 1105 *str='\0'; 1106 return EINVAL; 1107 } 1108 1109 do { 1110 *wstr++ = num[value % base]; 1111 if (--size == 0) 1112 return EOVERFLOW; 1113 } while(value /= base); 1114 *wstr='\0'; 1115 1116 // Reverse string 1117 str_reverse(str,wstr-1); 1118 return EOK; 1119 } 1019 1120 1020 1121 /** Convert initial part of string to unsigned long according to given base.
Note:
See TracChangeset
for help on using the changeset viewer.