NLS: update handling of Unicode
This patch (as1239) updates the kernel's treatment of Unicode. The character-set conversion routines are well behind the current state of the Unicode specification: They don't recognize the existence of code points beyond plane 0 or of surrogate pairs in the UTF-16 encoding. The old wchar_t 16-bit type is retained because it's still used in lots of places. This shouldn't cause any new problems; if a conversion now results in an invalid 16-bit code then before it must have yielded an undefined code. Difficult-to-read names like "utf_mbstowcs" are replaced with more transparent names like "utf8s_to_utf16s" and the ordering of the parameters is rationalized (buffer lengths come immediate after the pointers they refer to, and the inputs precede the outputs). Fortunately the low-level conversion routines are used in only a few places; the interfaces to the higher-level uni2char and char2uni methods have been left unchanged. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a853a3d4eb
commit
74675a5850
@@ -3,8 +3,23 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
/* unicode character */
|
||||
typedef __u16 wchar_t;
|
||||
/* Unicode has changed over the years. Unicode code points no longer
|
||||
* fit into 16 bits; as of Unicode 5 valid code points range from 0
|
||||
* to 0x10ffff (17 planes, where each plane holds 65536 code points).
|
||||
*
|
||||
* The original decision to represent Unicode characters as 16-bit
|
||||
* wchar_t values is now outdated. But plane 0 still includes the
|
||||
* most commonly used characters, so we will retain it. The newer
|
||||
* 32-bit unicode_t type can be used when it is necessary to
|
||||
* represent the full Unicode character set.
|
||||
*/
|
||||
|
||||
/* Plane-0 Unicode character */
|
||||
typedef u16 wchar_t;
|
||||
#define MAX_WCHAR_T 0xffff
|
||||
|
||||
/* Arbitrary Unicode character */
|
||||
typedef u32 unicode_t;
|
||||
|
||||
struct nls_table {
|
||||
const char *charset;
|
||||
@@ -21,6 +36,13 @@ struct nls_table {
|
||||
/* this value hold the maximum octet of charset */
|
||||
#define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */
|
||||
|
||||
/* Byte order for UTF-16 strings */
|
||||
enum utf16_endian {
|
||||
UTF16_HOST_ENDIAN,
|
||||
UTF16_LITTLE_ENDIAN,
|
||||
UTF16_BIG_ENDIAN
|
||||
};
|
||||
|
||||
/* nls.c */
|
||||
extern int register_nls(struct nls_table *);
|
||||
extern int unregister_nls(struct nls_table *);
|
||||
@@ -28,10 +50,11 @@ extern struct nls_table *load_nls(char *);
|
||||
extern void unload_nls(struct nls_table *);
|
||||
extern struct nls_table *load_nls_default(void);
|
||||
|
||||
extern int utf8_mbtowc(wchar_t *, const __u8 *, int);
|
||||
extern int utf8_mbstowcs(wchar_t *, const __u8 *, int);
|
||||
extern int utf8_wctomb(__u8 *, wchar_t, int);
|
||||
extern int utf8_wcstombs(__u8 *, const wchar_t *, int);
|
||||
extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu);
|
||||
extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen);
|
||||
extern int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs);
|
||||
extern int utf16s_to_utf8s(const wchar_t *pwcs, int len,
|
||||
enum utf16_endian endian, u8 *s, int maxlen);
|
||||
|
||||
static inline unsigned char nls_tolower(struct nls_table *t, unsigned char c)
|
||||
{
|
||||
|
Reference in New Issue
Block a user