| 1409 | |
| 1410 | #if defined EXV_HAVE_ICONV |
| 1411 | bool convertStringCharsetIconv(std::string& str, const char* from, const char* to) { |
| 1412 | if (strcmp(from, to) == 0) |
| 1413 | return true; // nothing to do |
| 1414 | |
| 1415 | bool ret = true; |
| 1416 | auto cd = iconv_open(to, from); |
| 1417 | if (cd == iconv_t(-1)) { |
| 1418 | #ifndef SUPPRESS_WARNINGS |
| 1419 | EXV_WARNING << "iconv_open: " << strError() << "\n"; |
| 1420 | #endif |
| 1421 | return false; |
| 1422 | } |
| 1423 | std::string outstr; |
| 1424 | #ifdef WINICONV_CONST |
| 1425 | auto inptr = (WINICONV_CONST char*)(str.c_str()); |
| 1426 | #else |
| 1427 | auto inptr = (EXV_ICONV_CONST char*)(str.c_str()); |
| 1428 | #endif |
| 1429 | size_t inbytesleft = str.length(); |
| 1430 | while (inbytesleft) { |
| 1431 | char outbuf[256]; |
| 1432 | char* outptr = outbuf; |
| 1433 | size_t outbytesleft = sizeof(outbuf); |
| 1434 | size_t rc = iconv(cd, &inptr, &inbytesleft, &outptr, &outbytesleft); |
| 1435 | const size_t outbytesProduced = sizeof(outbuf) - outbytesleft; |
| 1436 | if (rc == std::numeric_limits<size_t>::max() && errno != E2BIG) { |
| 1437 | #ifndef SUPPRESS_WARNINGS |
| 1438 | EXV_WARNING << "iconv: " << strError() << " inbytesleft = " << inbytesleft << "\n"; |
| 1439 | #endif |
| 1440 | ret = false; |
| 1441 | break; |
| 1442 | } |
| 1443 | outstr.append(std::string(outbuf, outbytesProduced)); |
| 1444 | } |
| 1445 | |
| 1446 | if (cd) |
| 1447 | iconv_close(cd); |
| 1448 | |
| 1449 | if (ret) |
| 1450 | str = outstr; |
| 1451 | return ret; |
| 1452 | } |
| 1453 | |
| 1454 | #elif defined(_WIN32) |
| 1455 | bool swapBytes(std::string& str) { |
no test coverage detected