Platform: Improve Windows wstring support

pull/73/head
David Rebbe 2025-02-06 18:43:51 +00:00 committed by Kyle Schwarz
parent c5ba2d8d32
commit f04cd16bee
7 changed files with 85 additions and 14 deletions

View File

@ -111,6 +111,7 @@ endif()
if(WIN32)
set(PLATFORM_SRC
platform/windows/strings.cpp
platform/windows/registry.cpp
)
@ -527,6 +528,7 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
test/unit/livedataencoderdecodertest.cpp
test/unit/ringbuffertest.cpp
test/unit/apperrordecodertest.cpp
test/unit/windowsstrings.cpp
)
target_link_libraries(libicsneo-unit-tests gtest gtest_main)

View File

@ -0,0 +1,22 @@
#ifndef __WINDOWS_STRINGS_H__
#define __WINDOWS_STRINGS_H__
#ifdef __cplusplus
#include <string>
namespace icsneo {
// Helper function to convert UTF-16 to UTF-8 strings (wide to standard)
std::string convertWideString(const std::wstring& value);
// Helper function to convert UTF-8 to UTF-16 strings (standard to wide)
std::wstring convertStringToWide(const std::string& value);
};
#endif // __cplusplus
#endif // __WINDOWS_STRINGS_H__

View File

@ -2,6 +2,7 @@
#include <winsock2.h>
#include "icsneo/platform/windows/pcap.h"
#include "icsneo/platform/windows/strings.h"
#include "icsneo/communication/network.h"
#include "icsneo/communication/communication.h"
#include "icsneo/communication/ethernetpacketizer.h"
@ -11,14 +12,12 @@
#include <pcap.h>
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
#include <codecvt>
#include <chrono>
#include <iostream>
#include <locale>
using namespace icsneo;
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::vector<PCAP::NetworkInterface> PCAP::knownInterfaces;
@ -80,8 +79,8 @@ void PCAP::Find(std::vector<FoundDevice>& found) {
memcpy(iface.macAddress, aa->PhysicalAddress, sizeof(iface.macAddress));
iface.nameFromWin32API = aa->AdapterName;
iface.descriptionFromWin32API = converter.to_bytes(aa->Description);
iface.friendlyNameFromWin32API = converter.to_bytes(aa->FriendlyName);
iface.descriptionFromWin32API = convertWideString(aa->Description);
iface.friendlyNameFromWin32API = convertWideString(aa->FriendlyName);
if(iface.descriptionFromWin32API.find("LAN9512/LAN9514") != std::string::npos) {
// This is an Ethernet EVB device
iface.fullName = "Intrepid Ethernet EVB ( " + iface.friendlyNameFromWin32API + " : " + iface.descriptionFromWin32API + " )";
@ -187,7 +186,7 @@ bool PCAP::IsHandleValid(neodevice_handle_t handle) {
return (netifIndex < knownInterfaces.size());
}
PCAP::PCAP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice), pcap(PCAPDLL::getInstance()), ethPacketizer(err) {
PCAP::PCAP(const device_eventhandler_t& eventHandler, neodevice_t& forDevice) : Driver(eventHandler), pcap(PCAPDLL::getInstance()), device(forDevice), ethPacketizer(eventHandler) {
if(IsHandleValid(device.handle)) {
iface = knownInterfaces[(device.handle >> 24) & 0xFF];
iface.fp = nullptr; // We're going to open our own connection to the interface. This should already be nullptr but just in case.

View File

@ -1,4 +1,5 @@
#include "icsneo/platform/windows/registry.h"
#include "icsneo/platform/windows/strings.h"
#include "icsneo/platform/windows.h"
#include <codecvt>
#include <vector>
@ -6,8 +7,6 @@
using namespace icsneo;
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
class Key {
public:
Key(std::wstring path, bool readwrite = false);
@ -95,8 +94,8 @@ bool Registry::Get(std::wstring path, std::wstring key, std::wstring& value) {
bool Registry::Get(std::string path, std::string key, std::string& value) {
std::wstring wvalue;
bool ret = Get(converter.from_bytes(path), converter.from_bytes(key), wvalue);
value = converter.to_bytes(wvalue);
bool ret = Get(convertStringToWide(path), convertStringToWide(key), wvalue);
value = convertWideString(wvalue);
return ret;
}
@ -116,5 +115,5 @@ bool Registry::Get(std::wstring path, std::wstring key, uint32_t& value) {
}
bool Registry::Get(std::string path, std::string key, uint32_t& value) {
return Get(converter.from_bytes(path), converter.from_bytes(key), value);
return Get(convertStringToWide(path), convertStringToWide(key), value);
}

View File

@ -0,0 +1,26 @@
#include <string>
#include <Windows.h>
#include <icsneo/platform/windows/strings.h>
// Helper function to convert UTF-16 to UTF-8 strings (wide to standard)
std::string icsneo::convertWideString(const std::wstring& value) {
// Get the width of the string (character count)
int width = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)value.c_str(), -1, 0, 0, NULL, NULL);
// Create the new string
std::string new_string(width+1, '\0');
// fill the new string with the converted characters
WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)value.c_str(), -1, new_string.data(), width, NULL, NULL);
return new_string;
};
// Helper function to convert UTF-8 to UTF-16 strings (standard to wide)
std::wstring icsneo::convertStringToWide(const std::string& value) {
// Get the width of the string (character count)
int width = MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, NULL, 0);
// Create the new string
std::wstring new_string(width+1, '\0');
// fill the new string with the converted characters
MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, (LPWSTR)new_string.data(), width);
return new_string;
}

View File

@ -1,4 +1,5 @@
#include "icsneo/platform/windows/ftdi.h"
#include "icsneo/platform/windows/strings.h"
#include "icsneo/platform/ftdi.h"
#include "icsneo/platform/registry.h"
#include "icsneo/device/founddevice.h"
@ -15,7 +16,6 @@
using namespace icsneo;
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
static const std::wstring DRIVER_SERVICES_REG_KEY = L"SYSTEM\\CurrentControlSet\\services\\";
static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\";
static constexpr unsigned int RETRY_TIMES = 5;
@ -95,7 +95,7 @@ void VCP::Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driver
if(!device.productId)
continue;
std::string serial = converter.to_bytes(oss.str());
std::string serial = convertWideString(oss.str());
// The serial number should not have a path slash in it. If it does, that means we don't have the real serial.
if(serial.find_first_of('\\') != std::string::npos) {
// The serial number was not in the first serenum key where we expected it.
@ -142,12 +142,12 @@ void VCP::Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driver
// This is a device with characters in the serial number
if(correctSerial.size() != 6)
continue;
serial = converter.to_bytes(correctSerial);
serial = convertWideString(correctSerial);
}
else {
std::wstringstream soss;
soss << sn;
serial = converter.to_bytes(soss.str());
serial = convertWideString(soss.str());
}
if(serial.find_first_of('\\') != std::string::npos)

View File

@ -0,0 +1,23 @@
#include <gtest/gtest.h>
#include <icsneo/platform/windows/strings.h>
#include <string>
TEST(WindowsUtilTest, testConvertWideString) {
#ifdef WIN32
std::wstring wideString(L"Hello World!");
auto normalString = icsneo::convertWideString(wideString);
ASSERT_STREQ(normalString.c_str(), "Hello World!");
#endif
}
TEST(WindowsUtilTest, testConvertStringToWide) {
#ifdef WIN32
std::string normalString("Hello World!");
auto wideString = icsneo::convertStringToWide(normalString);
ASSERT_STREQ(wideString.c_str(), L"Hello World!");
#endif
}