| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Uwe Zeisberger | f30c226 | 2006-10-03 23:01:26 +0200 | [diff] [blame] | 2 |  * linux/fs/nls/nls_koi8-ru.c | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 3 |  * | 
 | 4 |  * Charset koi8-ru translation based on charset koi8-u. | 
 | 5 |  * The Unicode to charset table has only exact mappings. | 
 | 6 |  */ | 
 | 7 |  | 
 | 8 | #include <linux/module.h> | 
 | 9 | #include <linux/kernel.h> | 
 | 10 | #include <linux/string.h> | 
 | 11 | #include <linux/nls.h> | 
 | 12 | #include <linux/errno.h> | 
 | 13 |  | 
 | 14 | static struct nls_table *p_nls; | 
 | 15 |  | 
 | 16 | static int uni2char(const wchar_t uni, | 
 | 17 | 		    unsigned char *out, int boundlen) | 
 | 18 | { | 
 | 19 | 	if (boundlen <= 0) | 
 | 20 | 		return -ENAMETOOLONG; | 
 | 21 |  | 
 | 22 | 	if ((uni & 0xffaf) == 0x040e || (uni & 0xffce) == 0x254c) { | 
 | 23 | 		/* koi8-ru and koi8-u differ only on two characters */ | 
 | 24 | 		if (uni == 0x040e) | 
 | 25 | 			out[0] = 0xbe; | 
 | 26 | 		else if (uni == 0x045e) | 
 | 27 | 			out[0] = 0xae; | 
 | 28 | 		else if (uni == 0x255d || uni == 0x256c) | 
 | 29 | 			return 0; | 
 | 30 | 		else | 
 | 31 | 			return p_nls->uni2char(uni, out, boundlen); | 
 | 32 | 		return 1; | 
 | 33 | 	} | 
 | 34 | 	else | 
 | 35 | 		/* fast path */ | 
 | 36 | 		return p_nls->uni2char(uni, out, boundlen); | 
 | 37 | } | 
 | 38 |  | 
 | 39 | static int char2uni(const unsigned char *rawstring, int boundlen, | 
 | 40 | 		    wchar_t *uni) | 
 | 41 | { | 
 | 42 | 	int n; | 
 | 43 |  | 
 | 44 | 	if ((*rawstring & 0xef) != 0xae) { | 
 | 45 | 		/* koi8-ru and koi8-u differ only on two characters */ | 
 | 46 | 		*uni = (*rawstring & 0x10) ? 0x040e : 0x045e; | 
 | 47 | 		return 1; | 
 | 48 | 	} | 
 | 49 |  | 
 | 50 | 	n = p_nls->char2uni(rawstring, boundlen, uni); | 
 | 51 | 	return n; | 
 | 52 | } | 
 | 53 |  | 
 | 54 | static struct nls_table table = { | 
 | 55 | 	.charset	= "koi8-ru", | 
 | 56 | 	.uni2char	= uni2char, | 
 | 57 | 	.char2uni	= char2uni, | 
 | 58 | 	.owner		= THIS_MODULE, | 
 | 59 | }; | 
 | 60 |  | 
 | 61 | static int __init init_nls_koi8_ru(void) | 
 | 62 | { | 
 | 63 | 	p_nls = load_nls("koi8-u"); | 
 | 64 |  | 
 | 65 | 	if (p_nls) { | 
 | 66 | 		table.charset2upper = p_nls->charset2upper; | 
 | 67 | 		table.charset2lower = p_nls->charset2lower; | 
 | 68 | 		return register_nls(&table); | 
 | 69 | 	} | 
 | 70 |  | 
 | 71 | 	return -EINVAL; | 
 | 72 | } | 
 | 73 |  | 
 | 74 | static void __exit exit_nls_koi8_ru(void) | 
 | 75 | { | 
 | 76 | 	unregister_nls(&table); | 
 | 77 | 	unload_nls(p_nls); | 
 | 78 | } | 
 | 79 |  | 
 | 80 | module_init(init_nls_koi8_ru) | 
 | 81 | module_exit(exit_nls_koi8_ru) | 
 | 82 |  | 
 | 83 | MODULE_LICENSE("Dual BSD/GPL"); |