Browse Source

Replace ucs2tochar* with ucs2_to_utf8* to handle Unicode

Luke Dashjr 12 years ago
parent
commit
b39fac5de6
3 changed files with 27 additions and 10 deletions
  1. 3 3
      fpgautils.c
  2. 22 5
      util.c
  3. 2 2
      util.h

+ 3 - 3
fpgautils.c

@@ -362,7 +362,7 @@ char *windows_usb_get_port_path(HANDLE hubh, const int portno)
 	if (!(DeviceIoControl(hubh, IOCTL_USB_GET_NODE_CONNECTION_NAME, path, bufsz, path, bufsz, &rsz, NULL) && rsz >= sizeof(*path)))
 		applogfailinfor(NULL, LOG_ERR, "ioctl (2)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
 	
-	return ucs2tochar_dup(path->NodeName, path->ActualLength);
+	return ucs2_to_utf8_dup(path->NodeName, path->ActualLength);
 }
 
 static
@@ -395,7 +395,7 @@ char *windows_usb_get_string(HANDLE hubh, const int portno, const uint8_t descid
 	if (descsz < 2 || desc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE || desc->bLength > descsz - sizeof(USB_DESCRIPTOR_REQUEST) || desc->bLength % 2)
 		applogfailr(NULL, LOG_ERR, "sanity check");
 	
-	return ucs2tochar_dup(desc->bString, desc->bLength);
+	return ucs2_to_utf8_dup(desc->bString, desc->bLength);
 }
 
 static void _vcom_devinfo_scan_windows__hub(struct lowlevel_device_info **, const char *);
@@ -513,7 +513,7 @@ char *windows_usb_get_root_hub_path(HANDLE hcntlrh)
 	if (!(DeviceIoControl(hcntlrh, IOCTL_USB_GET_ROOT_HUB_NAME, NULL, 0, hubpath, bufsz, &rsz, NULL) && rsz >= sizeof(*hubpath)))
 		applogfailinfor(NULL, LOG_ERR, "ioctl (2)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
 	
-	return ucs2tochar_dup(hubpath->RootHubName, hubpath->ActualLength);
+	return ucs2_to_utf8_dup(hubpath->RootHubName, hubpath->ActualLength);
 }
 
 static

+ 22 - 5
util.c

@@ -727,16 +727,33 @@ badchar:
 	return likely(!hexstr[0]);
 }
 
-void ucs2tochar(char * const out, const uint16_t * const in, const size_t sz)
+size_t ucs2_to_utf8(char * const out, const uint16_t * const in, const size_t sz)
 {
+	uint8_t *p = (void*)out;
 	for (int i = 0; i < sz; ++i)
-		out[i] = in[i];
+	{
+		const uint16_t c = in[i];
+		if (c < 0x80)
+			p++[0] = c;
+		else
+		{
+			if (c < 0x800)
+				p++[0] = 0xc0 | (c >> 6);
+			else
+			{
+				p++[0] = 0xe0 | (c >> 12);
+				p++[0] = 0x80 | ((c >> 6) & 0x3f);
+			}
+			p++[0] = 0x80 | (c & 0x3f);
+		}
+	}
+	return p - (uint8_t*)(void*)out;
 }
 
-char *ucs2tochar_dup(uint16_t * const in, const size_t sz)
+char *ucs2_to_utf8_dup(uint16_t * const in, size_t sz)
 {
-	char *out = malloc(sz + 1);
-	ucs2tochar(out, in, sz);
+	char * const out = malloc((sz * 4) + 1);
+	sz = ucs2_to_utf8(out, in, sz);
 	out[sz] = '\0';
 	return out;
 }

+ 2 - 2
util.h

@@ -113,8 +113,8 @@ extern json_t *json_rpc_call_completed(CURL *, int rc, bool probe, int *rolltime
 
 extern char *absolute_uri(char *uri, const char *ref);  // ref must be a root URI
 
-extern void ucs2tochar(char *out, const uint16_t *in, size_t sz);
-extern char *ucs2tochar_dup(uint16_t *in, size_t sz);
+extern size_t ucs2_to_utf8(char *out, const uint16_t *in, size_t sz);
+extern char *ucs2_to_utf8_dup(uint16_t *in, size_t sz);
 
 #define BFGINIT(var, val)  do{  \
 	if (!(var))       \