[MPlayer-dev-eng] [PATCH] implement the setlocale feature
Fengguang Wu
fengguang.wu at gmail.com
Tue Jun 20 10:30:35 CEST 2006
On Mon, Jun 19, 2006 at 11:36:39AM +0200, Reimar Döffinger wrote:
> Hi,
> On Mon, Jun 19, 2006 at 12:55:36PM +0800, Fengguang Wu wrote:
> > Attached a patch using UTF-8 unconditionally, comments are welcome.
>
> Much better, but still the original code is really broken.
> 1) There are already utf8->utf16 conversion functions in MPlayer, like
> libvo/sub.c, utf8_get_char so iconv is not needed.
> 2) Stuff like strlen(path)*2 to get the length of UTF-16 string will only
> work for pure ascii as well...
Thanks, updated the patch according to your comments.
I take the freedom to write a new utf8to16() function which was
originally written by Masanao Izumo <iz at onicos.co.jp>.
It can detect non-utf8 sequences. The intension is to fall back to
local charset if necessary. It's a worthy hack, IMHO.
Regards,
Wu
-------------- next part --------------
Index: libmpdemux/asf_mmst_streaming.c
===================================================================
--- libmpdemux/asf_mmst_streaming.c (revision 18754)
+++ libmpdemux/asf_mmst_streaming.c (working copy)
@@ -25,17 +25,6 @@
#include <winsock2.h>
#endif
-#ifndef USE_SETLOCALE
-#undef USE_ICONV
-#endif
-
-#ifdef USE_ICONV
-#include <iconv.h>
-#ifdef USE_LANGINFO
-#include <langinfo.h>
-#endif
-#endif
-
#include "url.h"
#include "asf.h"
@@ -119,40 +108,62 @@
}
}
-#ifdef USE_ICONV
-static iconv_t url_conv;
-#endif
+static char * utf8to16(char *dest, char *src, int len)
+{
+ int i;
+ unsigned char c, char2, char3;
+ long cc;
-static void string_utf16(char *dest, char *src, int len) {
- int i;
-#ifdef USE_ICONV
- size_t len1, len2;
- char *ip, *op;
+ i = 0;
+ while(i < len) {
+ c = src[i++];
+ switch(c >> 4) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+ // 0xxxxxxx
+ cc = c;
+ break;
+ case 12: case 13:
+ // 110x xxxx 10xx xxxx
+ char2 = src[i++];
+ if ((char2 & 0xC0) == 0x80)
+ cc = ((c & 0x1F) << 6) | (char2 & 0x3F);
+ else
+ cc = -1;
+ break;
+ case 14:
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ char2 = src[i++];
+ char3 = src[i++];
+ if ((char2 & 0xC0) == 0x80 && (char3 & 0xC0) == 0x80)
+ cc = ((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | (char3 & 0x3F);
+ else
+ cc = -1;
+ break;
+ default:
+ cc = -1;
+ }
- if (url_conv != (iconv_t)(-1))
- {
- memset(dest, 0, 1000);
- len1 = len; len2 = 1000;
- ip = src; op = dest;
+ if (cc == -1)
+ return 0;
- iconv(url_conv, &ip, &len1, &op, &len2);
- }
- else
- {
-#endif
- if (len > 499) len = 499;
- for (i=0; i<len; i++) {
- dest[i*2] = src[i];
- dest[i*2+1] = 0;
- }
- /* trailing zeroes */
- dest[i*2] = 0;
- dest[i*2+1] = 0;
-#ifdef USE_ICONV
- }
-#endif
+ *dest++ = cc;
+ *dest++ = cc >> 8;
+ }
+ return dest;
}
+static int string_utf16(char *dest, char *src, int len)
+{
+ char *end = utf8to16(dest, src, len);
+
+ if (end)
+ return (end - dest) / 2;
+
+ /* TODO: try to convert from local charset */
+ /* printf("utf8to16(%s, %d) failed\n", src, len); */
+ return 0;
+}
+
static void get_answer (int s)
{
char data[BUF_SIZE];
@@ -550,19 +561,10 @@
* cmd 1 0x01
* */
- /* prepare for the url encoding conversion */
-#ifdef USE_ICONV
-#ifdef USE_LANGINFO
- url_conv = iconv_open("UTF-16LE",nl_langinfo(CODESET));
-#else
- url_conv = iconv_open("UTF-16LE", NULL);
-#endif
-#endif
-
snprintf (str, 1023, "\034\003NSPlayer/7.0.0.1956; {33715801-BAB3-9D85-24E9-03B90328270A}; Host: %s", url1->hostname);
- string_utf16 (data, str, strlen(str));
+ len = string_utf16 (data, str, strlen(str));
// send_command(s, commandno ....)
- send_command (s, 1, 0, 0x0004000b, strlen(str)*2+2, data);
+ send_command (s, 1, 0, 0x0004000b, len*2+2, data);
len = recv (s, data, BUF_SIZE, 0) ;
@@ -583,9 +585,9 @@
/* This command sends file path (at server) and file name request to the server.
* 0x5 */
- string_utf16 (&data[8], path, strlen(path));
+ len = string_utf16 (&data[8], path, strlen(path));
memset (data, 0, 8);
- send_command (s, 5, 0, 0, strlen(path)*2+10, data);
+ send_command (s, 5, 0, 0, len*2+10, data);
free(path);
get_answer (s);
@@ -656,10 +658,5 @@
packet_length1 = packet_length;
mp_msg(MSGT_NETWORK,MSGL_INFO,"mmst packet_length = %d\n", packet_length);
-#ifdef USE_ICONV
- if (url_conv != (iconv_t)(-1))
- iconv_close(url_conv);
-#endif
-
return 0;
}
More information about the MPlayer-dev-eng
mailing list