Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision b48d04693b3416fe0c2e8bfff373f7c147ef35aa)
+++ uspace/lib/c/generic/str.c	(revision ebddd71b73a35eeabdd3240f2862b3205be2d20b)
@@ -3,4 +3,5 @@
  * Copyright (c) 2008 Jiri Svoboda
  * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -367,4 +368,16 @@
 }
 
+/** Check whether wide string is plain ASCII.
+ *
+ * @return True if wide string is plain ASCII.
+ *
+ */
+bool wstr_is_ascii(const wchar_t *wstr)
+{
+	while (*wstr && ascii_check(*wstr))
+		wstr++;
+	return *wstr == 0;
+}
+
 /** Check whether character is valid
  *
@@ -619,7 +632,10 @@
  * @param size	Size of the destination buffer.
  * @param src	Source wide string.
- */
-void wstr_to_str(char *dest, size_t size, const wchar_t *src)
-{
+ *
+ * @return EOK, if success, negative otherwise.
+ */
+int wstr_to_str(char *dest, size_t size, const wchar_t *src)
+{
+	int rc;
 	wchar_t ch;
 	size_t src_idx;
@@ -633,10 +649,90 @@
 
 	while ((ch = src[src_idx++]) != 0) {
-		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
+		rc = chr_encode(ch, dest, &dest_off, size - 1);
+		if (rc != EOK)
 			break;
 	}
 
 	dest[dest_off] = '\0';
-}
+	return rc;
+}
+
+/** Convert UTF16 string to string.
+ *
+ * Convert utf16 string @a src to string. The output is written to the buffer
+ * specified by @a dest and @a size. @a size must be non-zero and the string
+ * written will always be well-formed. Surrogate pairs also supported.
+ *
+ * @param dest	Destination buffer.
+ * @param size	Size of the destination buffer.
+ * @param src	Source utf16 string.
+ *
+ * @return EOK, if success, negative otherwise.
+ */
+int utf16_to_str(char *dest, size_t size, const uint16_t *src)
+{
+	size_t idx=0, dest_off=0;
+	wchar_t ch;
+	int rc = EOK;
+
+	/* There must be space for a null terminator in the buffer. */
+	assert(size > 0);
+
+	while (src[idx]) {
+		if ((src[idx] & 0xfc00) == 0xd800) {
+			if (src[idx+1] && (src[idx+1] & 0xfc00) == 0xdc00) {
+				ch = 0x10000;
+				ch += (src[idx] & 0x03FF) << 10;
+				ch += (src[idx+1] & 0x03FF);
+				idx += 2;
+			}
+			else
+				break;
+		} else {
+			ch = src[idx];
+			idx++;
+		}
+		rc = chr_encode(ch, dest, &dest_off, size-1);
+		if (rc != EOK)
+			break;
+	}
+	dest[dest_off] = '\0';
+	return rc;
+}
+
+int str_to_utf16(uint16_t *dest, size_t size, const char *src)
+{
+	int rc=EOK;
+	size_t offset=0;
+	size_t idx=0;
+	wchar_t c;
+
+	assert(size > 0);
+	
+	while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) {
+		if (c > 0x10000) {
+			if (idx+2 >= size-1) {
+				rc=EOVERFLOW;
+				break;
+			}
+			c = (c - 0x10000);
+			dest[idx] = 0xD800 | (c >> 10);
+			dest[idx+1] = 0xDC00 | (c & 0x3FF);
+			idx++;
+		} else {
+			 dest[idx] = c;
+		}
+
+		idx++;
+		if (idx >= size-1) {
+			rc=EOVERFLOW;
+			break;
+		}
+	}
+
+	dest[idx] = '\0';
+	return rc;
+}
+
 
 /** Convert wide string to new string.
@@ -698,7 +794,10 @@
  * @param dlen	Length of destination buffer (number of wchars).
  * @param src	Source string.
- */
-void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
-{
+ *
+ * @return EOK, if success, negative otherwise.
+ */
+int str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
+{
+	int rc=EOK;
 	size_t offset;
 	size_t di;
@@ -711,6 +810,8 @@
 
 	do {
-		if (di >= dlen - 1)
+		if (di >= dlen - 1) {
+			rc = EOVERFLOW;
 			break;
+		}
 
 		c = str_decode(src, &offset, STR_NO_LIMIT);
@@ -719,4 +820,5 @@
 
 	dest[dlen - 1] = '\0';
+	return rc;
 }
 
@@ -783,4 +885,39 @@
 	
 	return (char *) res;
+}
+
+/** Find first occurence of character in wide string.
+ *
+ * @param wstr String to search.
+ * @param ch  Character to look for.
+ *
+ * @return Pointer to character in @a wstr or NULL if not found.
+ */
+wchar_t *wstr_chr(const wchar_t *wstr, wchar_t ch)
+{
+	while (*wstr && *wstr != ch)
+		wstr++;
+	if (*wstr)
+		return (wchar_t *) wstr;
+	else
+		return NULL;
+}
+
+/** Find last occurence of character in wide string.
+ *
+ * @param wstr String to search.
+ * @param ch  Character to look for.
+ *
+ * @return Pointer to character in @a wstr or NULL if not found.
+ */
+wchar_t *wstr_rchr(const wchar_t *wstr, wchar_t ch)
+{
+	const wchar_t *res = NULL;
+	while (*wstr) {
+		if (*wstr == ch)
+			res = wstr;
+		wstr++;
+	}
+	return (wchar_t *) res;
 }
 
@@ -1037,4 +1174,34 @@
 }
 
+void str_reverse(char* begin, char* end) 
+{
+    char aux;
+    while(end>begin)
+        aux=*end, *end--=*begin, *begin++=aux;
+}
+
+int size_t_str(size_t value, int base, char* str, size_t size) 
+{
+    static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+    char* wstr=str;
+	
+	if (size == 0) 
+		return EINVAL;
+    if (base<2 || base>35) {
+        *str='\0';
+        return EINVAL;
+    }
+
+    do {
+        *wstr++ = num[value % base];
+		if (--size == 0)
+			return EOVERFLOW;
+    } while(value /= base);
+    *wstr='\0';
+
+    // Reverse string
+    str_reverse(str,wstr-1);
+	return EOK;
+}
 
 /** Convert initial part of string to unsigned long according to given base.
