Support UTF8 to UTF16 LE

This commit is contained in:
2026-03-31 14:10:21 +11:00
parent 0c24096c80
commit 70be68d0fc
14 changed files with 790 additions and 11 deletions

View File

@@ -1583,7 +1583,7 @@ namespace ANSCENTER {
}
LogThreadSafe("ANSFacialRecognition::UpdateUser",
"Successfully updated user ID " + std::to_string(userId));
"Successfully updated user ID " + std::to_string(userId), LogLevel::Info);
return result;
}
@@ -2350,6 +2350,32 @@ namespace ANSCENTER {
}
// Using nlohmann/json (much faster)
static std::string DoubleEscapeUnicode(const std::string& utf8Str) {
bool hasNonAscii = false;
for (unsigned char c : utf8Str) {
if (c >= 0x80) { hasNonAscii = true; break; }
}
if (!hasNonAscii) return utf8Str;
std::string result;
result.reserve(utf8Str.size() * 2);
size_t i = 0;
while (i < utf8Str.size()) {
unsigned char c = static_cast<unsigned char>(utf8Str[i]);
if (c < 0x80) { result += utf8Str[i++]; continue; }
uint32_t cp = 0;
if ((c & 0xE0) == 0xC0 && i + 1 < utf8Str.size()) {
cp = ((c & 0x1F) << 6) | (static_cast<unsigned char>(utf8Str[i + 1]) & 0x3F); i += 2;
} else if ((c & 0xF0) == 0xE0 && i + 2 < utf8Str.size()) {
cp = ((c & 0x0F) << 12) | ((static_cast<unsigned char>(utf8Str[i + 1]) & 0x3F) << 6) | (static_cast<unsigned char>(utf8Str[i + 2]) & 0x3F); i += 3;
} else if ((c & 0xF8) == 0xF0 && i + 3 < utf8Str.size()) {
cp = ((c & 0x07) << 18) | ((static_cast<unsigned char>(utf8Str[i + 1]) & 0x3F) << 12) | ((static_cast<unsigned char>(utf8Str[i + 2]) & 0x3F) << 6) | (static_cast<unsigned char>(utf8Str[i + 3]) & 0x3F); i += 4;
} else { i++; continue; }
if (cp <= 0xFFFF) { char buf[8]; snprintf(buf, sizeof(buf), "\\u%04x", cp); result += buf; }
else { cp -= 0x10000; char buf[16]; snprintf(buf, sizeof(buf), "\\u%04x\\u%04x", 0xD800 + (uint16_t)(cp >> 10), 0xDC00 + (uint16_t)(cp & 0x3FF)); result += buf; }
}
return result;
}
std::string ANSFacialRecognition::FaceObjectsToJsonString(const std::vector<FaceResultObject>& faces) {
START_TIMER(json_total);
@@ -2361,7 +2387,7 @@ namespace ANSCENTER {
for (const auto& face : faces) {
results.push_back({
{"user_id", face.userId},
{"user_name", face.userName},
{"user_name", DoubleEscapeUnicode(face.userName)},
{"similarity", std::to_string(face.similarity)},
{"is_unknown", std::to_string(face.isUnknown)},
{"prob", std::to_string(face.confidence)},
@@ -2399,7 +2425,7 @@ namespace ANSCENTER {
nlohmann::json detectedNode;
detectedNode["class_id"] = std::to_string(det.classId);
detectedNode["track_id"] = std::to_string(det.trackId);
detectedNode["class_name"] = det.className;
detectedNode["class_name"] = DoubleEscapeUnicode(det.className);
detectedNode["prob"] = std::to_string(det.confidence);
detectedNode["x"] = std::to_string(det.box.x);
detectedNode["y"] = std::to_string(det.box.y);