11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds * Module for handling utf8 just like any other charset.
31da177e4SLinus Torvalds * By Urban Widmark 2000
41da177e4SLinus Torvalds */
51da177e4SLinus Torvalds
61da177e4SLinus Torvalds #include <linux/module.h>
71da177e4SLinus Torvalds #include <linux/kernel.h>
81da177e4SLinus Torvalds #include <linux/string.h>
91da177e4SLinus Torvalds #include <linux/nls.h>
101da177e4SLinus Torvalds #include <linux/errno.h>
111da177e4SLinus Torvalds
121da177e4SLinus Torvalds static unsigned char identity[256];
131da177e4SLinus Torvalds
uni2char(wchar_t uni,unsigned char * out,int boundlen)141da177e4SLinus Torvalds static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
151da177e4SLinus Torvalds {
161da177e4SLinus Torvalds int n;
171da177e4SLinus Torvalds
18*74675a58SAlan Stern if (boundlen <= 0)
19*74675a58SAlan Stern return -ENAMETOOLONG;
20*74675a58SAlan Stern
21*74675a58SAlan Stern n = utf32_to_utf8(uni, out, boundlen);
22*74675a58SAlan Stern if (n < 0) {
231da177e4SLinus Torvalds *out = '?';
241da177e4SLinus Torvalds return -EINVAL;
251da177e4SLinus Torvalds }
261da177e4SLinus Torvalds return n;
271da177e4SLinus Torvalds }
281da177e4SLinus Torvalds
char2uni(const unsigned char * rawstring,int boundlen,wchar_t * uni)291da177e4SLinus Torvalds static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
301da177e4SLinus Torvalds {
311da177e4SLinus Torvalds int n;
32*74675a58SAlan Stern unicode_t u;
331da177e4SLinus Torvalds
34*74675a58SAlan Stern n = utf8_to_utf32(rawstring, boundlen, &u);
35*74675a58SAlan Stern if (n < 0 || u > MAX_WCHAR_T) {
361da177e4SLinus Torvalds *uni = 0x003f; /* ? */
37*74675a58SAlan Stern return -EINVAL;
381da177e4SLinus Torvalds }
39*74675a58SAlan Stern *uni = (wchar_t) u;
401da177e4SLinus Torvalds return n;
411da177e4SLinus Torvalds }
421da177e4SLinus Torvalds
431da177e4SLinus Torvalds static struct nls_table table = {
441da177e4SLinus Torvalds .charset = "utf8",
451da177e4SLinus Torvalds .uni2char = uni2char,
461da177e4SLinus Torvalds .char2uni = char2uni,
471da177e4SLinus Torvalds .charset2lower = identity, /* no conversion */
481da177e4SLinus Torvalds .charset2upper = identity,
491da177e4SLinus Torvalds };
501da177e4SLinus Torvalds
init_nls_utf8(void)511da177e4SLinus Torvalds static int __init init_nls_utf8(void)
521da177e4SLinus Torvalds {
531da177e4SLinus Torvalds int i;
541da177e4SLinus Torvalds for (i=0; i<256; i++)
551da177e4SLinus Torvalds identity[i] = i;
561da177e4SLinus Torvalds
571da177e4SLinus Torvalds return register_nls(&table);
581da177e4SLinus Torvalds }
591da177e4SLinus Torvalds
exit_nls_utf8(void)601da177e4SLinus Torvalds static void __exit exit_nls_utf8(void)
611da177e4SLinus Torvalds {
621da177e4SLinus Torvalds unregister_nls(&table);
631da177e4SLinus Torvalds }
641da177e4SLinus Torvalds
651da177e4SLinus Torvalds module_init(init_nls_utf8)
661da177e4SLinus Torvalds module_exit(exit_nls_utf8)
671da177e4SLinus Torvalds MODULE_LICENSE("Dual BSD/GPL");
68