diff options
Diffstat (limited to 'src/lib/libast/string/wc2utf8.c')
-rw-r--r-- | src/lib/libast/string/wc2utf8.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/lib/libast/string/wc2utf8.c b/src/lib/libast/string/wc2utf8.c new file mode 100644 index 0000000..3b70391 --- /dev/null +++ b/src/lib/libast/string/wc2utf8.c @@ -0,0 +1,74 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + * + * convert wide character to utf8 in s + * s must have room for at least 6 bytes + * number of chars in placed in s returned + * thanks Tom Duff + */ + +#include <ast.h> + +typedef struct Utf8_s +{ + uint32_t range; + unsigned short prefix; + unsigned short shift; +} Utf8_t; + +static const Utf8_t ops[] = +{ + { 0x00000080, 0x00, 0 }, + { 0x00000800, 0xc0, 6 }, + { 0x00010000, 0xe0, 12 }, + { 0x00200000, 0xf0, 18 }, + { 0x04000000, 0xf8, 24 }, + { 0x80000000, 0xfc, 30 } +}; + +int +wc2utf8(register char* s, register uint32_t w) +{ + register int i; + char* b; + + for (i = 0; i < elementsof(ops); i++) + if (w < ops[i].range) + { + b = s; + *s++ = ops[i].prefix | (w >> ops[i].shift); + switch (ops[i].shift) + { + case 30: *s++ = 0x80 | ((w >> 24) & 0x3f); + case 24: *s++ = 0x80 | ((w >> 18) & 0x3f); + case 18: *s++ = 0x80 | ((w >> 12) & 0x3f); + case 12: *s++ = 0x80 | ((w >> 6) & 0x3f); + case 6: *s++ = 0x80 | (w & 0x3f); + } + return s - b; + } + return 0; +} |