Ignore:
File:
1 edited

Legend:

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

    r1737bfb r933cadf  
    22 * Copyright (c) 2005 Martin Decky
    33 * Copyright (c) 2008 Jiri Svoboda
    4  * Copyright (c) 2011 Martin Sucha
    5  * Copyright (c) 2011 Oleg Romanenko
    64 * All rights reserved.
    75 *
     
    542540
    543541        dstr_size = str_size(dest);
    544         if (dstr_size >= size)
    545                 return;
    546        
    547542        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 into
    553  * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces
    554  * (ASCII 0x20). Convert space-padded ascii to string representation.
    555  *
    556  * If the text does not fit into the destination buffer, the function converts
    557  * as many characters as possible and returns EOVERFLOW.
    558  *
    559  * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
    560  * converted anyway and invalid characters are replaced with question marks
    561  * (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 buffer
    566  * @param size          Size of destination buffer
    567  * @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 fit
    571  *                      destination buffer, EIO if the text contains
    572  *                      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;
    611543}
    612544
     
    640572        dest[dest_off] = '\0';
    641573}
    642 
    643 /** Convert UTF16 string to string.
    644  *
    645  * Convert utf16 string @a src to string. The output is written to the buffer
    646  * specified by @a dest and @a size. @a size must be non-zero and the string
    647  * 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                         else
    673                                 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 
    720574
    721575/** Convert wide string to new string.
     
    800654}
    801655
    802 /** Convert string to wide string.
    803  *
    804  * Convert string @a src to wide string. A new wide NULL-terminated
    805  * 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 
    821656/** Find first occurence of character in string.
    822657 *
     
    839674       
    840675        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                 else
    887                         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         }
    895676}
    896677
     
    1169950        return dest;
    1170951}
     952
    1171953
    1172954/** Convert initial part of string to unsigned long according to given base.
     
    13451127}
    13461128
    1347 /** Convert string to uint8_t.
    1348  *
    1349  * @param nptr   Pointer to string.
    1350  * @param endptr If not NULL, pointer to the first invalid character
    1351  *               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 of
    1380            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 character
    1398  *               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 of
    1427            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 character
    1445  *               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 of
    1474            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 
    14881129/** Convert string to uint64_t.
    14891130 *
Note: See TracChangeset for help on using the changeset viewer.