summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsmbfs/smb/utf_str.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libsmbfs/smb/utf_str.c')
-rw-r--r--usr/src/lib/libsmbfs/smb/utf_str.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/usr/src/lib/libsmbfs/smb/utf_str.c b/usr/src/lib/libsmbfs/smb/utf_str.c
index e80b1180f2..f53189e64c 100644
--- a/usr/src/lib/libsmbfs/smb/utf_str.c
+++ b/usr/src/lib/libsmbfs/smb/utf_str.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -205,3 +205,67 @@ convert_utf8_to_ucs2xx(iconv_t cd, const char *utf8_string)
return (obuf);
}
+
+
+/*
+ * A simple wrapper around u8_textprep_str() that returns the Unicode
+ * upper-case version of some string. Returns memory from malloc.
+ * Borrowed from idmapd.
+ */
+static char *
+utf8_str_to_upper_or_lower(const char *s, int upper_lower)
+{
+ char *res = NULL;
+ char *outs;
+ size_t inlen, outlen, inbleft, outbleft;
+ int rc, err;
+
+ /*
+ * u8_textprep_str() does not allocate memory. The input and
+ * output buffers may differ in size (though that would be more
+ * likely when normalization is done). We have to loop over it...
+ *
+ * To improve the chances that we can avoid looping we add 10
+ * bytes of output buffer room the first go around.
+ */
+ inlen = inbleft = strlen(s);
+ outlen = outbleft = inlen + 10;
+ if ((res = malloc(outlen)) == NULL)
+ return (NULL);
+ outs = res;
+
+ while ((rc = u8_textprep_str((char *)s, &inbleft, outs,
+ &outbleft, upper_lower, U8_UNICODE_LATEST, &err)) < 0 &&
+ err == E2BIG) {
+ if ((res = realloc(res, outlen + inbleft)) == NULL)
+ return (NULL);
+ /* adjust input/output buffer pointers */
+ s += (inlen - inbleft);
+ outs = res + outlen - outbleft;
+ /* adjust outbleft and outlen */
+ outlen += inbleft;
+ outbleft += inbleft;
+ }
+
+ if (rc < 0) {
+ free(res);
+ res = NULL;
+ return (NULL);
+ }
+
+ res[outlen - outbleft] = '\0';
+
+ return (res);
+}
+
+char *
+utf8_str_toupper(const char *s)
+{
+ return (utf8_str_to_upper_or_lower(s, U8_TEXTPREP_TOUPPER));
+}
+
+char *
+utf8_str_tolower(const char *s)
+{
+ return (utf8_str_to_upper_or_lower(s, U8_TEXTPREP_TOLOWER));
+}