123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmProcessOutput.h"
- #if defined(_WIN32)
- #include <windows.h>
- unsigned int cmProcessOutput::defaultCodepage =
- KWSYS_ENCODING_DEFAULT_CODEPAGE;
- #endif
- cmProcessOutput::Encoding cmProcessOutput::FindEncoding(
- std::string const& name)
- {
- Encoding encoding = Auto;
- if ((name == "UTF8") || (name == "UTF-8")) {
- encoding = UTF8;
- } else if (name == "NONE") {
- encoding = None;
- } else if (name == "ANSI") {
- encoding = ANSI;
- } else if (name == "OEM") {
- encoding = OEM;
- }
- return encoding;
- }
- cmProcessOutput::cmProcessOutput(Encoding encoding, unsigned int maxSize)
- {
- #if defined(_WIN32)
- codepage = 0;
- bufferSize = maxSize;
- if (encoding == None) {
- codepage = defaultCodepage;
- } else if (encoding == Auto) {
- codepage = GetConsoleCP();
- } else if (encoding == UTF8) {
- codepage = CP_UTF8;
- } else if (encoding == OEM) {
- codepage = GetOEMCP();
- }
- if (!codepage || encoding == ANSI) {
- codepage = GetACP();
- }
- #else
- static_cast<void>(encoding);
- static_cast<void>(maxSize);
- #endif
- }
- cmProcessOutput::~cmProcessOutput()
- {
- }
- bool cmProcessOutput::DecodeText(std::string raw, std::string& decoded,
- size_t id)
- {
- #if !defined(_WIN32)
- static_cast<void>(id);
- decoded.swap(raw);
- return true;
- #else
- bool success = true;
- decoded = raw;
- if (id > 0) {
- if (rawparts.size() < id) {
- rawparts.reserve(id);
- while (rawparts.size() < id)
- rawparts.push_back(std::string());
- }
- raw = rawparts[id - 1] + raw;
- rawparts[id - 1].clear();
- decoded = raw;
- }
- if (raw.size() > 0 && codepage != defaultCodepage) {
- success = false;
- CPINFOEXW cpinfo;
- if (id > 0 && bufferSize > 0 && raw.size() == bufferSize &&
- GetCPInfoExW(codepage, 0, &cpinfo) == 1 && cpinfo.MaxCharSize > 1) {
- if (cpinfo.MaxCharSize == 2 && cpinfo.LeadByte[0] != 0) {
- LPSTR prevChar =
- CharPrevExA(codepage, raw.c_str(), raw.c_str() + raw.size(), 0);
- bool isLeadByte =
- (*(prevChar + 1) == 0) && IsDBCSLeadByteEx(codepage, *prevChar);
- if (isLeadByte) {
- rawparts[id - 1] += *(raw.end() - 1);
- raw.resize(raw.size() - 1);
- }
- success = DoDecodeText(raw, decoded, NULL);
- } else {
- bool restoreDecoded = false;
- std::string firstDecoded = decoded;
- wchar_t lastChar = 0;
- for (UINT i = 0; i < cpinfo.MaxCharSize; i++) {
- success = DoDecodeText(raw, decoded, &lastChar);
- if (success && lastChar != 0) {
- if (i == 0) {
- firstDecoded = decoded;
- }
- if (lastChar == cpinfo.UnicodeDefaultChar) {
- restoreDecoded = true;
- rawparts[id - 1] = *(raw.end() - 1) + rawparts[id - 1];
- raw.resize(raw.size() - 1);
- } else {
- restoreDecoded = false;
- break;
- }
- } else {
- break;
- }
- }
- if (restoreDecoded) {
- decoded = firstDecoded;
- rawparts[id - 1].clear();
- }
- }
- } else {
- success = DoDecodeText(raw, decoded, NULL);
- }
- }
- return success;
- #endif
- }
- bool cmProcessOutput::DecodeText(const char* data, size_t length,
- std::string& decoded, size_t id)
- {
- return DecodeText(std::string(data, length), decoded, id);
- }
- bool cmProcessOutput::DecodeText(std::vector<char> raw,
- std::vector<char>& decoded, size_t id)
- {
- std::string str;
- const bool success =
- DecodeText(std::string(raw.begin(), raw.end()), str, id);
- decoded.assign(str.begin(), str.end());
- return success;
- }
- #if defined(_WIN32)
- bool cmProcessOutput::DoDecodeText(std::string raw, std::string& decoded,
- wchar_t* lastChar)
- {
- bool success = false;
- const int wlength =
- MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), NULL, 0);
- wchar_t* wdata = new wchar_t[wlength];
- int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), wdata,
- wlength);
- if (r > 0) {
- if (lastChar) {
- *lastChar = 0;
- if ((wlength >= 2 && wdata[wlength - 2] != wdata[wlength - 1]) ||
- wlength >= 1) {
- *lastChar = wdata[wlength - 1];
- }
- }
- int length = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, NULL,
- 0, NULL, NULL);
- char* data = new char[length];
- r = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, data, length,
- NULL, NULL);
- if (r > 0) {
- decoded = std::string(data, length);
- success = true;
- }
- delete[] data;
- }
- delete[] wdata;
- return success;
- }
- #endif
|