[<prev] [next>] [day] [month] [year] [list]
Message-ID: <4FC8167C.5040508@gmail.com>
Date: Fri, 01 Jun 2012 03:10:20 +0200
From: Vladimir 'φ-coder/phcoder' Serbinenko
<phcoder@...il.com>
To: Jan Kara <jack@...e.cz>, linux-kernel@...r.kernel.org,
linux-fsdevel@...r.kernel.org
Subject: [PATCH 2/4] Add unaligned UTF-16 access
Used for reading and writing UTF-16 on UDF and Joliet.
Signed-off-by: Vladimir Serbinenko <phcoder@...il.com>
---
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
Download attachment "signature.asc" of type "application/pgp-signature" (295 bytes)
Powered by blists - more mailing lists