Changeset c05642d in mainline for uspace/lib/c/generic/str.c


Ignore:
Timestamp:
2011-09-07T00:03:26Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5081276
Parents:
bb74dabe (diff), 038b289 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    rbb74dabe rc05642d  
    33 * Copyright (c) 2008 Jiri Svoboda
    44 * Copyright (c) 2011 Martin Sucha
     5 * Copyright (c) 2011 Oleg Romanenko
    56 * All rights reserved.
    67 *
     
    550551 *
    551552 * 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 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces
    553554 * (ASCII 0x20). Convert space-padded ascii to string representation.
    554555 *
     
    639640        dest[dest_off] = '\0';
    640641}
     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 */
     655int 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
     686int 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
    641720
    642721/** Convert wide string to new string.
     
    10361115        return dest;
    10371116}
    1038 
    10391117
    10401118/** Convert initial part of string to unsigned long according to given base.
     
    12131291}
    12141292
     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 */
     1305int 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 */
     1352int 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 */
     1399int 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
    12151434/** Convert string to uint64_t.
    12161435 *
Note: See TracChangeset for help on using the changeset viewer.