Changes in uspace/lib/c/generic/str.c [a8bc7f8:d7f6248] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
ra8bc7f8 rd7f6248 2 2 * Copyright (c) 2005 Martin Decky 3 3 * Copyright (c) 2008 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha 5 * Copyright (c) 2011 Oleg Romanenko 4 6 * All rights reserved. 5 7 * … … 540 542 541 543 dstr_size = str_size(dest); 542 if (dstr_size >= size) {544 if (dstr_size >= size) 543 545 return; 544 }546 545 547 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; 546 611 } 547 612 … … 575 640 dest[dest_off] = '\0'; 576 641 } 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 577 720 578 721 /** Convert wide string to new string. … … 655 798 656 799 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; 657 819 } 658 820 … … 953 1115 return dest; 954 1116 } 955 956 1117 957 1118 /** Convert initial part of string to unsigned long according to given base. … … 1130 1291 } 1131 1292 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 1132 1434 /** Convert string to uint64_t. 1133 1435 *
Note:
See TracChangeset
for help on using the changeset viewer.