cifs: add new function to get unicode string length in bytes
authorJeff Layton <jlayton@redhat.com>
Thu, 30 Apr 2009 10:46:32 +0000 (06:46 -0400)
committerSteve French <sfrench@us.ibm.com>
Thu, 30 Apr 2009 15:45:00 +0000 (15:45 +0000)
Working in units of words means we do a lot of unnecessary conversion back
and forth. Standardize on bytes instead since that's more useful for
allocating buffers and such. Also, remove hostlen_fromUCS since the new
function has a similar purpose.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Suresh Jayaraman <sjayaraman@suse.de>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.h
fs/cifs/cifssmb.c

index 8389f35..6145125 100644 (file)
 #include "cifsglob.h"
 #include "cifs_debug.h"
 
+/*
+ * cifs_ucs2_bytes - how long will a string be after conversion?
+ * @ucs - pointer to input string
+ * @maxbytes - don't go past this many bytes of input string
+ * @codepage - destination codepage
+ *
+ * Walk a ucs2le string and return the number of bytes that the string will
+ * be after being converted to the given charset, not including any null
+ * termination required. Don't walk past maxbytes in the source buffer.
+ */
+int
+cifs_ucs2_bytes(const __le16 *from, int maxbytes,
+               const struct nls_table *codepage)
+{
+       int i;
+       int charlen, outlen = 0;
+       int maxwords = maxbytes / 2;
+       char tmp[NLS_MAX_CHARSET_SIZE];
+
+       for (i = 0; from[i] && i < maxwords; i++) {
+               charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp,
+                                            NLS_MAX_CHARSET_SIZE);
+               if (charlen > 0)
+                       outlen += charlen;
+               else
+                       outlen++;
+       }
+
+       return outlen;
+}
+
 /*
  * cifs_mapchar - convert a little-endian char to proper char in codepage
  * @target - where converted character should be copied
index 6aa6533..1857f5f 100644 (file)
@@ -74,6 +74,8 @@ extern struct UniCaseRange UniLowerRange[];
 #ifdef __KERNEL__
 int cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
                   const struct nls_table *codepage, bool mapchar);
+int cifs_ucs2_bytes(const __le16 *from, int maxbytes,
+                   const struct nls_table *codepage);
 int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
 int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
 #endif
index a02c43b..cadacae 100644 (file)
@@ -3928,27 +3928,6 @@ GetInodeNumOut:
        return rc;
 }
 
-/* computes length of UCS string converted to host codepage
- * @src:       UCS string
- * @maxlen:    length of the input string in UCS characters
- *             (not in bytes)
- *
- * return:     size of input string in host codepage
- */
-static int hostlen_fromUCS(const __le16 *src, const int maxlen,
-               const struct nls_table *nls_codepage) {
-       int i;
-       int hostlen = 0;
-       char to[4];
-       int charlen;
-       for (i = 0; (i < maxlen) && src[i]; ++i) {
-               charlen = nls_codepage->uni2char(le16_to_cpu(src[i]),
-                               to, NLS_MAX_CHARSET_SIZE);
-               hostlen += charlen > 0 ? charlen : 1;
-       }
-       return hostlen;
-}
-
 /* parses DFS refferal V3 structure
  * caller is responsible for freeing target_nodes
  * returns:
@@ -4016,8 +3995,8 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
                                                GFP_KERNEL);
                        cifsConvertToUCS((__le16 *) tmp, searchName,
                                        PATH_MAX, nls_codepage, remap);
-                       node->path_consumed = hostlen_fromUCS(tmp,
-                                       le16_to_cpu(pSMBr->PathConsumed)/2,
+                       node->path_consumed = cifs_ucs2_bytes(tmp,
+                                       le16_to_cpu(pSMBr->PathConsumed),
                                        nls_codepage);
                        kfree(tmp);
                } else