18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Module for handling utf8 just like any other charset. 38c2ecf20Sopenharmony_ci * By Urban Widmark 2000 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/module.h> 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <linux/string.h> 98c2ecf20Sopenharmony_ci#include <linux/nls.h> 108c2ecf20Sopenharmony_ci#include <linux/errno.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic unsigned char identity[256]; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic int uni2char(wchar_t uni, unsigned char *out, int boundlen) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci int n; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci if (boundlen <= 0) 198c2ecf20Sopenharmony_ci return -ENAMETOOLONG; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci n = utf32_to_utf8(uni, out, boundlen); 228c2ecf20Sopenharmony_ci if (n < 0) { 238c2ecf20Sopenharmony_ci *out = '?'; 248c2ecf20Sopenharmony_ci return -EINVAL; 258c2ecf20Sopenharmony_ci } 268c2ecf20Sopenharmony_ci return n; 278c2ecf20Sopenharmony_ci} 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci int n; 328c2ecf20Sopenharmony_ci unicode_t u; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci n = utf8_to_utf32(rawstring, boundlen, &u); 358c2ecf20Sopenharmony_ci if (n < 0 || u > MAX_WCHAR_T) { 368c2ecf20Sopenharmony_ci *uni = 0x003f; /* ? */ 378c2ecf20Sopenharmony_ci return -EINVAL; 388c2ecf20Sopenharmony_ci } 398c2ecf20Sopenharmony_ci *uni = (wchar_t) u; 408c2ecf20Sopenharmony_ci return n; 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic struct nls_table table = { 448c2ecf20Sopenharmony_ci .charset = "utf8", 458c2ecf20Sopenharmony_ci .uni2char = uni2char, 468c2ecf20Sopenharmony_ci .char2uni = char2uni, 478c2ecf20Sopenharmony_ci .charset2lower = identity, /* no conversion */ 488c2ecf20Sopenharmony_ci .charset2upper = identity, 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic int __init init_nls_utf8(void) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci int i; 548c2ecf20Sopenharmony_ci for (i=0; i<256; i++) 558c2ecf20Sopenharmony_ci identity[i] = i; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci return register_nls(&table); 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic void __exit exit_nls_utf8(void) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci unregister_nls(&table); 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cimodule_init(init_nls_utf8) 668c2ecf20Sopenharmony_cimodule_exit(exit_nls_utf8) 678c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 68