* ----------
*/
+static void euc_tw2big5(const unsigned char *euc, unsigned char *p, int len);
+static void big52euc_tw(const unsigned char *euc, unsigned char *p, int len);
static void big52mic(const unsigned char *big5, unsigned char *p, int len);
static void mic2big5(const unsigned char *mic, unsigned char *p, int len);
static void euc_tw2mic(const unsigned char *euc, unsigned char *p, int len);
unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
int len = PG_GETARG_INT32(4);
- unsigned char *buf;
CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_TW, PG_BIG5);
- buf = palloc(len * ENCODING_GROWTH_RATE + 1);
- euc_tw2mic(src, buf, len);
- mic2big5(buf, dest, strlen((char *) buf));
- pfree(buf);
+ euc_tw2big5(src, dest, len);
PG_RETURN_VOID();
}
unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
int len = PG_GETARG_INT32(4);
- unsigned char *buf;
CHECK_ENCODING_CONVERSION_ARGS(PG_BIG5, PG_EUC_TW);
- buf = palloc(len * ENCODING_GROWTH_RATE + 1);
- big52mic(src, buf, len);
- mic2euc_tw(buf, dest, strlen((char *) buf));
- pfree(buf);
+ big52euc_tw(src, dest, len);
PG_RETURN_VOID();
}
PG_RETURN_VOID();
}
+
+/*
+ * EUC_TW ---> Big5
+ */
+static void
+euc_tw2big5(const unsigned char *euc, unsigned char *p, int len)
+{
+ unsigned char c1;
+ unsigned short big5buf,
+ cnsBuf;
+ unsigned char lc;
+ int l;
+
+ while (len > 0)
+ {
+ c1 = *euc;
+ if (IS_HIGHBIT_SET(c1))
+ {
+ /* Verify and decode the next EUC_TW input character */
+ l = pg_encoding_verifymbchar(PG_EUC_TW, (const char *) euc, len);
+ if (l < 0)
+ report_invalid_encoding(PG_EUC_TW,
+ (const char *) euc, len);
+ if (c1 == SS2)
+ {
+ c1 = euc[1]; /* plane No. */
+ if (c1 == 0xa1)
+ lc = LC_CNS11643_1;
+ else if (c1 == 0xa2)
+ lc = LC_CNS11643_2;
+ else
+ lc = c1 - 0xa3 + LC_CNS11643_3;
+ cnsBuf = (euc[2] << 8) | euc[3];
+ }
+ else
+ { /* CNS11643-1 */
+ lc = LC_CNS11643_1;
+ cnsBuf = (c1 << 8) | euc[1];
+ }
+
+ /* Write it out in Big5 */
+ big5buf = CNStoBIG5(cnsBuf, lc);
+ if (big5buf == 0)
+ report_untranslatable_char(PG_EUC_TW, PG_BIG5,
+ (const char *) euc, len);
+ *p++ = (big5buf >> 8) & 0x00ff;
+ *p++ = big5buf & 0x00ff;
+
+ euc += l;
+ len -= l;
+ }
+ else
+ { /* should be ASCII */
+ if (c1 == 0)
+ report_invalid_encoding(PG_EUC_TW,
+ (const char *) euc, len);
+ *p++ = c1;
+ euc++;
+ len--;
+ }
+ }
+ *p = '\0';
+}
+
+/*
+ * Big5 ---> EUC_TW
+ */
+static void
+big52euc_tw(const unsigned char *big5, unsigned char *p, int len)
+{
+ unsigned short c1;
+ unsigned short big5buf,
+ cnsBuf;
+ unsigned char lc;
+ int l;
+
+ while (len > 0)
+ {
+ /* Verify and decode the next Big5 input character */
+ c1 = *big5;
+ if (IS_HIGHBIT_SET(c1))
+ {
+ l = pg_encoding_verifymbchar(PG_BIG5, (const char *) big5, len);
+ if (l < 0)
+ report_invalid_encoding(PG_BIG5,
+ (const char *) big5, len);
+ big5buf = (c1 << 8) | big5[1];
+ cnsBuf = BIG5toCNS(big5buf, &lc);
+
+ if (lc == LC_CNS11643_1)
+ {
+ *p++ = (cnsBuf >> 8) & 0x00ff;
+ *p++ = cnsBuf & 0x00ff;
+ }
+ else if (lc == LC_CNS11643_2)
+ {
+ *p++ = SS2;
+ *p++ = 0xa2;
+ *p++ = (cnsBuf >> 8) & 0x00ff;
+ *p++ = cnsBuf & 0x00ff;
+ }
+ else if (lc >= LC_CNS11643_3 && lc <= LC_CNS11643_7)
+ {
+ *p++ = SS2;
+ *p++ = lc - LC_CNS11643_3 + 0xa3;
+ *p++ = (cnsBuf >> 8) & 0x00ff;
+ *p++ = cnsBuf & 0x00ff;
+ }
+ else
+ report_untranslatable_char(PG_BIG5, PG_EUC_TW,
+ (const char *) big5, len);
+
+ big5 += l;
+ len -= l;
+ }
+ else
+ {
+ /* ASCII */
+ if (c1 == 0)
+ report_invalid_encoding(PG_BIG5,
+ (const char *) big5, len);
+ *p++ = c1;
+ big5++;
+ len--;
+ continue;
+ }
+ }
+ *p = '\0';
+}
+
/*
* EUC_TW ---> MIC
*/