Header And Logo

PostgreSQL
| The world's most advanced open source database.

cyrillic_and_mic.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *    Cyrillic and MULE_INTERNAL
00004  *
00005  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00006  * Portions Copyright (c) 1994, Regents of the University of California
00007  *
00008  * IDENTIFICATION
00009  *    src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c
00010  *
00011  *-------------------------------------------------------------------------
00012  */
00013 
00014 #include "postgres.h"
00015 #include "fmgr.h"
00016 #include "mb/pg_wchar.h"
00017 
00018 #define ENCODING_GROWTH_RATE 4
00019 
00020 PG_MODULE_MAGIC;
00021 
00022 PG_FUNCTION_INFO_V1(koi8r_to_mic);
00023 PG_FUNCTION_INFO_V1(mic_to_koi8r);
00024 PG_FUNCTION_INFO_V1(iso_to_mic);
00025 PG_FUNCTION_INFO_V1(mic_to_iso);
00026 PG_FUNCTION_INFO_V1(win1251_to_mic);
00027 PG_FUNCTION_INFO_V1(mic_to_win1251);
00028 PG_FUNCTION_INFO_V1(win866_to_mic);
00029 PG_FUNCTION_INFO_V1(mic_to_win866);
00030 PG_FUNCTION_INFO_V1(koi8r_to_win1251);
00031 PG_FUNCTION_INFO_V1(win1251_to_koi8r);
00032 PG_FUNCTION_INFO_V1(koi8r_to_win866);
00033 PG_FUNCTION_INFO_V1(win866_to_koi8r);
00034 PG_FUNCTION_INFO_V1(win866_to_win1251);
00035 PG_FUNCTION_INFO_V1(win1251_to_win866);
00036 PG_FUNCTION_INFO_V1(iso_to_koi8r);
00037 PG_FUNCTION_INFO_V1(koi8r_to_iso);
00038 PG_FUNCTION_INFO_V1(iso_to_win1251);
00039 PG_FUNCTION_INFO_V1(win1251_to_iso);
00040 PG_FUNCTION_INFO_V1(iso_to_win866);
00041 PG_FUNCTION_INFO_V1(win866_to_iso);
00042 
00043 extern Datum koi8r_to_mic(PG_FUNCTION_ARGS);
00044 extern Datum mic_to_koi8r(PG_FUNCTION_ARGS);
00045 extern Datum iso_to_mic(PG_FUNCTION_ARGS);
00046 extern Datum mic_to_iso(PG_FUNCTION_ARGS);
00047 extern Datum win1251_to_mic(PG_FUNCTION_ARGS);
00048 extern Datum mic_to_win1251(PG_FUNCTION_ARGS);
00049 extern Datum win866_to_mic(PG_FUNCTION_ARGS);
00050 extern Datum mic_to_win866(PG_FUNCTION_ARGS);
00051 extern Datum koi8r_to_win1251(PG_FUNCTION_ARGS);
00052 extern Datum win1251_to_koi8r(PG_FUNCTION_ARGS);
00053 extern Datum koi8r_to_win866(PG_FUNCTION_ARGS);
00054 extern Datum win866_to_koi8r(PG_FUNCTION_ARGS);
00055 extern Datum win866_to_win1251(PG_FUNCTION_ARGS);
00056 extern Datum win1251_to_win866(PG_FUNCTION_ARGS);
00057 extern Datum iso_to_koi8r(PG_FUNCTION_ARGS);
00058 extern Datum koi8r_to_iso(PG_FUNCTION_ARGS);
00059 extern Datum iso_to_win1251(PG_FUNCTION_ARGS);
00060 extern Datum win1251_to_iso(PG_FUNCTION_ARGS);
00061 extern Datum iso_to_win866(PG_FUNCTION_ARGS);
00062 extern Datum win866_to_iso(PG_FUNCTION_ARGS);
00063 
00064 /* ----------
00065  * conv_proc(
00066  *      INTEGER,    -- source encoding id
00067  *      INTEGER,    -- destination encoding id
00068  *      CSTRING,    -- source string (null terminated C string)
00069  *      CSTRING,    -- destination string (null terminated C string)
00070  *      INTEGER     -- source string length
00071  * ) returns VOID;
00072  * ----------
00073  */
00074 
00075 static void koi8r2mic(const unsigned char *l, unsigned char *p, int len);
00076 static void mic2koi8r(const unsigned char *mic, unsigned char *p, int len);
00077 static void iso2mic(const unsigned char *l, unsigned char *p, int len);
00078 static void mic2iso(const unsigned char *mic, unsigned char *p, int len);
00079 static void win12512mic(const unsigned char *l, unsigned char *p, int len);
00080 static void mic2win1251(const unsigned char *mic, unsigned char *p, int len);
00081 static void win8662mic(const unsigned char *l, unsigned char *p, int len);
00082 static void mic2win866(const unsigned char *mic, unsigned char *p, int len);
00083 
00084 Datum
00085 koi8r_to_mic(PG_FUNCTION_ARGS)
00086 {
00087     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00088     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00089     int         len = PG_GETARG_INT32(4);
00090 
00091     CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_MULE_INTERNAL);
00092 
00093     koi8r2mic(src, dest, len);
00094 
00095     PG_RETURN_VOID();
00096 }
00097 
00098 Datum
00099 mic_to_koi8r(PG_FUNCTION_ARGS)
00100 {
00101     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00102     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00103     int         len = PG_GETARG_INT32(4);
00104 
00105     CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_KOI8R);
00106 
00107     mic2koi8r(src, dest, len);
00108 
00109     PG_RETURN_VOID();
00110 }
00111 
00112 Datum
00113 iso_to_mic(PG_FUNCTION_ARGS)
00114 {
00115     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00116     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00117     int         len = PG_GETARG_INT32(4);
00118 
00119     CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_MULE_INTERNAL);
00120 
00121     iso2mic(src, dest, len);
00122 
00123     PG_RETURN_VOID();
00124 }
00125 
00126 Datum
00127 mic_to_iso(PG_FUNCTION_ARGS)
00128 {
00129     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00130     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00131     int         len = PG_GETARG_INT32(4);
00132 
00133     CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_ISO_8859_5);
00134 
00135     mic2iso(src, dest, len);
00136 
00137     PG_RETURN_VOID();
00138 }
00139 
00140 Datum
00141 win1251_to_mic(PG_FUNCTION_ARGS)
00142 {
00143     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00144     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00145     int         len = PG_GETARG_INT32(4);
00146 
00147     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_MULE_INTERNAL);
00148 
00149     win12512mic(src, dest, len);
00150 
00151     PG_RETURN_VOID();
00152 }
00153 
00154 Datum
00155 mic_to_win1251(PG_FUNCTION_ARGS)
00156 {
00157     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00158     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00159     int         len = PG_GETARG_INT32(4);
00160 
00161     CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_WIN1251);
00162 
00163     mic2win1251(src, dest, len);
00164 
00165     PG_RETURN_VOID();
00166 }
00167 
00168 Datum
00169 win866_to_mic(PG_FUNCTION_ARGS)
00170 {
00171     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00172     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00173     int         len = PG_GETARG_INT32(4);
00174 
00175     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_MULE_INTERNAL);
00176 
00177     win8662mic(src, dest, len);
00178 
00179     PG_RETURN_VOID();
00180 }
00181 
00182 Datum
00183 mic_to_win866(PG_FUNCTION_ARGS)
00184 {
00185     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00186     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00187     int         len = PG_GETARG_INT32(4);
00188 
00189     CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_WIN866);
00190 
00191     mic2win866(src, dest, len);
00192 
00193     PG_RETURN_VOID();
00194 }
00195 
00196 Datum
00197 koi8r_to_win1251(PG_FUNCTION_ARGS)
00198 {
00199     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00200     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00201     int         len = PG_GETARG_INT32(4);
00202     unsigned char *buf;
00203 
00204     CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_WIN1251);
00205 
00206     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00207     koi8r2mic(src, buf, len);
00208     mic2win1251(buf, dest, strlen((char *) buf));
00209     pfree(buf);
00210 
00211     PG_RETURN_VOID();
00212 }
00213 
00214 Datum
00215 win1251_to_koi8r(PG_FUNCTION_ARGS)
00216 {
00217     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00218     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00219     int         len = PG_GETARG_INT32(4);
00220     unsigned char *buf;
00221 
00222     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_KOI8R);
00223 
00224     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00225     win12512mic(src, buf, len);
00226     mic2koi8r(buf, dest, strlen((char *) buf));
00227     pfree(buf);
00228 
00229     PG_RETURN_VOID();
00230 }
00231 
00232 Datum
00233 koi8r_to_win866(PG_FUNCTION_ARGS)
00234 {
00235     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00236     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00237     int         len = PG_GETARG_INT32(4);
00238     unsigned char *buf;
00239 
00240     CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_WIN866);
00241 
00242     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00243     koi8r2mic(src, buf, len);
00244     mic2win866(buf, dest, strlen((char *) buf));
00245     pfree(buf);
00246 
00247     PG_RETURN_VOID();
00248 }
00249 
00250 Datum
00251 win866_to_koi8r(PG_FUNCTION_ARGS)
00252 {
00253     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00254     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00255     int         len = PG_GETARG_INT32(4);
00256     unsigned char *buf;
00257 
00258     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_KOI8R);
00259 
00260     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00261     win8662mic(src, buf, len);
00262     mic2koi8r(buf, dest, strlen((char *) buf));
00263     pfree(buf);
00264 
00265     PG_RETURN_VOID();
00266 }
00267 
00268 Datum
00269 win866_to_win1251(PG_FUNCTION_ARGS)
00270 {
00271     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00272     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00273     int         len = PG_GETARG_INT32(4);
00274     unsigned char *buf;
00275 
00276     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_WIN1251);
00277 
00278     /*
00279      * Note: There are a few characters like the "Numero" sign that exist in
00280      * all the other cyrillic encodings (win1251, ISO_8859-5 and cp866), but
00281      * not in KOI8R. As we use MULE_INTERNAL/KOI8R as an intermediary, we will
00282      * fail to convert those characters.
00283      */
00284     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00285     win8662mic(src, buf, len);
00286     mic2win1251(buf, dest, strlen((char *) buf));
00287     pfree(buf);
00288 
00289     PG_RETURN_VOID();
00290 }
00291 
00292 Datum
00293 win1251_to_win866(PG_FUNCTION_ARGS)
00294 {
00295     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00296     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00297     int         len = PG_GETARG_INT32(4);
00298     unsigned char *buf;
00299 
00300     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_WIN866);
00301 
00302     /* Use mic/KOI8R as intermediary, see comment in win866_to_win1251() */
00303     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00304     win12512mic(src, buf, len);
00305     mic2win866(buf, dest, strlen((char *) buf));
00306     pfree(buf);
00307 
00308     PG_RETURN_VOID();
00309 }
00310 
00311 Datum
00312 iso_to_koi8r(PG_FUNCTION_ARGS)
00313 {
00314     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00315     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00316     int         len = PG_GETARG_INT32(4);
00317     unsigned char *buf;
00318 
00319     CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_KOI8R);
00320 
00321     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00322     iso2mic(src, buf, len);
00323     mic2koi8r(buf, dest, strlen((char *) buf));
00324     pfree(buf);
00325 
00326     PG_RETURN_VOID();
00327 }
00328 
00329 Datum
00330 koi8r_to_iso(PG_FUNCTION_ARGS)
00331 {
00332     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00333     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00334     int         len = PG_GETARG_INT32(4);
00335     unsigned char *buf;
00336 
00337     CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_ISO_8859_5);
00338 
00339     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00340     koi8r2mic(src, buf, len);
00341     mic2iso(buf, dest, strlen((char *) buf));
00342     pfree(buf);
00343 
00344     PG_RETURN_VOID();
00345 }
00346 
00347 Datum
00348 iso_to_win1251(PG_FUNCTION_ARGS)
00349 {
00350     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00351     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00352     int         len = PG_GETARG_INT32(4);
00353     unsigned char *buf;
00354 
00355     CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_WIN1251);
00356 
00357     /* Use mic/KOI8R as intermediary, see comment in win866_to_win1251() */
00358     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00359     iso2mic(src, buf, len);
00360     mic2win1251(buf, dest, strlen((char *) buf));
00361     pfree(buf);
00362 
00363     PG_RETURN_VOID();
00364 }
00365 
00366 Datum
00367 win1251_to_iso(PG_FUNCTION_ARGS)
00368 {
00369     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00370     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00371     int         len = PG_GETARG_INT32(4);
00372     unsigned char *buf;
00373 
00374     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_ISO_8859_5);
00375 
00376     /* Use mic/KOI8R as intermediary, see comment in win866_to_win1251() */
00377     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00378     win12512mic(src, buf, len);
00379     mic2iso(buf, dest, strlen((char *) buf));
00380     pfree(buf);
00381 
00382     PG_RETURN_VOID();
00383 }
00384 
00385 Datum
00386 iso_to_win866(PG_FUNCTION_ARGS)
00387 {
00388     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00389     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00390     int         len = PG_GETARG_INT32(4);
00391     unsigned char *buf;
00392 
00393     CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_WIN866);
00394 
00395     /* Use mic/KOI8R as intermediary, see comment in win866_to_win1251() */
00396     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00397     iso2mic(src, buf, len);
00398     mic2win866(buf, dest, strlen((char *) buf));
00399     pfree(buf);
00400 
00401     PG_RETURN_VOID();
00402 }
00403 
00404 Datum
00405 win866_to_iso(PG_FUNCTION_ARGS)
00406 {
00407     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00408     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00409     int         len = PG_GETARG_INT32(4);
00410     unsigned char *buf;
00411 
00412     CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_ISO_8859_5);
00413 
00414     /* Use mic/KOI8R as intermediary, see comment in win866_to_win1251() */
00415     buf = palloc(len * ENCODING_GROWTH_RATE + 1);
00416     win8662mic(src, buf, len);
00417     mic2iso(buf, dest, strlen((char *) buf));
00418     pfree(buf);
00419 
00420     PG_RETURN_VOID();
00421 }
00422 
00423 /*
00424  * Cyrillic support
00425  * currently supported Cyrillic encodings:
00426  *
00427  * KOI8-R (this is the charset for the mule internal code
00428  *      for Cyrillic)
00429  * ISO-8859-5
00430  * Microsoft's CP1251(windows-1251)
00431  * Alternativny Variant (MS-DOS CP866)
00432  */
00433 
00434 /* koi8r2mic: KOI8-R to Mule internal code */
00435 static void
00436 koi8r2mic(const unsigned char *l, unsigned char *p, int len)
00437 {
00438     latin2mic(l, p, len, LC_KOI8_R, PG_KOI8R);
00439 }
00440 
00441 /* mic2koi8r: Mule internal code to KOI8-R */
00442 static void
00443 mic2koi8r(const unsigned char *mic, unsigned char *p, int len)
00444 {
00445     mic2latin(mic, p, len, LC_KOI8_R, PG_KOI8R);
00446 }
00447 
00448 /* iso2mic: ISO-8859-5 to Mule internal code */
00449 static void
00450 iso2mic(const unsigned char *l, unsigned char *p, int len)
00451 {
00452     static const unsigned char iso2koi[] = {
00453         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00454         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00455         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00456         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00457         0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00458         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00459         0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
00460         0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
00461         0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
00462         0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
00463         0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
00464         0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
00465         0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
00466         0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
00467         0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00468         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00469     };
00470 
00471     latin2mic_with_table(l, p, len, LC_KOI8_R, PG_ISO_8859_5, iso2koi);
00472 }
00473 
00474 /* mic2iso: Mule internal code to ISO8859-5 */
00475 static void
00476 mic2iso(const unsigned char *mic, unsigned char *p, int len)
00477 {
00478     static const unsigned char koi2iso[] = {
00479         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00480         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00481         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00482         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00483         0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00,
00484         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00485         0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00,
00486         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00487         0xee, 0xd0, 0xd1, 0xe6, 0xd4, 0xd5, 0xe4, 0xd3,
00488         0xe5, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
00489         0xdf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xd6, 0xd2,
00490         0xec, 0xeb, 0xd7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
00491         0xce, 0xb0, 0xb1, 0xc6, 0xb4, 0xb5, 0xc4, 0xb3,
00492         0xc5, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
00493         0xbf, 0xcf, 0xc0, 0xc1, 0xc2, 0xc3, 0xb6, 0xb2,
00494         0xcc, 0xcb, 0xb7, 0xc8, 0xcd, 0xc9, 0xc7, 0xca
00495     };
00496 
00497     mic2latin_with_table(mic, p, len, LC_KOI8_R, PG_ISO_8859_5, koi2iso);
00498 }
00499 
00500 /* win2mic: CP1251 to Mule internal code */
00501 static void
00502 win12512mic(const unsigned char *l, unsigned char *p, int len)
00503 {
00504     static const unsigned char win2koi[] = {
00505         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00506         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00507         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00508         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00509         0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00,
00510         0xb3, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0xb7,
00511         0x00, 0x00, 0xb6, 0xa6, 0xad, 0x00, 0x00, 0x00,
00512         0xa3, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0xa7,
00513         0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
00514         0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
00515         0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
00516         0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
00517         0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
00518         0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
00519         0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
00520         0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1
00521     };
00522 
00523     latin2mic_with_table(l, p, len, LC_KOI8_R, PG_WIN1251, win2koi);
00524 }
00525 
00526 /* mic2win: Mule internal code to CP1251 */
00527 static void
00528 mic2win1251(const unsigned char *mic, unsigned char *p, int len)
00529 {
00530     static const unsigned char koi2win[] = {
00531         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00532         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00533         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00534         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00535         0x00, 0x00, 0x00, 0xb8, 0xba, 0x00, 0xb3, 0xbf,
00536         0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00,
00537         0x00, 0x00, 0x00, 0xa8, 0xaa, 0x00, 0xb2, 0xaf,
00538         0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00,
00539         0xfe, 0xe0, 0xe1, 0xf6, 0xe4, 0xe5, 0xf4, 0xe3,
00540         0xf5, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
00541         0xef, 0xff, 0xf0, 0xf1, 0xf2, 0xf3, 0xe6, 0xe2,
00542         0xfc, 0xfb, 0xe7, 0xf8, 0xfd, 0xf9, 0xf7, 0xfa,
00543         0xde, 0xc0, 0xc1, 0xd6, 0xc4, 0xc5, 0xd4, 0xc3,
00544         0xd5, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
00545         0xcf, 0xdf, 0xd0, 0xd1, 0xd2, 0xd3, 0xc6, 0xc2,
00546         0xdc, 0xdb, 0xc7, 0xd8, 0xdd, 0xd9, 0xd7, 0xda
00547     };
00548 
00549     mic2latin_with_table(mic, p, len, LC_KOI8_R, PG_WIN1251, koi2win);
00550 }
00551 
00552 /* win8662mic: CP866 to Mule internal code */
00553 static void
00554 win8662mic(const unsigned char *l, unsigned char *p, int len)
00555 {
00556     static const unsigned char win8662koi[] = {
00557         0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
00558         0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
00559         0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
00560         0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
00561         0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
00562         0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
00563         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00564         0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00,
00565         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00566         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00567         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00568         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00569         0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
00570         0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
00571         0xb3, 0xa3, 0xb4, 0xa4, 0xb7, 0xa7, 0x00, 0x00,
00572         0xb6, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00573     };
00574 
00575     latin2mic_with_table(l, p, len, LC_KOI8_R, PG_WIN866, win8662koi);
00576 }
00577 
00578 /* mic2win866: Mule internal code to CP866 */
00579 static void
00580 mic2win866(const unsigned char *mic, unsigned char *p, int len)
00581 {
00582     static const unsigned char koi2win866[] = {
00583         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00584         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00585         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00586         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00587         0x00, 0x00, 0x00, 0xf1, 0xf3, 0x00, 0xf9, 0xf5,
00588         0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00,
00589         0x00, 0x00, 0x00, 0xf0, 0xf2, 0x00, 0xf8, 0xf4,
00590         0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00,
00591         0xee, 0xa0, 0xa1, 0xe6, 0xa4, 0xa5, 0xe4, 0xa3,
00592         0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
00593         0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xa6, 0xa2,
00594         0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
00595         0x9e, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
00596         0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
00597         0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82,
00598         0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
00599     };
00600 
00601     mic2latin_with_table(mic, p, len, LC_KOI8_R, PG_WIN866, koi2win866);
00602 }