| 481 | } |
| 482 | |
| 483 | void YamlSaveHelper::SaveString(const char* key, const char* value) |
| 484 | { |
| 485 | if (value[0] == 0) |
| 486 | value = "\"\""; |
| 487 | |
| 488 | // libyaml supports UTF-8 and not accented ANSI characters (GH#838) |
| 489 | // . So convert ANSI to UTF-8, which is a 2-step process: |
| 490 | |
| 491 | // 1) ANSI -> unicode |
| 492 | { |
| 493 | int size = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, value, -1, NULL, 0); |
| 494 | if (size == 0) |
| 495 | throw std::runtime_error("Unable to convert to unicode: " + std::string(value)); |
| 496 | if (size > m_wcStrSize) |
| 497 | { |
| 498 | delete[] m_pWcStr; |
| 499 | m_pWcStr = new WCHAR[size]; |
| 500 | m_wcStrSize = size; |
| 501 | } |
| 502 | int res = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, value, -1, m_pWcStr, m_wcStrSize); |
| 503 | if (!res) |
| 504 | throw std::runtime_error("Unable to convert to unicode: " + std::string(value)); |
| 505 | } |
| 506 | |
| 507 | // 2) unicode -> UTF-8 |
| 508 | { |
| 509 | // NB. WC_ERR_INVALID_CHARS only defined when WIN_VER >= 0x600 - but stdafx.h defines it as 0x500 |
| 510 | int size = WideCharToMultiByte(CP_UTF8, 0/*WC_ERR_INVALID_CHARS*/, m_pWcStr, -1, NULL, 0, NULL, NULL); |
| 511 | if (size == 0) |
| 512 | throw std::runtime_error("Unable to convert to UTF-8: " + std::string(value)); |
| 513 | if (size > m_mbStrSize) |
| 514 | { |
| 515 | delete[] m_pMbStr; |
| 516 | m_pMbStr = new char[size]; |
| 517 | m_mbStrSize = size; |
| 518 | } |
| 519 | int res = WideCharToMultiByte(CP_UTF8, 0/*WC_ERR_INVALID_CHARS*/, m_pWcStr, -1, m_pMbStr, m_mbStrSize, NULL, NULL); |
| 520 | if (!res) |
| 521 | throw std::runtime_error("Unable to convert to UTF-8: " + std::string(value)); |
| 522 | } |
| 523 | |
| 524 | // A string in quotes needs double-backslashes, otherwise backslash treated as an escape-character (GH#1499) |
| 525 | if (std::string(m_pMbStr).find("\\") != std::string::npos) |
| 526 | { |
| 527 | std::string str(m_pMbStr); |
| 528 | size_t pos = 0; |
| 529 | while ((pos = str.find("\\", pos)) != std::string::npos) |
| 530 | { |
| 531 | str = str.replace(pos, 1, "\\\\"); |
| 532 | pos += 2; |
| 533 | } |
| 534 | const size_t size = str.size() + 1; |
| 535 | delete[] m_pMbStr; |
| 536 | m_pMbStr = new char[size]; |
| 537 | strncpy_s(m_pMbStr, size, str.c_str(), _TRUNCATE); |
| 538 | m_mbStrSize = (int)size; |
| 539 | } |
| 540 |
no outgoing calls
no test coverage detected