Max 5 API Reference
00001 /* 00002 * jit.charset.c 00003 * JitterAPI 00004 * 00005 * Created by Jeremy Bernstein on 24.05.06. 00006 * Copyright 2006 Cycling '74. All rights reserved. 00007 * 00008 */ 00009 00010 #include "ext.h" 00011 #include "ext_obex.h" 00012 #include "ext_strings.h" 00013 #include "jit.common.h" 00014 #include "jit.charset.h" 00015 00016 #ifdef MAC_VERSION 00017 #if !TARGET_RT_MAC_MACHO 00018 #include "jit.charset.iconv.h" 00019 static CFBundleRef sysBundle; 00020 #else 00021 #define LIBICONV_STATIC // this is necessary on PPC 00022 #include <iconv.h> 00023 #endif 00024 #else 00025 #include <windows.h> 00026 #endif 00027 00028 #ifdef MAC_VERSION 00029 typedef iconv_t (*iconv_openPtr)(const char* tocode, const char* fromcode); 00030 typedef size_t (*iconvPtr)(iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft); 00031 typedef int (*iconv_closePtr)(iconv_t cd); 00032 00033 iconv_openPtr jit_charset_iconv_open; 00034 iconvPtr jit_charset_iconv; 00035 iconv_closePtr jit_charset_iconv_close; 00036 00037 #define charset_iso_8859_1 "ISO-8859-1" 00038 #define charset_utf_8 "UTF-8" 00039 #define charset_utf_16 "UTF-16BE" // we'll use big-endian by default 00040 #define charset_utf_16be "UTF-16BE" 00041 #define charset_utf_16le "UTF-16LE" 00042 #define charset_us_ascii "US-ASCII" 00043 #define charset_macroman "MACROMAN" 00044 #define charset_ms_ansi "MS-ANSI" // WINDOWS-1252 00045 #else 00046 #define charset_iso_8859_1 28591 // "ISO-8859-1" 00047 #define charset_utf_8 CP_UTF8 00048 #define charset_utf_16 1201 // "UTF-16", big-endian :: 1200, little-endian 00049 #define charset_utf_16be 1201 // "UTF-16", big-endian :: 1200, little-endian 00050 #define charset_utf_16le 1200 // "UTF-16", big-endian :: 1200, little-endian 00051 #define charset_us_ascii 20127 00052 #define charset_macroman CP_MACCP 00053 #define charset_ms_ansi 1252 // WINDOWS-1252 00054 #endif 00055 00056 t_symbol *ps_utf_8; 00057 t_symbol *ps_utf_16; 00058 t_symbol *ps_utf_16be; 00059 t_symbol *ps_utf_16le; 00060 t_symbol *ps_iso_8859_1; 00061 t_symbol *ps_us_ascii; 00062 t_symbol *ps_ms_ansi; 00063 t_symbol *ps_macroman; 00064 00065 t_symbol *ps_convert; 00066 t_symbol *ps_jit_charset_converter; 00067 00068 t_class *_jit_charset_converter_class=NULL; 00069 00070 t_jit_err jit_charset_init(void); 00071 t_jit_charset_converter *jit_charset_converter_new(t_symbol *src, t_symbol *dst); 00072 void jit_charset_converter_free(t_jit_charset_converter *x); 00073 t_jit_err jit_charset_converter_convert(t_jit_charset_converter *x, const char *in, long inbytes, char **out, long *outbytes); 00074 void *jit_charset_encoding_sym2enc(t_symbol *encoding); 00075 #ifdef MAC_VERSION 00076 void jit_charset_converter_initialize(t_jit_charset_converter *x); 00077 #if !TARGET_RT_MAC_MACHO 00078 void jit_charset_framework_init(void); 00079 #endif 00080 #endif 00081 00082 00083 t_jit_err jit_charset_init(void) 00084 { 00085 t_class *c; 00086 long attrflags=0; 00087 void *attr; 00088 00089 c = jit_class_new("jit_charset_converter", (method)jit_charset_converter_new, (method)jit_charset_converter_free, 00090 (short)sizeof(t_jit_charset_converter), A_CANT, 0); 00091 00092 jit_class_addmethod(c,(method)jit_charset_converter_convert, "convert", A_CANT, 0); 00093 00094 jit_class_register(c); 00095 _jit_charset_converter_class = c; 00096 00097 ps_utf_8 = gensym("utf-8"); 00098 ps_utf_16 = gensym("utf-16"); 00099 ps_utf_16be = gensym("utf-16be"); 00100 ps_utf_16le = gensym("utf-16le"); 00101 ps_iso_8859_1 = gensym("iso-8859-1"); 00102 ps_us_ascii = gensym("us-ascii"); 00103 ps_macroman = gensym("macroman"); 00104 ps_ms_ansi = gensym("ms-ansi"); 00105 00106 ps_convert = gensym("convert"); 00107 ps_jit_charset_converter = gensym("jit_charset_converter"); 00108 00109 #ifdef MAC_VERSION 00110 #if !TARGET_RT_MAC_MACHO 00111 jit_charset_framework_init(); 00112 #else 00113 jit_charset_iconv_open = iconv_open; 00114 jit_charset_iconv = iconv; 00115 jit_charset_iconv_close = iconv_close; 00116 #endif 00117 #endif 00118 00119 return 0; 00120 } 00121 00122 #if defined (MAC_VERSION) && (!TARGET_RT_MAC_MACHO) 00123 void jit_charset_framework_init(void) 00124 { 00125 OSStatus err; 00126 00127 err = LoadFrameworkBundle(CFSTR("System.framework"), &sysBundle); 00128 if (err == noErr) { 00129 jit_charset_iconv_open = (iconv_openPtr)CFBundleGetFunctionPointerForName 00130 (sysBundle, CFSTR("iconv_open")); 00131 jit_charset_iconv = (iconvPtr)CFBundleGetFunctionPointerForName 00132 (sysBundle, CFSTR("iconv")); 00133 jit_charset_iconv_close = (iconv_closePtr)CFBundleGetFunctionPointerForName 00134 (sysBundle, CFSTR("iconv_close")); 00135 } else { 00136 error("jit.charset: error %d in framework_init"); 00137 } 00138 } 00139 #endif 00140 00141 t_jit_charset_converter *jit_charset_converter_new(t_symbol *src, t_symbol *dst) 00142 { 00143 t_jit_charset_converter *x; 00144 00145 if (x = (t_jit_charset_converter *)object_alloc(_jit_charset_converter_class)) { 00146 x->src_encoding = NULL; 00147 x->dst_encoding = NULL; 00148 x->conv = NULL; 00149 00150 if (src && dst) { 00151 x->src_encoding = jit_charset_encoding_sym2enc(src); 00152 x->dst_encoding = jit_charset_encoding_sym2enc(dst); 00153 } 00154 if (!(x->src_encoding && x->dst_encoding)) { 00155 error("jit.charset: could not create new converter (bad or no character set supplied)"); 00156 freeobject((t_object *)x); 00157 return NULL; 00158 } 00159 #ifdef MAC_VERSION 00160 jit_charset_converter_initialize(x); 00161 if (!x->conv) { 00162 error("jit.charset: could not create new converter (error initializing converter)"); 00163 freeobject((t_object *)x); 00164 return NULL; 00165 } 00166 #endif 00167 } 00168 00169 return x; 00170 } 00171 00172 void jit_charset_converter_free(t_jit_charset_converter *x) 00173 { 00174 #ifdef MAC_VERSION 00175 if (x->conv) { 00176 jit_charset_iconv_close(x->conv); 00177 x->conv = NULL; 00178 } 00179 #endif 00180 } 00181 00182 #ifdef MAC_VERSION 00183 void jit_charset_converter_initialize(t_jit_charset_converter *x) 00184 { 00185 x->conv = jit_charset_iconv_open((char *)x->dst_encoding, (char *)x->src_encoding); 00186 if (!x->conv || x->conv == (void *)0xFFFFFFFF) 00187 x->conv = NULL; 00188 } 00189 #endif 00190 00191 t_jit_err jit_charset_converter_convert(t_jit_charset_converter *x, const char *in, long inbytes, char **out, long *outbytes) 00192 { 00193 char *cvtbuffer = NULL; 00194 long cvtbuffersize = 0; 00195 long result; 00196 t_jit_err rv = JIT_ERR_GENERIC; 00197 #ifdef MAC_VERSION 00198 char *src, *dst; 00199 size_t srcbytes, dstbytes; 00200 char *tmpbuffer = NULL; 00201 long tmpbuffersize = 0; 00202 char *srcenc; 00203 char *dstenc; 00204 #else 00205 WCHAR *widebuffer = NULL; 00206 long widebuffersize = 0; 00207 UINT srcenc; 00208 UINT dstenc; 00209 #endif 00210 00211 if (!(x && in && inbytes && out && outbytes)) 00212 return JIT_ERR_GENERIC; 00213 00214 #ifdef MAC_VERSION 00215 srcenc = (char *)x->src_encoding; 00216 dstenc = (char *)x->dst_encoding; 00217 #else 00218 srcenc = (UINT)x->src_encoding; 00219 dstenc = (UINT)x->dst_encoding; 00220 #endif 00221 00222 if (!(srcenc && dstenc)) 00223 return JIT_ERR_GENERIC; 00224 00225 #ifdef MAC_VERSION 00226 tmpbuffersize = inbytes * 4; // UTF-8 can occupy up to 4 bytes per character 00227 tmpbuffer = sysmem_newptr(tmpbuffersize); 00228 if (!tmpbuffer) { 00229 error("jit.charset: memory error allocating temporary character buffer"); 00230 return JIT_ERR_OUT_OF_MEM; 00231 } 00232 00233 src = (char *)in; 00234 srcbytes = inbytes; 00235 dst = tmpbuffer; 00236 dstbytes = tmpbuffersize; 00237 00238 result = jit_charset_iconv(x->conv, (const char **)&src, &srcbytes, &dst, &dstbytes); 00239 if (result) { 00240 error("jit.charset: error %d converting character encodings", result); 00241 rv = JIT_ERR_GENERIC; 00242 } else { 00243 long bytecount = dst - tmpbuffer; 00244 00245 cvtbuffer = sysmem_newptr(bytecount); 00246 if (!cvtbuffer) { 00247 error("jit.charset: memory error allocating output character buffer"); 00248 rv = JIT_ERR_OUT_OF_MEM; 00249 } else { 00250 sysmem_copyptr(tmpbuffer, cvtbuffer, bytecount); 00251 *out = cvtbuffer; 00252 *outbytes = bytecount; 00253 return JIT_ERR_NONE; 00254 } 00255 } 00256 if (tmpbuffer && tmpbuffersize) 00257 sysmem_freeptr(tmpbuffer); 00258 if (cvtbuffer && cvtbuffersize) 00259 sysmem_freeptr(cvtbuffer); 00260 00261 return rv; 00262 #else 00263 result = MultiByteToWideChar(srcenc, 0, in, inbytes, NULL, 0); 00264 if (!result) { 00265 error("jit.charset: error getting wide character buffer size"); 00266 return JIT_ERR_GENERIC; 00267 } 00268 00269 widebuffersize = result * sizeof(WCHAR); 00270 widebuffer = (WCHAR *)sysmem_newptr(widebuffersize); 00271 if (!widebuffer) { 00272 error("jit.charset: memory error allocating wide character buffer"); 00273 return JIT_ERR_OUT_OF_MEM; 00274 } 00275 00276 result = MultiByteToWideChar(srcenc, 0, in, inbytes, widebuffer, widebuffersize); 00277 if (!result) { 00278 error("jit.charset: error converting string to wide character buffer"); 00279 rv = JIT_ERR_GENERIC; 00280 goto bail; 00281 } 00282 00283 result = WideCharToMultiByte(dstenc, 0, widebuffer, widebuffersize / sizeof(WCHAR), NULL, 0, NULL, NULL); 00284 if (!result) { 00285 error("jit.charset: error getting multibyte character buffer size"); 00286 rv = JIT_ERR_GENERIC; 00287 goto bail; 00288 } 00289 00290 cvtbuffersize = result; 00291 cvtbuffer = sysmem_newptr(cvtbuffersize); 00292 if (!cvtbuffer) { 00293 error("jit.charset: memory error allocating multibyte character buffer"); 00294 rv = JIT_ERR_OUT_OF_MEM; 00295 goto bail; 00296 } 00297 result = WideCharToMultiByte(dstenc, 0, widebuffer, widebuffersize / sizeof(WCHAR), cvtbuffer, cvtbuffersize, NULL, NULL); 00298 if (!result) { 00299 error("jit.charset: error converting wide string to multibyte character buffer"); 00300 rv = JIT_ERR_GENERIC; 00301 goto bail; 00302 } 00303 sysmem_freeptr(widebuffer); 00304 *out = cvtbuffer; 00305 *outbytes = cvtbuffersize; 00306 return JIT_ERR_NONE; 00307 00308 bail: 00309 if (widebuffer && widebuffersize) 00310 sysmem_freeptr(widebuffer); 00311 if (cvtbuffer && cvtbuffersize) 00312 sysmem_freeptr(cvtbuffer); 00313 00314 return rv; 00315 #endif 00316 } 00317 00318 void *jit_charset_encoding_sym2enc(t_symbol *encoding) 00319 { 00320 if (encoding == ps_utf_8) 00321 return (void *)charset_utf_8; 00322 if (encoding == ps_utf_16) 00323 return (void *)charset_utf_16; 00324 if (encoding == ps_iso_8859_1) 00325 return (void *)charset_iso_8859_1; 00326 if (encoding == ps_us_ascii) 00327 return (void *)charset_us_ascii; 00328 if (encoding == ps_ms_ansi) 00329 return (void *)charset_ms_ansi; 00330 if (encoding == ps_macroman) 00331 return (void *)charset_macroman; 00332 if (encoding == ps_utf_16be) 00333 return (void *)charset_utf_16be; 00334 if (encoding == ps_utf_16le) 00335 return (void *)charset_utf_16le; 00336 00337 return NULL; 00338 } 00339 00340 t_symbol *jit_charset_encoding_checkvalid(t_symbol *encoding) 00341 { 00342 if (encoding == ps_utf_8 || 00343 encoding == ps_utf_16 || 00344 encoding == ps_iso_8859_1 || 00345 encoding == ps_us_ascii || 00346 encoding == ps_ms_ansi || 00347 encoding == ps_macroman || 00348 encoding == ps_utf_16be || 00349 encoding == ps_utf_16le) 00350 { 00351 return encoding; 00352 } 00353 return NULL; 00354 } 00355
Copyright © 2008, Cycling '74