Ignore:
File:
1 edited

Legend:

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

    rdcb74c0a rfc97128  
    22 * Copyright (c) 2005 Martin Decky
    33 * Copyright (c) 2008 Jiri Svoboda
     4 * Copyright (c) 2011 Oleg Romanenko
    45 * All rights reserved.
    56 *
     
    366367}
    367368
     369/** Check whether wide string is plain ASCII.
     370 *
     371 * @return True if wide string is plain ASCII.
     372 *
     373 */
     374bool wstr_is_ascii(const wchar_t *wstr)
     375{
     376        while (*wstr && ascii_check(*wstr))
     377                wstr++;
     378        return *wstr == 0;
     379}
     380
    368381/** Check whether character is valid
    369382 *
     
    540553
    541554        dstr_size = str_size(dest);
    542         if (dstr_size >= size)
    543                 return;
    544        
    545555        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 into
    551  * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces
    552  * (ASCII 0x20). Convert space-padded ascii to string representation.
    553  *
    554  * If the text does not fit into the destination buffer, the function converts
    555  * as many characters as possible and returns EOVERFLOW.
    556  *
    557  * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
    558  * converted anyway and invalid characters are replaced with question marks
    559  * (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 buffer
    564  * @param size          Size of destination buffer
    565  * @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 fit
    569  *                      destination buffer, EIO if the text contains
    570  *                      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;
    609556}
    610557
     
    618565 * @param size  Size of the destination buffer.
    619566 * @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 */
     570int wstr_to_str(char *dest, size_t size, const wchar_t *src)
     571{
     572        int rc;
    623573        wchar_t ch;
    624574        size_t src_idx;
     
    632582
    633583        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)
    635586                        break;
    636587        }
    637588
    638589        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 */
     605int 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
     636int 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
    640670
    641671/** Convert wide string to new string.
     
    697727 * @param dlen  Length of destination buffer (number of wchars).
    698728 * @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 */
     732int str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
     733{
     734        int rc=EOK;
    702735        size_t offset;
    703736        size_t di;
     
    710743
    711744        do {
    712                 if (di >= dlen - 1)
     745                if (di >= dlen - 1) {
     746                        rc = EOVERFLOW;
    713747                        break;
     748                }
    714749
    715750                c = str_decode(src, &offset, STR_NO_LIMIT);
     
    718753
    719754        dest[dlen - 1] = '\0';
     755        return rc;
    720756}
    721757
     
    763799       
    764800        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 */
     810wchar_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 */
     827wchar_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;
    765836}
    766837
     
    10171088}
    10181089
     1090void str_reverse(char* begin, char* end)
     1091{
     1092    char aux;
     1093    while(end>begin)
     1094        aux=*end, *end--=*begin, *begin++=aux;
     1095}
     1096
     1097int 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}
    10191120
    10201121/** Convert initial part of string to unsigned long according to given base.
Note: See TracChangeset for help on using the changeset viewer.