[PATCH 2/4] Add unaligned UTF-16 access

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Used for reading and writing UTF-16 on UDF and Joliet.

Signed-off-by: Vladimir Serbinenko <phcoder@xxxxxxxxx>
---
 fs/nls/nls_base.c   |   31 +++++++++++++++++++++----------
 include/linux/nls.h |    4 +++-
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 0c1ad5b..e941a80 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -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 */
diff --git a/include/linux/nls.h b/include/linux/nls.h
index 7de1765..bb35d2b 100644
--- a/include/linux/nls.h
+++ b/include/linux/nls.h
@@ -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 */
-- 
1.7.10

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux