- static bool already_loaded = FALSE;
-
- if (already_loaded) return;
-
- already_loaded = TRUE;
-#if defined(__UNIX__) && wxUSE_TEXTFILE
- // search through files in /usr/share/i18n/charmaps
- wxString fname;
- for (fname = ::wxFindFirstFile(_T("/usr/share/i18n/charmaps/*"));
- !fname.IsEmpty();
- fname = ::wxFindNextFile()) {
- wxTextFile cmap(fname);
- if (cmap.Open()) {
- wxCharacterSet *cset = new wxCharacterSet;
- wxString comchar,escchar;
- bool in_charset = FALSE;
-
- // wxFprintf(stderr,_T("Loaded: %s\n"),fname.c_str());
-
- wxString line;
- for (line = cmap.GetFirstLine();
- !cmap.Eof();
- line = cmap.GetNextLine()) {
- // wxFprintf(stderr,_T("line contents: %s\n"),line.c_str());
- wxStringTokenizer token(line);
- wxString cmd = token.GetNextToken();
- if (cmd == comchar) {
- if (token.GetNextToken() == _T("alias"))
- cset->names.Add(token.GetNextToken());
- }
- else if (cmd == _T("<code_set_name>"))
- cset->names.Add(token.GetNextToken());
- else if (cmd == _T("<comment_char>"))
- comchar = token.GetNextToken();
- else if (cmd == _T("<escape_char>"))
- escchar = token.GetNextToken();
- else if (cmd == _T("<mb_cur_min>")) {
- delete cset;
- cset = (wxCharacterSet *) NULL;
- break; // we don't support multibyte charsets ourselves (yet)
- }
- else if (cmd == _T("CHARMAP")) {
- cset->data = (wchar_t *)calloc(256, sizeof(wchar_t));
- in_charset = TRUE;
- }
- else if (cmd == _T("END")) {
- if (token.GetNextToken() == _T("CHARMAP"))
- in_charset = FALSE;
- }
- else if (in_charset) {
- // format: <NUL> /x00 <U0000> NULL (NUL)
- // <A> /x41 <U0041> LATIN CAPITAL LETTER A
- wxString hex = token.GetNextToken();
- // skip whitespace (why doesn't wxStringTokenizer do this?)
- while (wxIsEmpty(hex) && token.HasMoreTokens()) hex = token.GetNextToken();
- wxString uni = token.GetNextToken();
- // skip whitespace again
- while (wxIsEmpty(uni) && token.HasMoreTokens()) uni = token.GetNextToken();
- if ((hex.Len() > 2) && (wxString(hex.GetChar(0)) == escchar) && (hex.GetChar(1) == _T('x')) &&
- (uni.Left(2) == _T("<U"))) {
- hex.MakeUpper(); uni.MakeUpper();
- int pos = ::wxHexToDec(hex.Mid(2,2));
- if (pos>=0) {
- unsigned long uni1 = ::wxHexToDec(uni.Mid(2,2));
- unsigned long uni2 = ::wxHexToDec(uni.Mid(4,2));
- cset->data[pos] = (uni1 << 16) | uni2;
- // wxFprintf(stderr,_T("char %02x mapped to %04x (%c)\n"),pos,cset->data[pos],cset->data[pos]);
- }
- }
- }
- }
- if (cset) {
- cset->names.Shrink();
- wxCharsets.Add(cset);
- }
+public:
+ iconv_t m2w, w2m;
+ IC_CharSet(const wxChar*name) : wxCharacterSet(name), m2w((iconv_t)-1), w2m((iconv_t)-1) {}
+ ~IC_CharSet() {
+ if (m2w!=(iconv_t)-1) iconv_close(m2w);
+ if (w2m!=(iconv_t)-1) iconv_close(w2m);
+ }
+ void LoadM2W() { if (m2w==(iconv_t)-1) m2w=iconv_open(WC_NAME,wxConvLibc.cWX2MB(cname)); }
+ void LoadW2M() { if (w2m==(iconv_t)-1) w2m=iconv_open(wxConvLibc.cWX2MB(cname),WC_NAME); }
+ size_t MB2WC(wchar_t*buf, const char*psz, size_t n) {
+ LoadM2W();
+ size_t inbuf = strlen(psz);
+ size_t outbuf = n*SIZEOF_WCHAR_T;
+ size_t res, cres;
+ fprintf(stderr,"IC Convert to WC using %s\n",(const char*)wxConvLibc.cWX2MB(cname));
+ if (buf) {
+ // have destination buffer, convert there
+ cres = iconv(m2w,&psz,&inbuf,(char**)&buf,&outbuf);
+ res = n-(outbuf/SIZEOF_WCHAR_T);
+ // convert to native endianness
+ WC_BSWAP(buf, res)
+ } else {
+ // no destination buffer... convert using temp buffer
+ // to calculate destination buffer requirement
+ wchar_t tbuf[8];
+ res = 0;
+ do {
+ buf = tbuf; outbuf = 8*SIZEOF_WCHAR_T;
+ cres = iconv(m2w,&psz,&inbuf,(char**)&buf,&outbuf);
+ res += 8-(outbuf/SIZEOF_WCHAR_T);
+ } while ((cres==(size_t)-1) && (errno==E2BIG));