^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Module for handling utf8 just like any other charset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * By Urban Widmark 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/nls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static unsigned char identity[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) if (boundlen <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) n = utf32_to_utf8(uni, out, boundlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (n < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *out = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unicode_t u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) n = utf8_to_utf32(rawstring, boundlen, &u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (n < 0 || u > MAX_WCHAR_T) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *uni = 0x003f; /* ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *uni = (wchar_t) u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static struct nls_table table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .charset = "utf8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .uni2char = uni2char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .char2uni = char2uni,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .charset2lower = identity, /* no conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .charset2upper = identity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int __init init_nls_utf8(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) for (i=0; i<256; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) identity[i] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return register_nls(&table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static void __exit exit_nls_utf8(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unregister_nls(&table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) module_init(init_nls_utf8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) module_exit(exit_nls_utf8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) MODULE_LICENSE("Dual BSD/GPL");