xref: /openbmc/linux/fs/nls/nls_koi8-ru.c (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
11da177e4SLinus Torvalds /*
2*f30c2269SUwe Zeisberger  * linux/fs/nls/nls_koi8-ru.c
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Charset koi8-ru translation based on charset koi8-u.
51da177e4SLinus Torvalds  * The Unicode to charset table has only exact mappings.
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #include <linux/module.h>
91da177e4SLinus Torvalds #include <linux/kernel.h>
101da177e4SLinus Torvalds #include <linux/string.h>
111da177e4SLinus Torvalds #include <linux/nls.h>
121da177e4SLinus Torvalds #include <linux/errno.h>
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds static struct nls_table *p_nls;
151da177e4SLinus Torvalds 
uni2char(const wchar_t uni,unsigned char * out,int boundlen)161da177e4SLinus Torvalds static int uni2char(const wchar_t uni,
171da177e4SLinus Torvalds 		    unsigned char *out, int boundlen)
181da177e4SLinus Torvalds {
191da177e4SLinus Torvalds 	if (boundlen <= 0)
201da177e4SLinus Torvalds 		return -ENAMETOOLONG;
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds 	if ((uni & 0xffaf) == 0x040e || (uni & 0xffce) == 0x254c) {
231da177e4SLinus Torvalds 		/* koi8-ru and koi8-u differ only on two characters */
241da177e4SLinus Torvalds 		if (uni == 0x040e)
251da177e4SLinus Torvalds 			out[0] = 0xbe;
261da177e4SLinus Torvalds 		else if (uni == 0x045e)
271da177e4SLinus Torvalds 			out[0] = 0xae;
281da177e4SLinus Torvalds 		else if (uni == 0x255d || uni == 0x256c)
291da177e4SLinus Torvalds 			return 0;
301da177e4SLinus Torvalds 		else
311da177e4SLinus Torvalds 			return p_nls->uni2char(uni, out, boundlen);
321da177e4SLinus Torvalds 		return 1;
331da177e4SLinus Torvalds 	}
341da177e4SLinus Torvalds 	else
351da177e4SLinus Torvalds 		/* fast path */
361da177e4SLinus Torvalds 		return p_nls->uni2char(uni, out, boundlen);
371da177e4SLinus Torvalds }
381da177e4SLinus Torvalds 
char2uni(const unsigned char * rawstring,int boundlen,wchar_t * uni)391da177e4SLinus Torvalds static int char2uni(const unsigned char *rawstring, int boundlen,
401da177e4SLinus Torvalds 		    wchar_t *uni)
411da177e4SLinus Torvalds {
421da177e4SLinus Torvalds 	int n;
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds 	if ((*rawstring & 0xef) != 0xae) {
451da177e4SLinus Torvalds 		/* koi8-ru and koi8-u differ only on two characters */
461da177e4SLinus Torvalds 		*uni = (*rawstring & 0x10) ? 0x040e : 0x045e;
471da177e4SLinus Torvalds 		return 1;
481da177e4SLinus Torvalds 	}
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds 	n = p_nls->char2uni(rawstring, boundlen, uni);
511da177e4SLinus Torvalds 	return n;
521da177e4SLinus Torvalds }
531da177e4SLinus Torvalds 
541da177e4SLinus Torvalds static struct nls_table table = {
551da177e4SLinus Torvalds 	.charset	= "koi8-ru",
561da177e4SLinus Torvalds 	.uni2char	= uni2char,
571da177e4SLinus Torvalds 	.char2uni	= char2uni,
581da177e4SLinus Torvalds };
591da177e4SLinus Torvalds 
init_nls_koi8_ru(void)601da177e4SLinus Torvalds static int __init init_nls_koi8_ru(void)
611da177e4SLinus Torvalds {
621da177e4SLinus Torvalds 	p_nls = load_nls("koi8-u");
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds 	if (p_nls) {
651da177e4SLinus Torvalds 		table.charset2upper = p_nls->charset2upper;
661da177e4SLinus Torvalds 		table.charset2lower = p_nls->charset2lower;
671da177e4SLinus Torvalds 		return register_nls(&table);
681da177e4SLinus Torvalds 	}
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds 	return -EINVAL;
711da177e4SLinus Torvalds }
721da177e4SLinus Torvalds 
exit_nls_koi8_ru(void)731da177e4SLinus Torvalds static void __exit exit_nls_koi8_ru(void)
741da177e4SLinus Torvalds {
751da177e4SLinus Torvalds 	unregister_nls(&table);
761da177e4SLinus Torvalds 	unload_nls(p_nls);
771da177e4SLinus Torvalds }
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds module_init(init_nls_koi8_ru)
801da177e4SLinus Torvalds module_exit(exit_nls_koi8_ru)
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds MODULE_LICENSE("Dual BSD/GPL");
83