Header And Logo

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

euc_cn_and_mic.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *    EUC_CN 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/euc_cn_and_mic/euc_cn_and_mic.c
00010  *
00011  *-------------------------------------------------------------------------
00012  */
00013 
00014 #include "postgres.h"
00015 #include "fmgr.h"
00016 #include "mb/pg_wchar.h"
00017 
00018 PG_MODULE_MAGIC;
00019 
00020 PG_FUNCTION_INFO_V1(euc_cn_to_mic);
00021 PG_FUNCTION_INFO_V1(mic_to_euc_cn);
00022 
00023 extern Datum euc_cn_to_mic(PG_FUNCTION_ARGS);
00024 extern Datum mic_to_euc_cn(PG_FUNCTION_ARGS);
00025 
00026 /* ----------
00027  * conv_proc(
00028  *      INTEGER,    -- source encoding id
00029  *      INTEGER,    -- destination encoding id
00030  *      CSTRING,    -- source string (null terminated C string)
00031  *      CSTRING,    -- destination string (null terminated C string)
00032  *      INTEGER     -- source string length
00033  * ) returns VOID;
00034  * ----------
00035  */
00036 
00037 static void euc_cn2mic(const unsigned char *euc, unsigned char *p, int len);
00038 static void mic2euc_cn(const unsigned char *mic, unsigned char *p, int len);
00039 
00040 Datum
00041 euc_cn_to_mic(PG_FUNCTION_ARGS)
00042 {
00043     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00044     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00045     int         len = PG_GETARG_INT32(4);
00046 
00047     CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_CN, PG_MULE_INTERNAL);
00048 
00049     euc_cn2mic(src, dest, len);
00050 
00051     PG_RETURN_VOID();
00052 }
00053 
00054 Datum
00055 mic_to_euc_cn(PG_FUNCTION_ARGS)
00056 {
00057     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
00058     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
00059     int         len = PG_GETARG_INT32(4);
00060 
00061     CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_EUC_CN);
00062 
00063     mic2euc_cn(src, dest, len);
00064 
00065     PG_RETURN_VOID();
00066 }
00067 
00068 /*
00069  * EUC_CN ---> MIC
00070  */
00071 static void
00072 euc_cn2mic(const unsigned char *euc, unsigned char *p, int len)
00073 {
00074     int         c1;
00075 
00076     while (len > 0)
00077     {
00078         c1 = *euc;
00079         if (IS_HIGHBIT_SET(c1))
00080         {
00081             if (len < 2 || !IS_HIGHBIT_SET(euc[1]))
00082                 report_invalid_encoding(PG_EUC_CN, (const char *) euc, len);
00083             *p++ = LC_GB2312_80;
00084             *p++ = c1;
00085             *p++ = euc[1];
00086             euc += 2;
00087             len -= 2;
00088         }
00089         else
00090         {                       /* should be ASCII */
00091             if (c1 == 0)
00092                 report_invalid_encoding(PG_EUC_CN, (const char *) euc, len);
00093             *p++ = c1;
00094             euc++;
00095             len--;
00096         }
00097     }
00098     *p = '\0';
00099 }
00100 
00101 /*
00102  * MIC ---> EUC_CN
00103  */
00104 static void
00105 mic2euc_cn(const unsigned char *mic, unsigned char *p, int len)
00106 {
00107     int         c1;
00108 
00109     while (len > 0)
00110     {
00111         c1 = *mic;
00112         if (IS_HIGHBIT_SET(c1))
00113         {
00114             if (c1 != LC_GB2312_80)
00115                 report_untranslatable_char(PG_MULE_INTERNAL, PG_EUC_CN,
00116                                            (const char *) mic, len);
00117             if (len < 3 || !IS_HIGHBIT_SET(mic[1]) || !IS_HIGHBIT_SET(mic[2]))
00118                 report_invalid_encoding(PG_MULE_INTERNAL,
00119                                         (const char *) mic, len);
00120             mic++;
00121             *p++ = *mic++;
00122             *p++ = *mic++;
00123             len -= 3;
00124         }
00125         else
00126         {                       /* should be ASCII */
00127             if (c1 == 0)
00128                 report_invalid_encoding(PG_MULE_INTERNAL,
00129                                         (const char *) mic, len);
00130             *p++ = c1;
00131             mic++;
00132             len--;
00133         }
00134     }
00135     *p = '\0';
00136 }