about summary refs log tree commit diff
path: root/src/locale/iconv.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-08-07 13:16:14 -0400
committerRich Felker <dalias@aerifal.cx>2013-08-07 13:16:14 -0400
commit19b4a0a20efc6b9df98b6a43536ecdd628ba4643 (patch)
treec4069cb2953bd887e9be0b6f423763315701bf54 /src/locale/iconv.c
parent983acebc8a22866f720fbdb60aadc2a9c074d8f1 (diff)
downloadmusl-19b4a0a20efc6b9df98b6a43536ecdd628ba4643.tar.gz
musl-19b4a0a20efc6b9df98b6a43536ecdd628ba4643.tar.xz
musl-19b4a0a20efc6b9df98b6a43536ecdd628ba4643.zip
add Big5 charset support to iconv
at this point, it is just the common base charset equivalent to
Windows CP 950, with no further extensions. HKSCS and possibly other
supersets will be added later. other aliases may need to be added too.
Diffstat (limited to 'src/locale/iconv.c')
-rw-r--r--src/locale/iconv.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/locale/iconv.c b/src/locale/iconv.c
index d3caafa7..30ea8da6 100644
--- a/src/locale/iconv.c
+++ b/src/locale/iconv.c
@@ -20,6 +20,7 @@
 #define GB18030     0330
 #define GBK         0331
 #define GB2312      0332
+#define BIG5        0340
 #define EUC_KR      0350
 
 /* FIXME: these are not implemented yet
@@ -48,6 +49,7 @@ static const unsigned char charmaps[] =
 "gb18030\0\0\330"
 "gbk\0\0\331"
 "gb2312\0\0\332"
+"big5\0bigfive\0cp950\0\0\340"
 "euckr\0ksc5601\0ksx1001\0cp949\0\0\350"
 #include "codepages.h"
 ;
@@ -64,6 +66,10 @@ static const unsigned short gb18030[126][190] = {
 #include "gb18030.h"
 };
 
+static const unsigned short big5[89][157] = {
+#include "big5.h"
+};
+
 static const unsigned short ksc[93][94] = {
 #include "ksc.h"
 };
@@ -284,6 +290,18 @@ size_t iconv(iconv_t cd0, char **restrict in, size_t *restrict inb, char **restr
 			if (d>63) d--;
 			c = gb18030[c][d];
 			break;
+		case BIG5:
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (c-0xa1>=0xfa-0xa1) goto ilseq;
+			c -= 0xa1;
+			if (d-0x40>=0xff-0x40 || d-0x7f<0xa1-0x7f) goto ilseq;
+			d -= 0x40;
+			if (d > 0x3e) d -= 0x22;
+			c = big5[c][d];
+			if (!c) goto ilseq;
+			break;
 		case EUC_KR:
 			l = 2;
 			if (*inb < 2) goto starved;