Support unicode APIs for LabVIEW
This commit is contained in:
@@ -77,7 +77,10 @@
|
|||||||
"Bash(find /c/Projects/CLionProjects/ANSCORE -type d -name *ANSODEngine*)",
|
"Bash(find /c/Projects/CLionProjects/ANSCORE -type d -name *ANSODEngine*)",
|
||||||
"Bash(powershell -Command \"\\(Get-Content ''C:\\\\Users\\\\nghia\\\\Downloads\\\\ANSLEGION41.log''\\).Count\")",
|
"Bash(powershell -Command \"\\(Get-Content ''C:\\\\Users\\\\nghia\\\\Downloads\\\\ANSLEGION41.log''\\).Count\")",
|
||||||
"Bash(powershell -Command \"\\(Get-Content ''C:\\\\Users\\\\nghia\\\\Downloads\\\\ANSLEGION42.log''\\).Count\")",
|
"Bash(powershell -Command \"\\(Get-Content ''C:\\\\Users\\\\nghia\\\\Downloads\\\\ANSLEGION42.log''\\).Count\")",
|
||||||
"Bash(grep -rn \"ApplyTracking\\\\|_trackerEnabled\" /c/Projects/CLionProjects/ANSCORE/modules/ANSODEngine/*.cpp)"
|
"Bash(grep -rn \"ApplyTracking\\\\|_trackerEnabled\" /c/Projects/CLionProjects/ANSCORE/modules/ANSODEngine/*.cpp)",
|
||||||
|
"Bash(cmake --build build --target ANSUtilities)",
|
||||||
|
"Bash(ls -d /c/Projects/CLionProjects/ANSCORE/cmake-build-* /c/Projects/CLionProjects/ANSCORE/out/*)",
|
||||||
|
"Bash(cmake --build /c/Projects/CLionProjects/ANSCORE/cmake-build-release --target ANSUtilities)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1002,5 +1002,55 @@ namespace ANSCENTER
|
|||||||
return utf8Str;
|
return utf8Str;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ANSUtilities::ConvertUTF16LEToUnicodeEscapes(const char* utf16leBytes, int byteLen) {
|
||||||
|
if (!utf16leBytes || byteLen <= 0) return "";
|
||||||
|
int offset = 0;
|
||||||
|
// Strip BOM (FF FE) if present
|
||||||
|
if (byteLen >= 2 &&
|
||||||
|
static_cast<unsigned char>(utf16leBytes[0]) == 0xFF &&
|
||||||
|
static_cast<unsigned char>(utf16leBytes[1]) == 0xFE) {
|
||||||
|
offset = 2;
|
||||||
|
}
|
||||||
|
int remaining = byteLen - offset;
|
||||||
|
if (remaining <= 0 || remaining % 2 != 0) return "";
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
result.reserve(remaining * 3);
|
||||||
|
for (int i = offset; i + 1 < byteLen; i += 2) {
|
||||||
|
uint16_t codepoint = static_cast<unsigned char>(utf16leBytes[i])
|
||||||
|
| (static_cast<unsigned char>(utf16leBytes[i + 1]) << 8);
|
||||||
|
if (codepoint >= 0x20 && codepoint <= 0x7E) {
|
||||||
|
result += static_cast<char>(codepoint);
|
||||||
|
} else {
|
||||||
|
char buf[7];
|
||||||
|
snprintf(buf, sizeof(buf), "\\u%04X", codepoint);
|
||||||
|
result += buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ANSUtilities::ConvertUnicodeEscapesToUTF8(const std::string& escapedStr) {
|
||||||
|
if (escapedStr.empty()) return "";
|
||||||
|
// First decode \uXXXX to UTF-16LE, then convert to UTF-8
|
||||||
|
std::string utf16le;
|
||||||
|
utf16le.reserve(escapedStr.size() * 2);
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < escapedStr.size()) {
|
||||||
|
if (i + 5 < escapedStr.size() && escapedStr[i] == '\\' && escapedStr[i + 1] == 'u') {
|
||||||
|
char hex[5] = { escapedStr[i + 2], escapedStr[i + 3], escapedStr[i + 4], escapedStr[i + 5], 0 };
|
||||||
|
uint16_t codepoint = (uint16_t)strtoul(hex, nullptr, 16);
|
||||||
|
utf16le += static_cast<char>(codepoint & 0xFF);
|
||||||
|
utf16le += static_cast<char>((codepoint >> 8) & 0xFF);
|
||||||
|
i += 6;
|
||||||
|
} else {
|
||||||
|
utf16le += escapedStr[i];
|
||||||
|
utf16le += '\0';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ConvertUTF16LEToUTF8(utf16le.data(), (int)utf16le.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,16 @@ namespace ANSCENTER {
|
|||||||
// Convert a UTF-16LE byte string to UTF-8.
|
// Convert a UTF-16LE byte string to UTF-8.
|
||||||
// Useful for receiving Unicode text from LabVIEW and converting to UTF-8 for internal processing.
|
// Useful for receiving Unicode text from LabVIEW and converting to UTF-8 for internal processing.
|
||||||
static std::string ConvertUTF16LEToUTF8(const char* utf16leBytes, int byteLen);
|
static std::string ConvertUTF16LEToUTF8(const char* utf16leBytes, int byteLen);
|
||||||
|
|
||||||
|
// Convert UTF-16LE byte string (with optional BOM) to Unicode escape sequences (\uXXXX).
|
||||||
|
// Input: raw UTF-16LE bytes (BOM is auto-stripped if present).
|
||||||
|
// Output: ASCII string with \uXXXX for non-ASCII codepoints, plain ASCII chars preserved.
|
||||||
|
static std::string ConvertUTF16LEToUnicodeEscapes(const char* utf16leBytes, int byteLen);
|
||||||
|
|
||||||
|
// Convert Unicode escape sequences (\uXXXX) to UTF-8 string.
|
||||||
|
// Input: ASCII string with \uXXXX escapes (e.g., "\\u6c5f\\u6771 599")
|
||||||
|
// Output: UTF-8 encoded Unicode string.
|
||||||
|
static std::string ConvertUnicodeEscapesToUTF8(const std::string& escapedStr);
|
||||||
};
|
};
|
||||||
// Connection bundle for pool
|
// Connection bundle for pool
|
||||||
struct S3Connection {
|
struct S3Connection {
|
||||||
@@ -247,6 +257,8 @@ extern "C" ANSULT_API int RebootSystem();
|
|||||||
extern "C" ANSULT_API int ANSConvertUTF8ToUTF16LE(const char* utf8Str, LStrHandle result, int includeBOM = 1);
|
extern "C" ANSULT_API int ANSConvertUTF8ToUTF16LE(const char* utf8Str, LStrHandle result, int includeBOM = 1);
|
||||||
extern "C" ANSULT_API int ANSDecodeJsonUnicodeToUTF16LE(const char* escapedStr, LStrHandle result);
|
extern "C" ANSULT_API int ANSDecodeJsonUnicodeToUTF16LE(const char* escapedStr, LStrHandle result);
|
||||||
extern "C" ANSULT_API int ANSConvertUTF16LEToUTF8(const unsigned char* utf16leBytes, int byteLen, LStrHandle result);
|
extern "C" ANSULT_API int ANSConvertUTF16LEToUTF8(const unsigned char* utf16leBytes, int byteLen, LStrHandle result);
|
||||||
|
extern "C" ANSULT_API int ANSConvertUTF16LEToUnicodeEscapes(const unsigned char* utf16leBytes, int byteLen, LStrHandle result);
|
||||||
|
extern "C" ANSULT_API int ANSConvertUnicodeEscapesToUTF8(const char* escapedStr, LStrHandle result);
|
||||||
|
|
||||||
// AWS S3 class
|
// AWS S3 class
|
||||||
|
|
||||||
|
|||||||
@@ -893,9 +893,40 @@ extern "C" ANSULT_API int ANSDecodeJsonUnicodeToUTF16LE(const char* escapedStr,
|
|||||||
catch (...) { return -1; }
|
catch (...) { return -1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" ANSULT_API int ANSConvertUTF16LEToUnicodeEscapes(const unsigned char* utf16leBytes, int byteLen, LStrHandle result) {
|
||||||
|
try {
|
||||||
|
if (!utf16leBytes || byteLen <= 0 || !result) return -1;
|
||||||
|
std::string escaped = ANSCENTER::ANSUtilities::ConvertUTF16LEToUnicodeEscapes(
|
||||||
|
reinterpret_cast<const char*>(utf16leBytes), byteLen);
|
||||||
|
if (escaped.empty()) return 0;
|
||||||
|
int size = static_cast<int>(escaped.size());
|
||||||
|
MgErr error = DSSetHandleSize(result, sizeof(int32) + size * sizeof(uChar));
|
||||||
|
if (error != noErr) return -2;
|
||||||
|
(*result)->cnt = size;
|
||||||
|
memcpy((*result)->str, escaped.data(), size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (...) { return -1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" ANSULT_API int ANSConvertUnicodeEscapesToUTF8(const char* escapedStr, LStrHandle result) {
|
||||||
|
try {
|
||||||
|
if (!escapedStr || !result) return -1;
|
||||||
|
int len = (int)strlen(escapedStr);
|
||||||
|
if (len == 0) return 0;
|
||||||
|
std::string utf8 = ANSCENTER::ANSUtilities::ConvertUnicodeEscapesToUTF8(escapedStr);
|
||||||
|
if (utf8.empty()) return 0;
|
||||||
|
int size = static_cast<int>(utf8.size());
|
||||||
|
MgErr error = DSSetHandleSize(result, sizeof(int32) + size * sizeof(uChar));
|
||||||
|
if (error != noErr) return -2;
|
||||||
|
(*result)->cnt = size;
|
||||||
|
memcpy((*result)->str, utf8.data(), size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (...) { return -1; }
|
||||||
|
}
|
||||||
|
|
||||||
// AWSS3
|
// AWSS3
|
||||||
extern "C" ANSULT_API int CreateANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* licenseKey) {
|
extern "C" ANSULT_API int CreateANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* licenseKey) {
|
||||||
if (Handle == nullptr || licenseKey == nullptr) return 0;
|
if (Handle == nullptr || licenseKey == nullptr) return 0;
|
||||||
if (*Handle) {
|
if (*Handle) {
|
||||||
|
|||||||
Reference in New Issue
Block a user