2005-04-17 02:20:36 +04:00
/*
2006-10-04 01:01:26 +04:00
* linux / fs / nls / nls_base . c
2005-04-17 02:20:36 +04:00
*
* Native language support - - charsets and unicode translations .
* By Gordon Chaffee 1996 , 1997
*
* Unicode based case conversion 1999 by Wolfram Pienkoss
*
*/
# include <linux/module.h>
# include <linux/string.h>
# include <linux/nls.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/kmod.h>
# include <linux/spinlock.h>
2009-04-30 18:08:18 +04:00
# include <asm/byteorder.h>
2005-04-17 02:20:36 +04:00
static struct nls_table default_table ;
static struct nls_table * tables = & default_table ;
static DEFINE_SPINLOCK ( nls_lock ) ;
/*
* Sample implementation from Unicode home page .
* http : //www.stonehand.com/unicode/standard/fss-utf.html
*/
struct utf8_table {
int cmask ;
int cval ;
int shift ;
long lmask ;
long lval ;
} ;
2007-10-17 10:29:54 +04:00
static const struct utf8_table utf8_table [ ] =
2005-04-17 02:20:36 +04:00
{
{ 0x80 , 0x00 , 0 * 6 , 0x7F , 0 , /* 1 byte sequence */ } ,
{ 0xE0 , 0xC0 , 1 * 6 , 0x7FF , 0x80 , /* 2 byte sequence */ } ,
{ 0xF0 , 0xE0 , 2 * 6 , 0xFFFF , 0x800 , /* 3 byte sequence */ } ,
{ 0xF8 , 0xF0 , 3 * 6 , 0x1FFFFF , 0x10000 , /* 4 byte sequence */ } ,
{ 0xFC , 0xF8 , 4 * 6 , 0x3FFFFFF , 0x200000 , /* 5 byte sequence */ } ,
{ 0xFE , 0xFC , 5 * 6 , 0x7FFFFFFF , 0x4000000 , /* 6 byte sequence */ } ,
{ 0 , /* end of table */ }
} ;
2009-04-30 18:08:18 +04:00
# define UNICODE_MAX 0x0010ffff
# define PLANE_SIZE 0x00010000
# define SURROGATE_MASK 0xfffff800
# define SURROGATE_PAIR 0x0000d800
# define SURROGATE_LOW 0x00000400
# define SURROGATE_BITS 0x000003ff
2011-11-21 19:15:13 +04:00
int utf8_to_utf32 ( const u8 * s , int inlen , unicode_t * pu )
2005-04-17 02:20:36 +04:00
{
2009-04-30 18:08:18 +04:00
unsigned long l ;
2005-04-17 02:20:36 +04:00
int c0 , c , nc ;
2007-10-17 10:29:54 +04:00
const struct utf8_table * t ;
2005-04-17 02:20:36 +04:00
nc = 0 ;
c0 = * s ;
l = c0 ;
for ( t = utf8_table ; t - > cmask ; t + + ) {
nc + + ;
if ( ( c0 & t - > cmask ) = = t - > cval ) {
l & = t - > lmask ;
2009-04-30 18:08:18 +04:00
if ( l < t - > lval | | l > UNICODE_MAX | |
( l & SURROGATE_MASK ) = = SURROGATE_PAIR )
2005-04-17 02:20:36 +04:00
return - 1 ;
2009-04-30 18:08:18 +04:00
* pu = ( unicode_t ) l ;
2005-04-17 02:20:36 +04:00
return nc ;
}
2011-11-21 19:15:13 +04:00
if ( inlen < = nc )
2005-04-17 02:20:36 +04:00
return - 1 ;
s + + ;
c = ( * s ^ 0x80 ) & 0xFF ;
if ( c & 0xC0 )
return - 1 ;
l = ( l < < 6 ) | c ;
}
return - 1 ;
}
2009-04-30 18:08:18 +04:00
EXPORT_SYMBOL ( utf8_to_utf32 ) ;
2005-04-17 02:20:36 +04:00
2011-11-21 19:15:13 +04:00
int utf32_to_utf8 ( unicode_t u , u8 * s , int maxout )
2005-04-17 02:20:36 +04:00
{
2009-04-30 18:08:18 +04:00
unsigned long l ;
2005-04-17 02:20:36 +04:00
int c , nc ;
2007-10-17 10:29:54 +04:00
const struct utf8_table * t ;
2009-04-30 18:08:18 +04:00
2007-10-18 14:07:05 +04:00
if ( ! s )
2005-04-17 02:20:36 +04:00
return 0 ;
2009-04-30 18:08:18 +04:00
l = u ;
if ( l > UNICODE_MAX | | ( l & SURROGATE_MASK ) = = SURROGATE_PAIR )
return - 1 ;
2005-04-17 02:20:36 +04:00
nc = 0 ;
2011-11-21 19:15:13 +04:00
for ( t = utf8_table ; t - > cmask & & maxout ; t + + , maxout - - ) {
2005-04-17 02:20:36 +04:00
nc + + ;
if ( l < = t - > lmask ) {
c = t - > shift ;
2009-04-30 18:08:18 +04:00
* s = ( u8 ) ( t - > cval | ( l > > c ) ) ;
2005-04-17 02:20:36 +04:00
while ( c > 0 ) {
c - = 6 ;
s + + ;
2009-04-30 18:08:18 +04:00
* s = ( u8 ) ( 0x80 | ( ( l > > c ) & 0x3F ) ) ;
2005-04-17 02:20:36 +04:00
}
return nc ;
}
}
return - 1 ;
}
2009-04-30 18:08:18 +04:00
EXPORT_SYMBOL ( utf32_to_utf8 ) ;
2005-04-17 02:20:36 +04:00
2011-11-18 01:42:19 +04:00
static inline void put_utf16 ( wchar_t * s , unsigned c , enum utf16_endian endian )
{
switch ( endian ) {
default :
* s = ( wchar_t ) c ;
break ;
case UTF16_LITTLE_ENDIAN :
* s = __cpu_to_le16 ( c ) ;
break ;
case UTF16_BIG_ENDIAN :
* s = __cpu_to_be16 ( c ) ;
break ;
}
}
2011-11-21 19:15:13 +04:00
int utf8s_to_utf16s ( const u8 * s , int inlen , enum utf16_endian endian ,
wchar_t * pwcs , int maxout )
2005-04-17 02:20:36 +04:00
{
2009-04-30 18:08:18 +04:00
u16 * op ;
2005-04-17 02:20:36 +04:00
int size ;
2009-04-30 18:08:18 +04:00
unicode_t u ;
op = pwcs ;
2011-11-21 19:15:13 +04:00
while ( inlen > 0 & & maxout > 0 & & * s ) {
2009-04-30 18:08:18 +04:00
if ( * s & 0x80 ) {
2011-11-21 19:15:13 +04:00
size = utf8_to_utf32 ( s , inlen , & u ) ;
2009-08-01 16:30:31 +04:00
if ( size < 0 )
return - EINVAL ;
2011-11-18 01:42:19 +04:00
s + = size ;
2011-11-21 19:15:13 +04:00
inlen - = size ;
2009-08-01 16:30:31 +04:00
if ( u > = PLANE_SIZE ) {
2011-11-21 19:15:13 +04:00
if ( maxout < 2 )
2011-11-18 01:42:19 +04:00
break ;
2009-04-30 18:08:18 +04:00
u - = PLANE_SIZE ;
2011-11-18 01:42:19 +04:00
put_utf16 ( op + + , SURROGATE_PAIR |
( ( u > > 10 ) & SURROGATE_BITS ) ,
endian ) ;
put_utf16 ( op + + , SURROGATE_PAIR |
2009-04-30 18:08:18 +04:00
SURROGATE_LOW |
2011-11-18 01:42:19 +04:00
( u & SURROGATE_BITS ) ,
endian ) ;
2011-11-21 19:15:13 +04:00
maxout - = 2 ;
2009-04-30 18:08:18 +04:00
} else {
2011-11-18 01:42:19 +04:00
put_utf16 ( op + + , u , endian ) ;
2011-11-21 19:15:13 +04:00
maxout - - ;
2009-04-30 18:08:18 +04:00
}
} else {
2011-11-18 01:42:19 +04:00
put_utf16 ( op + + , * s + + , endian ) ;
2011-11-21 19:15:13 +04:00
inlen - - ;
maxout - - ;
2009-04-30 18:08:18 +04:00
}
}
return op - pwcs ;
}
EXPORT_SYMBOL ( utf8s_to_utf16s ) ;
static inline unsigned long get_utf16 ( unsigned c , enum utf16_endian endian )
{
switch ( endian ) {
default :
return c ;
case UTF16_LITTLE_ENDIAN :
return __le16_to_cpu ( c ) ;
case UTF16_BIG_ENDIAN :
return __be16_to_cpu ( c ) ;
}
}
2011-11-21 19:15:13 +04:00
int utf16s_to_utf8s ( const wchar_t * pwcs , int inlen , enum utf16_endian endian ,
u8 * s , int maxout )
2009-04-30 18:08:18 +04:00
{
u8 * op ;
int size ;
unsigned long u , v ;
2005-04-17 02:20:36 +04:00
op = s ;
2011-11-21 19:15:13 +04:00
while ( inlen > 0 & & maxout > 0 ) {
2009-04-30 18:08:18 +04:00
u = get_utf16 ( * pwcs , endian ) ;
if ( ! u )
break ;
pwcs + + ;
2011-11-21 19:15:13 +04:00
inlen - - ;
2009-04-30 18:08:18 +04:00
if ( u > 0x7f ) {
if ( ( u & SURROGATE_MASK ) = = SURROGATE_PAIR ) {
if ( u & SURROGATE_LOW ) {
/* Ignore character and move on */
continue ;
}
2011-11-21 19:15:13 +04:00
if ( inlen < = 0 )
2009-04-30 18:08:18 +04:00
break ;
v = get_utf16 ( * pwcs , endian ) ;
if ( ( v & SURROGATE_MASK ) ! = SURROGATE_PAIR | |
! ( v & SURROGATE_LOW ) ) {
/* Ignore character and move on */
continue ;
}
u = PLANE_SIZE + ( ( u & SURROGATE_BITS ) < < 10 )
+ ( v & SURROGATE_BITS ) ;
pwcs + + ;
2011-11-21 19:15:13 +04:00
inlen - - ;
2009-04-30 18:08:18 +04:00
}
2011-11-21 19:15:13 +04:00
size = utf32_to_utf8 ( u , op , maxout ) ;
2005-04-17 02:20:36 +04:00
if ( size = = - 1 ) {
/* Ignore character and move on */
} else {
op + = size ;
2011-11-21 19:15:13 +04:00
maxout - = size ;
2005-04-17 02:20:36 +04:00
}
} else {
2009-04-30 18:08:18 +04:00
* op + + = ( u8 ) u ;
2011-11-21 19:15:13 +04:00
maxout - - ;
2005-04-17 02:20:36 +04:00
}
}
2009-04-30 18:08:18 +04:00
return op - s ;
2005-04-17 02:20:36 +04:00
}
2009-04-30 18:08:18 +04:00
EXPORT_SYMBOL ( utf16s_to_utf8s ) ;
2005-04-17 02:20:36 +04:00
2013-11-22 10:45:04 +04:00
int __register_nls ( struct nls_table * nls , struct module * owner )
2005-04-17 02:20:36 +04:00
{
struct nls_table * * tmp = & tables ;
if ( nls - > next )
return - EBUSY ;
2013-11-22 10:45:04 +04:00
nls - > owner = owner ;
2005-04-17 02:20:36 +04:00
spin_lock ( & nls_lock ) ;
while ( * tmp ) {
if ( nls = = * tmp ) {
spin_unlock ( & nls_lock ) ;
return - EBUSY ;
}
tmp = & ( * tmp ) - > next ;
}
nls - > next = tables ;
tables = nls ;
spin_unlock ( & nls_lock ) ;
return 0 ;
}
2013-11-22 10:45:04 +04:00
EXPORT_SYMBOL ( __register_nls ) ;
2005-04-17 02:20:36 +04:00
int unregister_nls ( struct nls_table * nls )
{
struct nls_table * * tmp = & tables ;
spin_lock ( & nls_lock ) ;
while ( * tmp ) {
if ( nls = = * tmp ) {
* tmp = nls - > next ;
spin_unlock ( & nls_lock ) ;
return 0 ;
}
tmp = & ( * tmp ) - > next ;
}
spin_unlock ( & nls_lock ) ;
return - EINVAL ;
}
static struct nls_table * find_nls ( char * charset )
{
struct nls_table * nls ;
spin_lock ( & nls_lock ) ;
for ( nls = tables ; nls ; nls = nls - > next ) {
if ( ! strcmp ( nls - > charset , charset ) )
break ;
if ( nls - > alias & & ! strcmp ( nls - > alias , charset ) )
break ;
}
if ( nls & & ! try_module_get ( nls - > owner ) )
nls = NULL ;
spin_unlock ( & nls_lock ) ;
return nls ;
}
struct nls_table * load_nls ( char * charset )
{
2008-07-09 12:28:40 +04:00
return try_then_request_module ( find_nls ( charset ) , " nls_%s " , charset ) ;
2005-04-17 02:20:36 +04:00
}
void unload_nls ( struct nls_table * nls )
{
2009-08-17 01:05:08 +04:00
if ( nls )
module_put ( nls - > owner ) ;
2005-04-17 02:20:36 +04:00
}
2007-10-17 10:29:54 +04:00
static const wchar_t charset2uni [ 256 ] = {
2005-04-17 02:20:36 +04:00
/* 0x00*/
0x0000 , 0x0001 , 0x0002 , 0x0003 ,
0x0004 , 0x0005 , 0x0006 , 0x0007 ,
0x0008 , 0x0009 , 0x000a , 0x000b ,
0x000c , 0x000d , 0x000e , 0x000f ,
/* 0x10*/
0x0010 , 0x0011 , 0x0012 , 0x0013 ,
0x0014 , 0x0015 , 0x0016 , 0x0017 ,
0x0018 , 0x0019 , 0x001a , 0x001b ,
0x001c , 0x001d , 0x001e , 0x001f ,
/* 0x20*/
0x0020 , 0x0021 , 0x0022 , 0x0023 ,
0x0024 , 0x0025 , 0x0026 , 0x0027 ,
0x0028 , 0x0029 , 0x002a , 0x002b ,
0x002c , 0x002d , 0x002e , 0x002f ,
/* 0x30*/
0x0030 , 0x0031 , 0x0032 , 0x0033 ,
0x0034 , 0x0035 , 0x0036 , 0x0037 ,
0x0038 , 0x0039 , 0x003a , 0x003b ,
0x003c , 0x003d , 0x003e , 0x003f ,
/* 0x40*/
0x0040 , 0x0041 , 0x0042 , 0x0043 ,
0x0044 , 0x0045 , 0x0046 , 0x0047 ,
0x0048 , 0x0049 , 0x004a , 0x004b ,
0x004c , 0x004d , 0x004e , 0x004f ,
/* 0x50*/
0x0050 , 0x0051 , 0x0052 , 0x0053 ,
0x0054 , 0x0055 , 0x0056 , 0x0057 ,
0x0058 , 0x0059 , 0x005a , 0x005b ,
0x005c , 0x005d , 0x005e , 0x005f ,
/* 0x60*/
0x0060 , 0x0061 , 0x0062 , 0x0063 ,
0x0064 , 0x0065 , 0x0066 , 0x0067 ,
0x0068 , 0x0069 , 0x006a , 0x006b ,
0x006c , 0x006d , 0x006e , 0x006f ,
/* 0x70*/
0x0070 , 0x0071 , 0x0072 , 0x0073 ,
0x0074 , 0x0075 , 0x0076 , 0x0077 ,
0x0078 , 0x0079 , 0x007a , 0x007b ,
0x007c , 0x007d , 0x007e , 0x007f ,
/* 0x80*/
0x0080 , 0x0081 , 0x0082 , 0x0083 ,
0x0084 , 0x0085 , 0x0086 , 0x0087 ,
0x0088 , 0x0089 , 0x008a , 0x008b ,
0x008c , 0x008d , 0x008e , 0x008f ,
/* 0x90*/
0x0090 , 0x0091 , 0x0092 , 0x0093 ,
0x0094 , 0x0095 , 0x0096 , 0x0097 ,
0x0098 , 0x0099 , 0x009a , 0x009b ,
0x009c , 0x009d , 0x009e , 0x009f ,
/* 0xa0*/
0x00a0 , 0x00a1 , 0x00a2 , 0x00a3 ,
0x00a4 , 0x00a5 , 0x00a6 , 0x00a7 ,
0x00a8 , 0x00a9 , 0x00aa , 0x00ab ,
0x00ac , 0x00ad , 0x00ae , 0x00af ,
/* 0xb0*/
0x00b0 , 0x00b1 , 0x00b2 , 0x00b3 ,
0x00b4 , 0x00b5 , 0x00b6 , 0x00b7 ,
0x00b8 , 0x00b9 , 0x00ba , 0x00bb ,
0x00bc , 0x00bd , 0x00be , 0x00bf ,
/* 0xc0*/
0x00c0 , 0x00c1 , 0x00c2 , 0x00c3 ,
0x00c4 , 0x00c5 , 0x00c6 , 0x00c7 ,
0x00c8 , 0x00c9 , 0x00ca , 0x00cb ,
0x00cc , 0x00cd , 0x00ce , 0x00cf ,
/* 0xd0*/
0x00d0 , 0x00d1 , 0x00d2 , 0x00d3 ,
0x00d4 , 0x00d5 , 0x00d6 , 0x00d7 ,
0x00d8 , 0x00d9 , 0x00da , 0x00db ,
0x00dc , 0x00dd , 0x00de , 0x00df ,
/* 0xe0*/
0x00e0 , 0x00e1 , 0x00e2 , 0x00e3 ,
0x00e4 , 0x00e5 , 0x00e6 , 0x00e7 ,
0x00e8 , 0x00e9 , 0x00ea , 0x00eb ,
0x00ec , 0x00ed , 0x00ee , 0x00ef ,
/* 0xf0*/
0x00f0 , 0x00f1 , 0x00f2 , 0x00f3 ,
0x00f4 , 0x00f5 , 0x00f6 , 0x00f7 ,
0x00f8 , 0x00f9 , 0x00fa , 0x00fb ,
0x00fc , 0x00fd , 0x00fe , 0x00ff ,
} ;
2007-10-17 10:29:54 +04:00
static const unsigned char page00 [ 256 ] = {
2005-04-17 02:20:36 +04:00
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , /* 0x00-0x07 */
0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , /* 0x08-0x0f */
0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 , /* 0x10-0x17 */
0x18 , 0x19 , 0x1a , 0x1b , 0x1c , 0x1d , 0x1e , 0x1f , /* 0x18-0x1f */
0x20 , 0x21 , 0x22 , 0x23 , 0x24 , 0x25 , 0x26 , 0x27 , /* 0x20-0x27 */
0x28 , 0x29 , 0x2a , 0x2b , 0x2c , 0x2d , 0x2e , 0x2f , /* 0x28-0x2f */
0x30 , 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 , /* 0x30-0x37 */
0x38 , 0x39 , 0x3a , 0x3b , 0x3c , 0x3d , 0x3e , 0x3f , /* 0x38-0x3f */
0x40 , 0x41 , 0x42 , 0x43 , 0x44 , 0x45 , 0x46 , 0x47 , /* 0x40-0x47 */
0x48 , 0x49 , 0x4a , 0x4b , 0x4c , 0x4d , 0x4e , 0x4f , /* 0x48-0x4f */
0x50 , 0x51 , 0x52 , 0x53 , 0x54 , 0x55 , 0x56 , 0x57 , /* 0x50-0x57 */
0x58 , 0x59 , 0x5a , 0x5b , 0x5c , 0x5d , 0x5e , 0x5f , /* 0x58-0x5f */
0x60 , 0x61 , 0x62 , 0x63 , 0x64 , 0x65 , 0x66 , 0x67 , /* 0x60-0x67 */
0x68 , 0x69 , 0x6a , 0x6b , 0x6c , 0x6d , 0x6e , 0x6f , /* 0x68-0x6f */
0x70 , 0x71 , 0x72 , 0x73 , 0x74 , 0x75 , 0x76 , 0x77 , /* 0x70-0x77 */
0x78 , 0x79 , 0x7a , 0x7b , 0x7c , 0x7d , 0x7e , 0x7f , /* 0x78-0x7f */
0x80 , 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 , /* 0x80-0x87 */
0x88 , 0x89 , 0x8a , 0x8b , 0x8c , 0x8d , 0x8e , 0x8f , /* 0x88-0x8f */
0x90 , 0x91 , 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 , /* 0x90-0x97 */
0x98 , 0x99 , 0x9a , 0x9b , 0x9c , 0x9d , 0x9e , 0x9f , /* 0x98-0x9f */
0xa0 , 0xa1 , 0xa2 , 0xa3 , 0xa4 , 0xa5 , 0xa6 , 0xa7 , /* 0xa0-0xa7 */
0xa8 , 0xa9 , 0xaa , 0xab , 0xac , 0xad , 0xae , 0xaf , /* 0xa8-0xaf */
0xb0 , 0xb1 , 0xb2 , 0xb3 , 0xb4 , 0xb5 , 0xb6 , 0xb7 , /* 0xb0-0xb7 */
0xb8 , 0xb9 , 0xba , 0xbb , 0xbc , 0xbd , 0xbe , 0xbf , /* 0xb8-0xbf */
0xc0 , 0xc1 , 0xc2 , 0xc3 , 0xc4 , 0xc5 , 0xc6 , 0xc7 , /* 0xc0-0xc7 */
0xc8 , 0xc9 , 0xca , 0xcb , 0xcc , 0xcd , 0xce , 0xcf , /* 0xc8-0xcf */
0xd0 , 0xd1 , 0xd2 , 0xd3 , 0xd4 , 0xd5 , 0xd6 , 0xd7 , /* 0xd0-0xd7 */
0xd8 , 0xd9 , 0xda , 0xdb , 0xdc , 0xdd , 0xde , 0xdf , /* 0xd8-0xdf */
0xe0 , 0xe1 , 0xe2 , 0xe3 , 0xe4 , 0xe5 , 0xe6 , 0xe7 , /* 0xe0-0xe7 */
0xe8 , 0xe9 , 0xea , 0xeb , 0xec , 0xed , 0xee , 0xef , /* 0xe8-0xef */
0xf0 , 0xf1 , 0xf2 , 0xf3 , 0xf4 , 0xf5 , 0xf6 , 0xf7 , /* 0xf0-0xf7 */
0xf8 , 0xf9 , 0xfa , 0xfb , 0xfc , 0xfd , 0xfe , 0xff , /* 0xf8-0xff */
} ;
2007-10-17 10:29:54 +04:00
static const unsigned char * const page_uni2charset [ 256 ] = {
2005-04-17 02:20:36 +04:00
page00
} ;
2007-10-17 10:29:54 +04:00
static const unsigned char charset2lower [ 256 ] = {
2005-04-17 02:20:36 +04:00
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , /* 0x00-0x07 */
0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , /* 0x08-0x0f */
0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 , /* 0x10-0x17 */
0x18 , 0x19 , 0x1a , 0x1b , 0x1c , 0x1d , 0x1e , 0x1f , /* 0x18-0x1f */
0x20 , 0x21 , 0x22 , 0x23 , 0x24 , 0x25 , 0x26 , 0x27 , /* 0x20-0x27 */
0x28 , 0x29 , 0x2a , 0x2b , 0x2c , 0x2d , 0x2e , 0x2f , /* 0x28-0x2f */
0x30 , 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 , /* 0x30-0x37 */
0x38 , 0x39 , 0x3a , 0x3b , 0x3c , 0x3d , 0x3e , 0x3f , /* 0x38-0x3f */
0x40 , 0x61 , 0x62 , 0x63 , 0x64 , 0x65 , 0x66 , 0x67 , /* 0x40-0x47 */
0x68 , 0x69 , 0x6a , 0x6b , 0x6c , 0x6d , 0x6e , 0x6f , /* 0x48-0x4f */
0x70 , 0x71 , 0x72 , 0x73 , 0x74 , 0x75 , 0x76 , 0x77 , /* 0x50-0x57 */
0x78 , 0x79 , 0x7a , 0x5b , 0x5c , 0x5d , 0x5e , 0x5f , /* 0x58-0x5f */
0x60 , 0x61 , 0x62 , 0x63 , 0x64 , 0x65 , 0x66 , 0x67 , /* 0x60-0x67 */
0x68 , 0x69 , 0x6a , 0x6b , 0x6c , 0x6d , 0x6e , 0x6f , /* 0x68-0x6f */
0x70 , 0x71 , 0x72 , 0x73 , 0x74 , 0x75 , 0x76 , 0x77 , /* 0x70-0x77 */
0x78 , 0x79 , 0x7a , 0x7b , 0x7c , 0x7d , 0x7e , 0x7f , /* 0x78-0x7f */
0x80 , 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 , /* 0x80-0x87 */
0x88 , 0x89 , 0x8a , 0x8b , 0x8c , 0x8d , 0x8e , 0x8f , /* 0x88-0x8f */
0x90 , 0x91 , 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 , /* 0x90-0x97 */
0x98 , 0x99 , 0x9a , 0x9b , 0x9c , 0x9d , 0x9e , 0x9f , /* 0x98-0x9f */
0xa0 , 0xa1 , 0xa2 , 0xa3 , 0xa4 , 0xa5 , 0xa6 , 0xa7 , /* 0xa0-0xa7 */
0xa8 , 0xa9 , 0xaa , 0xab , 0xac , 0xad , 0xae , 0xaf , /* 0xa8-0xaf */
0xb0 , 0xb1 , 0xb2 , 0xb3 , 0xb4 , 0xb5 , 0xb6 , 0xb7 , /* 0xb0-0xb7 */
0xb8 , 0xb9 , 0xba , 0xbb , 0xbc , 0xbd , 0xbe , 0xbf , /* 0xb8-0xbf */
0xc0 , 0xc1 , 0xc2 , 0xc3 , 0xc4 , 0xc5 , 0xc6 , 0xc7 , /* 0xc0-0xc7 */
0xc8 , 0xc9 , 0xca , 0xcb , 0xcc , 0xcd , 0xce , 0xcf , /* 0xc8-0xcf */
0xd0 , 0xd1 , 0xd2 , 0xd3 , 0xd4 , 0xd5 , 0xd6 , 0xd7 , /* 0xd0-0xd7 */
0xd8 , 0xd9 , 0xda , 0xdb , 0xdc , 0xdd , 0xde , 0xdf , /* 0xd8-0xdf */
0xe0 , 0xe1 , 0xe2 , 0xe3 , 0xe4 , 0xe5 , 0xe6 , 0xe7 , /* 0xe0-0xe7 */
0xe8 , 0xe9 , 0xea , 0xeb , 0xec , 0xed , 0xee , 0xef , /* 0xe8-0xef */
0xf0 , 0xf1 , 0xf2 , 0xf3 , 0xf4 , 0xf5 , 0xf6 , 0xf7 , /* 0xf0-0xf7 */
0xf8 , 0xf9 , 0xfa , 0xfb , 0xfc , 0xfd , 0xfe , 0xff , /* 0xf8-0xff */
} ;
2007-10-17 10:29:54 +04:00
static const unsigned char charset2upper [ 256 ] = {
2005-04-17 02:20:36 +04:00
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , /* 0x00-0x07 */
0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , /* 0x08-0x0f */
0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 , /* 0x10-0x17 */
0x18 , 0x19 , 0x1a , 0x1b , 0x1c , 0x1d , 0x1e , 0x1f , /* 0x18-0x1f */
0x20 , 0x21 , 0x22 , 0x23 , 0x24 , 0x25 , 0x26 , 0x27 , /* 0x20-0x27 */
0x28 , 0x29 , 0x2a , 0x2b , 0x2c , 0x2d , 0x2e , 0x2f , /* 0x28-0x2f */
0x30 , 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 , /* 0x30-0x37 */
0x38 , 0x39 , 0x3a , 0x3b , 0x3c , 0x3d , 0x3e , 0x3f , /* 0x38-0x3f */
0x40 , 0x41 , 0x42 , 0x43 , 0x44 , 0x45 , 0x46 , 0x47 , /* 0x40-0x47 */
0x48 , 0x49 , 0x4a , 0x4b , 0x4c , 0x4d , 0x4e , 0x4f , /* 0x48-0x4f */
0x50 , 0x51 , 0x52 , 0x53 , 0x54 , 0x55 , 0x56 , 0x57 , /* 0x50-0x57 */
0x58 , 0x59 , 0x5a , 0x5b , 0x5c , 0x5d , 0x5e , 0x5f , /* 0x58-0x5f */
0x60 , 0x41 , 0x42 , 0x43 , 0x44 , 0x45 , 0x46 , 0x47 , /* 0x60-0x67 */
0x48 , 0x49 , 0x4a , 0x4b , 0x4c , 0x4d , 0x4e , 0x4f , /* 0x68-0x6f */
0x50 , 0x51 , 0x52 , 0x53 , 0x54 , 0x55 , 0x56 , 0x57 , /* 0x70-0x77 */
0x58 , 0x59 , 0x5a , 0x7b , 0x7c , 0x7d , 0x7e , 0x7f , /* 0x78-0x7f */
0x80 , 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 , /* 0x80-0x87 */
0x88 , 0x89 , 0x8a , 0x8b , 0x8c , 0x8d , 0x8e , 0x8f , /* 0x88-0x8f */
0x90 , 0x91 , 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 , /* 0x90-0x97 */
0x98 , 0x99 , 0x9a , 0x9b , 0x9c , 0x9d , 0x9e , 0x9f , /* 0x98-0x9f */
0xa0 , 0xa1 , 0xa2 , 0xa3 , 0xa4 , 0xa5 , 0xa6 , 0xa7 , /* 0xa0-0xa7 */
0xa8 , 0xa9 , 0xaa , 0xab , 0xac , 0xad , 0xae , 0xaf , /* 0xa8-0xaf */
0xb0 , 0xb1 , 0xb2 , 0xb3 , 0xb4 , 0xb5 , 0xb6 , 0xb7 , /* 0xb0-0xb7 */
0xb8 , 0xb9 , 0xba , 0xbb , 0xbc , 0xbd , 0xbe , 0xbf , /* 0xb8-0xbf */
0xc0 , 0xc1 , 0xc2 , 0xc3 , 0xc4 , 0xc5 , 0xc6 , 0xc7 , /* 0xc0-0xc7 */
0xc8 , 0xc9 , 0xca , 0xcb , 0xcc , 0xcd , 0xce , 0xcf , /* 0xc8-0xcf */
0xd0 , 0xd1 , 0xd2 , 0xd3 , 0xd4 , 0xd5 , 0xd6 , 0xd7 , /* 0xd0-0xd7 */
0xd8 , 0xd9 , 0xda , 0xdb , 0xdc , 0xdd , 0xde , 0xdf , /* 0xd8-0xdf */
0xe0 , 0xe1 , 0xe2 , 0xe3 , 0xe4 , 0xe5 , 0xe6 , 0xe7 , /* 0xe0-0xe7 */
0xe8 , 0xe9 , 0xea , 0xeb , 0xec , 0xed , 0xee , 0xef , /* 0xe8-0xef */
0xf0 , 0xf1 , 0xf2 , 0xf3 , 0xf4 , 0xf5 , 0xf6 , 0xf7 , /* 0xf0-0xf7 */
0xf8 , 0xf9 , 0xfa , 0xfb , 0xfc , 0xfd , 0xfe , 0xff , /* 0xf8-0xff */
} ;
static int uni2char ( wchar_t uni , unsigned char * out , int boundlen )
{
2007-10-17 10:29:54 +04:00
const unsigned char * uni2charset ;
2005-04-17 02:20:36 +04:00
unsigned char cl = uni & 0x00ff ;
unsigned char ch = ( uni & 0xff00 ) > > 8 ;
if ( boundlen < = 0 )
return - ENAMETOOLONG ;
uni2charset = page_uni2charset [ ch ] ;
if ( uni2charset & & uni2charset [ cl ] )
out [ 0 ] = uni2charset [ cl ] ;
else
return - EINVAL ;
return 1 ;
}
static int char2uni ( const unsigned char * rawstring , int boundlen , wchar_t * uni )
{
* uni = charset2uni [ * rawstring ] ;
if ( * uni = = 0x0000 )
return - EINVAL ;
return 1 ;
}
static struct nls_table default_table = {
. charset = " default " ,
. uni2char = uni2char ,
. char2uni = char2uni ,
. charset2lower = charset2lower ,
. charset2upper = charset2upper ,
} ;
/* Returns a simple default translation table */
struct nls_table * load_nls_default ( void )
{
struct nls_table * default_nls ;
default_nls = load_nls ( CONFIG_NLS_DEFAULT ) ;
if ( default_nls ! = NULL )
return default_nls ;
else
return & default_table ;
}
EXPORT_SYMBOL ( unregister_nls ) ;
EXPORT_SYMBOL ( unload_nls ) ;
EXPORT_SYMBOL ( load_nls ) ;
EXPORT_SYMBOL ( load_nls_default ) ;
MODULE_LICENSE ( " Dual BSD/GPL " ) ;