Ignore:
File:
1 edited

Legend:

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

    rd7f6248 ra8bc7f8  
    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)
     542        if (dstr_size >= size) {
    545543                return;
    546        
     544        }
    547545        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;
    611546}
    612547
     
    640575        dest[dest_off] = '\0';
    641576}
    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 
    720577
    721578/** Convert wide string to new string.
     
    798655
    799656        dest[dlen - 1] = '\0';
    800 }
    801 
    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;
    819657}
    820658
     
    1115953        return dest;
    1116954}
     955
    1117956
    1118957/** Convert initial part of string to unsigned long according to given base.
     
    12911130}
    12921131
    1293 /** Convert string to uint8_t.
    1294  *
    1295  * @param nptr   Pointer to string.
    1296  * @param endptr If not NULL, pointer to the first invalid character
    1297  *               is stored here.
    1298  * @param base   Zero or number between 2 and 36 inclusive.
    1299  * @param strict Do not allow any trailing characters.
    1300  * @param result Result of the conversion.
    1301  *
    1302  * @return EOK if conversion was successful.
    1303  *
    1304  */
    1305 int str_uint8_t(const char *nptr, char **endptr, unsigned int base,
    1306     bool strict, uint8_t *result)
    1307 {
    1308         assert(result != NULL);
    1309        
    1310         bool neg;
    1311         char *lendptr;
    1312         uint64_t res;
    1313         int ret = str_uint(nptr, &lendptr, base, &neg, &res);
    1314        
    1315         if (endptr != NULL)
    1316                 *endptr = (char *) lendptr;
    1317        
    1318         if (ret != EOK)
    1319                 return ret;
    1320        
    1321         /* Do not allow negative values */
    1322         if (neg)
    1323                 return EINVAL;
    1324        
    1325         /* Check whether we are at the end of
    1326            the string in strict mode */
    1327         if ((strict) && (*lendptr != 0))
    1328                 return EINVAL;
    1329        
    1330         /* Check for overflow */
    1331         uint8_t _res = (uint8_t) res;
    1332         if (_res != res)
    1333                 return EOVERFLOW;
    1334        
    1335         *result = _res;
    1336        
    1337         return EOK;
    1338 }
    1339 
    1340 /** Convert string to uint16_t.
    1341  *
    1342  * @param nptr   Pointer to string.
    1343  * @param endptr If not NULL, pointer to the first invalid character
    1344  *               is stored here.
    1345  * @param base   Zero or number between 2 and 36 inclusive.
    1346  * @param strict Do not allow any trailing characters.
    1347  * @param result Result of the conversion.
    1348  *
    1349  * @return EOK if conversion was successful.
    1350  *
    1351  */
    1352 int str_uint16_t(const char *nptr, char **endptr, unsigned int base,
    1353     bool strict, uint16_t *result)
    1354 {
    1355         assert(result != NULL);
    1356        
    1357         bool neg;
    1358         char *lendptr;
    1359         uint64_t res;
    1360         int ret = str_uint(nptr, &lendptr, base, &neg, &res);
    1361        
    1362         if (endptr != NULL)
    1363                 *endptr = (char *) lendptr;
    1364        
    1365         if (ret != EOK)
    1366                 return ret;
    1367        
    1368         /* Do not allow negative values */
    1369         if (neg)
    1370                 return EINVAL;
    1371        
    1372         /* Check whether we are at the end of
    1373            the string in strict mode */
    1374         if ((strict) && (*lendptr != 0))
    1375                 return EINVAL;
    1376        
    1377         /* Check for overflow */
    1378         uint16_t _res = (uint16_t) res;
    1379         if (_res != res)
    1380                 return EOVERFLOW;
    1381        
    1382         *result = _res;
    1383        
    1384         return EOK;
    1385 }
    1386 
    1387 /** Convert string to uint32_t.
    1388  *
    1389  * @param nptr   Pointer to string.
    1390  * @param endptr If not NULL, pointer to the first invalid character
    1391  *               is stored here.
    1392  * @param base   Zero or number between 2 and 36 inclusive.
    1393  * @param strict Do not allow any trailing characters.
    1394  * @param result Result of the conversion.
    1395  *
    1396  * @return EOK if conversion was successful.
    1397  *
    1398  */
    1399 int str_uint32_t(const char *nptr, char **endptr, unsigned int base,
    1400     bool strict, uint32_t *result)
    1401 {
    1402         assert(result != NULL);
    1403        
    1404         bool neg;
    1405         char *lendptr;
    1406         uint64_t res;
    1407         int ret = str_uint(nptr, &lendptr, base, &neg, &res);
    1408        
    1409         if (endptr != NULL)
    1410                 *endptr = (char *) lendptr;
    1411        
    1412         if (ret != EOK)
    1413                 return ret;
    1414        
    1415         /* Do not allow negative values */
    1416         if (neg)
    1417                 return EINVAL;
    1418        
    1419         /* Check whether we are at the end of
    1420            the string in strict mode */
    1421         if ((strict) && (*lendptr != 0))
    1422                 return EINVAL;
    1423        
    1424         /* Check for overflow */
    1425         uint32_t _res = (uint32_t) res;
    1426         if (_res != res)
    1427                 return EOVERFLOW;
    1428        
    1429         *result = _res;
    1430        
    1431         return EOK;
    1432 }
    1433 
    14341132/** Convert string to uint64_t.
    14351133 *
Note: See TracChangeset for help on using the changeset viewer.