Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/str.c

    rfc97128 rb48d046  
    22 * Copyright (c) 2005 Martin Decky
    33 * Copyright (c) 2008 Jiri Svoboda
    4  * Copyright (c) 2011 Oleg Romanenko
     4 * Copyright (c) 2011 Martin Sucha
    55 * All rights reserved.
    66 *
     
    367367}
    368368
    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 
    381369/** Check whether character is valid
    382370 *
     
    553541
    554542        dstr_size = str_size(dest);
     543        if (dstr_size >= size)
     544                return;
     545       
    555546        str_cpy(dest + dstr_size, size - dstr_size, src);
     547}
     548
     549/** Convert space-padded ASCII to string.
     550 *
     551 * Common legacy text encoding in hardware is 7-bit ASCII fitted into
     552 * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces
     553 * (ASCII 0x20). Convert space-padded ascii to string representation.
     554 *
     555 * If the text does not fit into the destination buffer, the function converts
     556 * as many characters as possible and returns EOVERFLOW.
     557 *
     558 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
     559 * converted anyway and invalid characters are replaced with question marks
     560 * (U_SPECIAL) and the function returns EIO.
     561 *
     562 * Regardless of return value upon return @a dest will always be well-formed.
     563 *
     564 * @param dest          Destination buffer
     565 * @param size          Size of destination buffer
     566 * @param src           Space-padded ASCII.
     567 * @param n             Size of the source buffer in bytes.
     568 *
     569 * @return              EOK on success, EOVERFLOW if the text does not fit
     570 *                      destination buffer, EIO if the text contains
     571 *                      non-ASCII bytes.
     572 */
     573int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)
     574{
     575        size_t sidx;
     576        size_t didx;
     577        size_t dlast;
     578        uint8_t byte;
     579        int rc;
     580        int result;
     581
     582        /* There must be space for a null terminator in the buffer. */
     583        assert(size > 0);
     584        result = EOK;
     585
     586        didx = 0;
     587        dlast = 0;
     588        for (sidx = 0; sidx < n; ++sidx) {
     589                byte = src[sidx];
     590                if (!ascii_check(byte)) {
     591                        byte = U_SPECIAL;
     592                        result = EIO;
     593                }
     594
     595                rc = chr_encode(byte, dest, &didx, size - 1);
     596                if (rc != EOK) {
     597                        assert(rc == EOVERFLOW);
     598                        dest[didx] = '\0';
     599                        return rc;
     600                }
     601
     602                /* Remember dest index after last non-empty character */
     603                if (byte != 0x20)
     604                        dlast = didx;
     605        }
     606
     607        /* Terminate string after last non-empty character */
     608        dest[dlast] = '\0';
     609        return result;
    556610}
    557611
     
    565619 * @param size  Size of the destination buffer.
    566620 * @param src   Source wide string.
    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;
     621 */
     622void wstr_to_str(char *dest, size_t size, const wchar_t *src)
     623{
    573624        wchar_t ch;
    574625        size_t src_idx;
     
    582633
    583634        while ((ch = src[src_idx++]) != 0) {
    584                 rc = chr_encode(ch, dest, &dest_off, size - 1);
    585                 if (rc != EOK)
     635                if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
    586636                        break;
    587637        }
    588638
    589639        dest[dest_off] = '\0';
    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}
    670641
    671642/** Convert wide string to new string.
     
    727698 * @param dlen  Length of destination buffer (number of wchars).
    728699 * @param src   Source string.
    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;
     700 */
     701void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
     702{
    735703        size_t offset;
    736704        size_t di;
     
    743711
    744712        do {
    745                 if (di >= dlen - 1) {
    746                         rc = EOVERFLOW;
     713                if (di >= dlen - 1)
    747714                        break;
    748                 }
    749715
    750716                c = str_decode(src, &offset, STR_NO_LIMIT);
     
    753719
    754720        dest[dlen - 1] = '\0';
    755         return rc;
     721}
     722
     723/** Convert string to wide string.
     724 *
     725 * Convert string @a src to wide string. A new wide NULL-terminated
     726 * string will be allocated on the heap.
     727 *
     728 * @param src   Source string.
     729 */
     730wchar_t *str_to_awstr(const char *str)
     731{
     732        size_t len = str_length(str);
     733       
     734        wchar_t *wstr = calloc(len+1, sizeof(wchar_t));
     735        if (wstr == NULL)
     736                return NULL;
     737       
     738        str_to_wstr(wstr, len + 1, str);
     739        return wstr;
    756740}
    757741
     
    799783       
    800784        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;
    836785}
    837786
     
    10881037}
    10891038
    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 }
    11201039
    11211040/** Convert initial part of string to unsigned long according to given base.
Note: See TracChangeset for help on using the changeset viewer.