1 /*-------------------------------------------------------------------------
3 * EUC_TW, BIG5 and MULE_INTERNAL
5 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
9 * $Header: /cvsroot/pgsql/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c,v 1.3 2002/09/04 20:31:31 momjian Exp $
11 *-------------------------------------------------------------------------
16 #include "mb/pg_wchar.h"
18 #define ENCODING_GROWTH_RATE 4
20 PG_FUNCTION_INFO_V1(euc_tw_to_big5)
21 PG_FUNCTION_INFO_V1(big5_to_euc_tw)
22 PG_FUNCTION_INFO_V1(euc_tw_to_mic)
23 PG_FUNCTION_INFO_V1(mic_to_euc_tw)
24 PG_FUNCTION_INFO_V1(big5_to_mic)
25 PG_FUNCTION_INFO_V1(mic_to_big5)
27 extern Datum euc_tw_to_big5(PG_FUNCTION_ARGS);
28 extern Datum big5_to_euc_tw(PG_FUNCTION_ARGS);
29 extern Datum euc_tw_to_mic(PG_FUNCTION_ARGS);
30 extern Datum mic_to_euc_tw(PG_FUNCTION_ARGS);
31 extern Datum big5_to_mic(PG_FUNCTION_ARGS);
32 extern Datum mic_to_big5(PG_FUNCTION_ARGS);
36 * INTEGER, -- source encoding id
37 * INTEGER, -- destination encoding id
38 * CSTRING, -- source string (null terminated C string)
39 * CSTRING, -- destination string (null terminated C string)
40 * INTEGER -- source string length
45 static void big52mic(unsigned char *big5, unsigned char *p, int len);
46 static void mic2big5(unsigned char *mic, unsigned char *p, int len);
47 static void euc_tw2mic(unsigned char *euc, unsigned char *p, int len);
48 static void mic2euc_tw(unsigned char *mic, unsigned char *p, int len);
51 euc_tw_to_big5(PG_FUNCTION_ARGS)
53 unsigned char *src = PG_GETARG_CSTRING(2);
54 unsigned char *dest = PG_GETARG_CSTRING(3);
55 int len = PG_GETARG_INT32(4);
58 Assert(PG_GETARG_INT32(0) == PG_EUC_TW);
59 Assert(PG_GETARG_INT32(1) == PG_BIG5);
62 buf = palloc(len * ENCODING_GROWTH_RATE);
63 euc_tw2mic(src, buf, len);
64 mic2big5(buf, dest, strlen(buf));
71 big5_to_euc_tw(PG_FUNCTION_ARGS)
73 unsigned char *src = PG_GETARG_CSTRING(2);
74 unsigned char *dest = PG_GETARG_CSTRING(3);
75 int len = PG_GETARG_INT32(4);
78 Assert(PG_GETARG_INT32(0) == PG_BIG5);
79 Assert(PG_GETARG_INT32(1) == PG_EUC_TW);
82 buf = palloc(len * ENCODING_GROWTH_RATE);
83 big52mic(src, buf, len);
84 mic2euc_tw(buf, dest, strlen(buf));
91 euc_tw_to_mic(PG_FUNCTION_ARGS)
93 unsigned char *src = PG_GETARG_CSTRING(2);
94 unsigned char *dest = PG_GETARG_CSTRING(3);
95 int len = PG_GETARG_INT32(4);
97 Assert(PG_GETARG_INT32(0) == PG_EUC_TW);
98 Assert(PG_GETARG_INT32(1) == PG_MULE_INTERNAL);
101 euc_tw2mic(src, dest, len);
107 mic_to_euc_tw(PG_FUNCTION_ARGS)
109 unsigned char *src = PG_GETARG_CSTRING(2);
110 unsigned char *dest = PG_GETARG_CSTRING(3);
111 int len = PG_GETARG_INT32(4);
113 Assert(PG_GETARG_INT32(0) == PG_MULE_INTERNAL);
114 Assert(PG_GETARG_INT32(1) == PG_EUC_TW);
117 mic2big5(src, dest, len);
123 big5_to_mic(PG_FUNCTION_ARGS)
125 unsigned char *src = PG_GETARG_CSTRING(2);
126 unsigned char *dest = PG_GETARG_CSTRING(3);
127 int len = PG_GETARG_INT32(4);
129 Assert(PG_GETARG_INT32(0) == PG_BIG5);
130 Assert(PG_GETARG_INT32(1) == PG_MULE_INTERNAL);
133 big52mic(src, dest, len);
139 mic_to_big5(PG_FUNCTION_ARGS)
141 unsigned char *src = PG_GETARG_CSTRING(2);
142 unsigned char *dest = PG_GETARG_CSTRING(3);
143 int len = PG_GETARG_INT32(4);
145 Assert(PG_GETARG_INT32(0) == PG_MULE_INTERNAL);
146 Assert(PG_GETARG_INT32(1) == PG_BIG5);
149 mic2big5(src, dest, len);
158 euc_tw2mic(unsigned char *euc, unsigned char *p, int len)
162 while (len > 0 && (c1 = *euc++))
167 c1 = *euc++; /* plane No. */
169 *p++ = LC_CNS11643_1;
171 *p++ = LC_CNS11643_2;
174 *p++ = 0x9d; /* LCPRV2 */
175 *p++ = 0xa3 - c1 + LC_CNS11643_3;
183 *p++ = LC_CNS11643_1;
188 { /* should be ASCII */
200 mic2euc_tw(unsigned char *mic, unsigned char *p, int len)
204 while (len > 0 && (c1 = *mic))
206 len -= pg_mic_mblen(mic++);
208 if (c1 == LC_CNS11643_1)
213 else if (c1 == LC_CNS11643_2)
223 *p++ = *mic++ - LC_CNS11643_3 + 0xa3;
228 { /* cannot convert to EUC_TW! */
230 pg_print_bogus_char(&mic, &p);
233 { /* should be ASCII */
244 big52mic(unsigned char *big5, unsigned char *p, int len)
247 unsigned short big5buf,
253 while (len > 0 && (c1 = *big5++))
266 cnsBuf = BIG5toCNS(big5buf, &lc);
269 if (lc == LC_CNS11643_3 || lc == LC_CNS11643_4)
271 *p++ = 0x9d; /* LCPRV2 */
273 *p++ = lc; /* Plane No. */
274 *p++ = (cnsBuf >> 8) & 0x00ff;
275 *p++ = cnsBuf & 0x00ff;
278 { /* cannot convert */
281 for (i = 0; i < 2; i++)
283 sprintf(bogusBuf, "%02x", *big5++);
298 mic2big5(unsigned char *mic, unsigned char *p, int len)
302 unsigned short big5buf,
305 while (len > 0 && (c1 = *mic))
307 l = pg_mic_mblen(mic++);
310 /* 0x9d means LCPRV2 */
311 if (c1 == LC_CNS11643_1 || c1 == LC_CNS11643_2 || c1 == 0x9d)
315 c1 = *mic++; /* get plane no. */
317 cnsBuf = (*mic++) << 8;
318 cnsBuf |= (*mic++) & 0x00ff;
319 big5buf = CNStoBIG5(cnsBuf, c1);
321 { /* cannot convert to Big5! */
323 pg_print_bogus_char(&mic, &p);
327 *p++ = (big5buf >> 8) & 0x00ff;
328 *p++ = big5buf & 0x00ff;
331 else if (c1 <= 0x7f) /* ASCII */
334 { /* cannot convert to Big5! */
336 pg_print_bogus_char(&mic, &p);