On Tue, Jun 06, 2006 at 06:38:04PM -0700, Rob Leslie wrote:
I'm not sure what's the best way to convert it from ucs4 to wchar_t though, and can't think of a portable way, and I'd love if someone could point me out how to do it.
(On Linux (glibc), casting it from a id3_ucs4_t to a wchar_t seems to work, but it's not portable.)
There's nothing wrong with this per se as long as wchar_t is at least 21 bits wide (for example, when __STDC_ISO_10646__ is defined) or you are sure the UCS-4 code point in question can otherwise be represented by a wchar_t -- and the relevant locale is compatible.
The biggest problem being that "the locale is compatible" means it's not very portable.
Note that casting id3_ucs4_t to wchar_t is not the same as casting (id3_ucs4_t *) to (wchar_t *); the latter is definitely not portable though it may work if the underlying types happen to have the same size.
As I pointed out, on 64 bit arches, they're typicaly of different size, so break.
A simple way to translate a UCS-4 string to wchar_t might be (untested):
wchar_t *ucs4_to_wchar(id3_ucs4_t const *ucs4) { wchar_t *wchar;
wchar = malloc(id3_ucs4_size(ucs4) * sizeof(wchar_t)); if (wchar) { wchar_t *ptr = wchar; while ((*ptr++ = (wchar_t) *ucs4++)) ; }
return wchar; }
I've used the following code: wchar_t *ucs4_to_wchar_strdup(const id3_ucs4_t *ucs4) { id3_length_t size = id3_ucs4_size(ucs4); wchar_t *s = malloc(size * sizeof(wchar_t)); id3_length_t i;
for (i = 0; i < size; i++) { s[i] = ucs4[i]; } return s; }
Which basicly does about the same, but doesn't do error checking, and seems to work. The problem however is that id3_ucs4_size isn't exported in the header files that get installed.
Anyway, I think now what might be more portable is that you just run iconv() to convert it from ucs4 to nl_langinfo(CODESET); If you want, you can then convert things with something like mbtowc() to a wchar_t afterwards, but this isn't needed.
Note that iconv() might not be able to represent everything in CODESET, but you'll have that problem anyway once you try to output it.
I'll try and send a patch for madplayer/player.c later, if you think this should work and is acceptable. I'm just not sure how happy you are about things that are SUS/POSIX specific, since both iconv() and nl_langinfo() are.
Kurt