[linux-cifs-client] [PATCH 2/7] [CIFS] add cifs_nls_convert
function to convert from one nls to another
Jeff Layton
jlayton at redhat.com
Fri Jul 25 15:23:15 GMT 2008
Add a cifs_nls_convert function, that does a conversion from one codepage
to another. When one or both codepages is NULL, it just does a memcpy
from one to the other.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
fs/cifs/cifs_unicode.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
fs/cifs/cifs_unicode.h | 3 +++
2 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 7d75272..f827422 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -88,3 +88,60 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
return i;
}
+/*
+ * cifs_nls_convert - convert string from one character set to another
+ * @from: original string
+ * @to: destination for converted string
+ * @from_nls: nls that the "from" string is in
+ * @to_nls: nls to which we need to convert the "to" string
+ * @len: from string length
+ * @from_le: is the original string in little endian format?
+ *
+ * convert a string from one nls_codepage to another. If either codepage is
+ * NULL, then we assume that both ends are using the same codepage and just
+ * do a memcpy.
+ */
+int
+cifs_nls_convert(const unsigned char *from, unsigned char *to,
+ const struct nls_table *from_nls,
+ const struct nls_table *to_nls, unsigned int inlen)
+{
+ int charlen, outlen = 0;
+ wchar_t temp;
+
+ /* if either codepage is NULL, then just memcpy */
+ if (!from_nls || !to_nls) {
+ memcpy(to, from, inlen);
+ /* NULL terminate */
+ to[inlen] = 0;
+ return inlen;
+ }
+
+ while (inlen && *from) {
+ /* convert character to unicode */
+ charlen = from_nls->char2uni(from, inlen, &temp);
+ if (charlen < 1) {
+ cFYI(1, ("strtoUCS: char2uni of %x returned %d",
+ *from, charlen));
+ /* A question mark */
+ temp = 0x003f;
+ charlen = 1;
+ }
+
+ /* adjust input lengths */
+ from += charlen;
+ inlen -= charlen;
+
+ /* convert temp char from unicode to to_nls */
+ charlen = to_nls->uni2char(temp, &to[outlen],
+ NLS_MAX_CHARSET_SIZE);
+ if (charlen > 0)
+ outlen += charlen;
+ else
+ to[outlen++] = '?';
+ }
+
+ /* NULL terminate */
+ to[outlen] = 0;
+ return outlen;
+}
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 14eb9a2..9577972 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -61,6 +61,9 @@ extern struct UniCaseRange UniLowerRange[];
#ifdef __KERNEL__
int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
+int cifs_nls_convert(const unsigned char *from, unsigned char *to,
+ const struct nls_table *from_nls,
+ const struct nls_table *to_nls, unsigned int inlen);
#endif
/*
More information about the linux-cifs-client
mailing list