Changes in uspace/lib/c/generic/str.c [d7f6248:a8bc7f8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
rd7f6248 ra8bc7f8 2 2 * Copyright (c) 2005 Martin Decky 3 3 * Copyright (c) 2008 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha5 * Copyright (c) 2011 Oleg Romanenko6 4 * All rights reserved. 7 5 * … … 542 540 543 541 dstr_size = str_size(dest); 544 if (dstr_size >= size) 542 if (dstr_size >= size) { 545 543 return; 546 544 } 547 545 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 into553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces554 * (ASCII 0x20). Convert space-padded ascii to string representation.555 *556 * If the text does not fit into the destination buffer, the function converts557 * as many characters as possible and returns EOVERFLOW.558 *559 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is560 * converted anyway and invalid characters are replaced with question marks561 * (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 buffer566 * @param size Size of destination buffer567 * @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 fit571 * destination buffer, EIO if the text contains572 * 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;611 546 } 612 547 … … 640 575 dest[dest_off] = '\0'; 641 576 } 642 643 /** Convert UTF16 string to string.644 *645 * Convert utf16 string @a src to string. The output is written to the buffer646 * specified by @a dest and @a size. @a size must be non-zero and the string647 * 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 else673 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 720 577 721 578 /** Convert wide string to new string. … … 798 655 799 656 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-terminated805 * 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 657 } 820 658 … … 1115 953 return dest; 1116 954 } 955 1117 956 1118 957 /** Convert initial part of string to unsigned long according to given base. … … 1291 1130 } 1292 1131 1293 /** Convert string to uint8_t.1294 *1295 * @param nptr Pointer to string.1296 * @param endptr If not NULL, pointer to the first invalid character1297 * 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 of1326 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 character1344 * 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 of1373 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 character1391 * 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 of1420 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 1434 1132 /** Convert string to uint64_t. 1435 1133 *
Note:
See TracChangeset
for help on using the changeset viewer.