USB Kit: Use libtextencoding to perform character set conversions.

This way USB devices with actual Unicode names will not be mangled.
Change-Id: I59b50d38776f185cbdb4df9763608341c059a163
This commit is contained in:
Augustin Cavalier
2022-01-26 13:44:14 -05:00
parent eecf3977a5
commit ebd5ba380d
2 changed files with 30 additions and 9 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
USBEndpoint.cpp
USBInterface.cpp
USBRoster.cpp
: be [ TargetLibsupc++ ]
: be textencoding [ TargetLibsupc++ ]
;
}
}
+29 -8
View File
@@ -6,8 +6,10 @@
* Michael Lotz <[email protected]>
*/
#include <ByteOrder.h>
#include <USBKit.h>
#include <usb_raw.h>
#include <UTF8.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -269,21 +271,40 @@ BUSBDevice::DecodeStringDescriptor(uint32 index) const
usb_string_descriptor *stringDescriptor;
stringDescriptor = (usb_string_descriptor *)&buffer;
size_t stringLength = GetStringDescriptor(index, stringDescriptor,
sizeof(buffer) - sizeof(usb_string_descriptor));
int32 stringLength = GetStringDescriptor(index, stringDescriptor,
sizeof(buffer) - sizeof(usb_string_descriptor)) - 1;
if (stringLength < 3)
return NULL;
// pseudo convert unicode string
stringLength = (stringLength - 2) / 2;
char *result = new(std::nothrow) char[stringLength + 1];
int32 resultLength = 0;
// USB is always little-endian, UCS-2 is big-endian.
uint16* ustr = (uint16*)stringDescriptor->string;
for (int32 i = 0; i < (stringLength / 2); i++) {
// Increase size of result as needed by source character.
const uint16 character = B_LENDIAN_TO_HOST_INT16(ustr[i]);
resultLength++;
if (character >= 0x80)
resultLength++;
if (character >= 0x800)
resultLength++;
ustr[i] = B_SWAP_INT16(ustr[i]);
}
char *result = new(std::nothrow) char[resultLength + 1];
if (result == NULL)
return NULL;
for (size_t i = 0; i < stringLength; i++)
result[i] = stringDescriptor->string[i * 2];
result[stringLength] = 0;
status_t status = convert_to_utf8(B_UNICODE_CONVERSION,
(const char*)stringDescriptor->string, &stringLength,
result, &resultLength, NULL);
if (status != B_OK) {
delete[] result;
return NULL;
}
result[resultLength] = 0;
return result;
}