[linux-cifs-client] [PATCH 1/5] cifs: Introduce helpers for unicode
buffer handing
Suresh Jayaraman
sjayaraman at suse.de
Fri Apr 17 15:09:28 GMT 2009
Introduce helpers to compute length of NLS string in bytes and to
convert ucs string to nls format.
Signed-off-by: Suresh Jayaraman <sjayaraman at suse.de>
---
fs/cifs/cifs_unicode.h | 27 +++++++++++++++++++++++++++
fs/cifs/cifsproto.h | 2 ++
fs/cifs/cifssmb.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 0 deletions(-)
Index: cifs-2.6.git/fs/cifs/cifs_unicode.h
===================================================================
--- cifs-2.6.git.orig/fs/cifs/cifs_unicode.h
+++ cifs-2.6.git/fs/cifs/cifs_unicode.h
@@ -159,6 +159,33 @@ UniStrnlen(const wchar_t *ucs1, int maxl
}
/*
+ * UniStrnlenBytes: Return the length of a NLS string in bytes. Also, populates
+ * 'nchars' with the length of string in 16 bit Unicode chars.
+ */
+static inline size_t
+UniStrnlenBytes(const wchar_t *str, int maxlen, int *nchars,
+ const struct nls_table *codepage)
+{
+ int nc;
+ size_t nbytes = 0;
+ char buf[NLS_MAX_CHARSET_SIZE]; /* enough for one char at a time */
+
+ *nchars = 0;
+ while (*str++ && maxlen) {
+ nc = codepage->uni2char(*str, buf, NLS_MAX_CHARSET_SIZE);
+ if (nc > 0)
+ nbytes += nc;
+ else
+ nbytes += 1; /* for '?' */
+ (*nchars)++;
+ if (*nchars >= maxlen)
+ break;
+ }
+
+ return nbytes;
+}
+
+/*
* UniStrncat: Concatenate length limited string
*/
static inline wchar_t *
Index: cifs-2.6.git/fs/cifs/cifsproto.h
===================================================================
--- cifs-2.6.git.orig/fs/cifs/cifsproto.h
+++ cifs-2.6.git/fs/cifs/cifsproto.h
@@ -383,4 +383,6 @@ extern int CIFSSMBSetPosixACL(const int
const struct nls_table *nls_codepage, int remap_special_chars);
extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
+extern int cifs_ucs_to_nls(char **dst, const char *src, const int maxlen,
+ int *plen, const struct nls_table *nls_codepage);
#endif /* _CIFSPROTO_H */
Index: cifs-2.6.git/fs/cifs/cifssmb.c
===================================================================
--- cifs-2.6.git.orig/fs/cifs/cifssmb.c
+++ cifs-2.6.git/fs/cifs/cifssmb.c
@@ -81,6 +81,37 @@ static struct {
#endif /* CONFIG_CIFS_WEAK_PW_HASH */
#endif /* CIFS_POSIX */
+
+/*
+ * Calculates, allocates memory and converts to a NLS string.
+ * Note: caller is responsible for freeing dst if function returned 0.
+ * returns:
+ * on success - 0
+ * on failure - errno
+ */
+int
+cifs_ucs_to_nls(char **dst, const char *src, const int maxlen, int *plen,
+ const struct nls_table *nls_codepage)
+{
+ size_t nbytes;
+
+ nbytes = UniStrnlenBytes((wchar_t *)src, maxlen, plen, nls_codepage);
+ cFYI(1, ("UniStrnlenBytes returned %ld bytes", nbytes));
+ *dst = kzalloc(nbytes + 2, GFP_KERNEL);
+ if (!*dst)
+ goto err_exit;
+
+ cifs_strfromUCS_le(*dst, (__le16 *)src, *plen, nls_codepage);
+
+ /* kzalloc() ensures NULL termination */
+
+ return 0;
+
+err_exit:
+ cERROR(1, ("Failed to allocate buffer for string\n"));
+ return -ENOMEM;
+}
+
/* Allocates buffer into dst and copies smb string from src to it.
* caller is responsible for freeing dst if function returned 0.
* returns:
More information about the linux-cifs-client
mailing list