Ignore:
File:
1 edited

Legend:

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

    rfc97128 rdcb74c0a  
    22 * Copyright (c) 2005 Martin Decky
    33 * Copyright (c) 2008 Jiri Svoboda
    4  * Copyright (c) 2011 Oleg Romanenko
    54 * All rights reserved.
    65 *
     
    367366}
    368367
    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 
    381368/** Check whether character is valid
    382369 *
     
    553540
    554541        dstr_size = str_size(dest);
     542        if (dstr_size >= size)
     543                return;
     544       
    555545        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 */
     572int 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;
    556609}
    557610
     
    565618 * @param size  Size of the destination buffer.
    566619 * @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;
     620 */
     621void wstr_to_str(char *dest, size_t size, const wchar_t *src)
     622{
    573623        wchar_t ch;
    574624        size_t src_idx;
     
    582632
    583633        while ((ch = src[src_idx++]) != 0) {
    584                 rc = chr_encode(ch, dest, &dest_off, size - 1);
    585                 if (rc != EOK)
     634                if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
    586635                        break;
    587636        }
    588637
    589638        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 
     639}
    670640
    671641/** Convert wide string to new string.
     
    727697 * @param dlen  Length of destination buffer (number of wchars).
    728698 * @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;
     699 */
     700void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
     701{
    735702        size_t offset;
    736703        size_t di;
     
    743710
    744711        do {
    745                 if (di >= dlen - 1) {
    746                         rc = EOVERFLOW;
     712                if (di >= dlen - 1)
    747713                        break;
    748                 }
    749714
    750715                c = str_decode(src, &offset, STR_NO_LIMIT);
     
    753718
    754719        dest[dlen - 1] = '\0';
    755         return rc;
    756720}
    757721
     
    799763       
    800764        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;
    836765}
    837766
     
    10881017}
    10891018
    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 }
    11201019
    11211020/** Convert initial part of string to unsigned long according to given base.
Note: See TracChangeset for help on using the changeset viewer.