Add unaligned UTF-16 access
PATCH 2/4 Add unaligned UTF-16 access
Used for reading and writing UTF-16 on UDF and Joliet.
Signed-off-by Vladimir Serbinenko <[email protected]>
--- fs/nls/nls_base.c | 31 +++++++++++++++++++++---------- include/linux/nls.h | 4 +++- 2 files changed, 24 insertions(+), 11 deletions(-)
fs/nls/nls_base.c +21 -10
@@ -16,6 +16,7 @@#include <linux/kmod.h> #include <linux/spinlock.h> #include <asm/byteorder.h> +#include <asm/unaligned.h> static struct nls_table default_table;static struct nls_table *tables = &default_table;
@@ -114,7 +115,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout) }EXPORT_SYMBOL (utf32_to_utf8); -static inline void put_utf16 (wchar_t *s,unsigned c,enum utf16_endian endian) +static inline void put_utf16 (u16 *s,unsigned c,enum utf16_endian endian) {switch (endian) {default :
@@ -126,11 +127,17 @@ static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian)case UTF16_BIG_ENDIAN : *s =__cpu_to_be16 (c);break ; +case UTF16_LITTLE_ENDIAN_UNALIGNED : +put_unaligned_le16 (c, s); +break ; +case UTF16_BIG_ENDIAN_UNALIGNED : +put_unaligned_be16 (c, s); +break ; } }int utf8s_to_utf16s (const u8 *s,int inlen,enum utf16_endian endian, -wchar_t *pwcs,int maxout) +wchar_t *pwcs,int maxout) {u16 *op;int size;
@@ -197,15 +204,19 @@ int unicode_to_utf16s(unicode_t u, enum utf16_endian endian, }EXPORT_SYMBOL (unicode_to_utf16s); -static inline unsigned long get_utf16 (unsigned c,enum utf16_endian endian) +static inline unsigned long get_utf16 (const u16 *c,enum utf16_endian endian) {switch (endian) {default : -return c; +return *c;case UTF16_LITTLE_ENDIAN : -return __le16_to_cpu (c); +return __le16_to_cpu (*c);case UTF16_BIG_ENDIAN : -return __be16_to_cpu (c); +return __be16_to_cpu (*c); +case UTF16_LITTLE_ENDIAN_UNALIGNED : +return get_unaligned_le16 (c); +case UTF16_BIG_ENDIAN_UNALIGNED : +return get_unaligned_be16 (c); } }
@@ -218,7 +229,7 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian, op = s;while (inlen >0 && maxout >0 ) { - u =get_utf16 (*pwcs, endian); + u =get_utf16 (pwcs, endian);if (!u)break ; pwcs++;
@@ -231,7 +242,7 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian, }if (inlen <=0 )break ; - v =get_utf16 (*pwcs, endian); + v =get_utf16 (pwcs, endian);if ((v &SURROGATE_MASK ) !=SURROGATE_PAIR || !(v &SURROGATE_LOW )) {/* Ignore character and move on */
@@ -265,7 +276,7 @@ int utf16s_to_unicode(const wchar_t *pwcs, int inlen, enum utf16_endian endian,const wchar_t *pwcs0 = pwcs;while (inlen >0 ) { - u =get_utf16 (*pwcs, endian); + u =get_utf16 (pwcs, endian);if (!u)break ; pwcs++;
@@ -277,7 +288,7 @@ int utf16s_to_unicode(const wchar_t *pwcs, int inlen, enum utf16_endian endian, }if (inlen <=0 )break ; - v =get_utf16 (*pwcs, endian); + v =get_utf16 (pwcs, endian);if ((v &SURROGATE_MASK ) !=SURROGATE_PAIR || !(v &SURROGATE_LOW )) {/* Ignore character and move on */
include/linux/nls.h +3 -1
@@ -40,7 +40,9 @@ struct nls_table {enum utf16_endian {UTF16_HOST_ENDIAN ,UTF16_LITTLE_ENDIAN , -UTF16_BIG_ENDIAN +UTF16_BIG_ENDIAN , +UTF16_LITTLE_ENDIAN_UNALIGNED , +UTF16_BIG_ENDIAN_UNALIGNED };/* nls_base.c */
Signature · 5 lines
1.7.10 -- Regards Vladimir 'φ-coder/phcoder' Serbinenko