discomfitor pushed a commit to branch master.
commit 37aa26b977563fad0b36c163b01f210b92f9f8ae
Author: Mike Blumenkrantz <[email protected]>
Date: Wed May 29 12:42:37 2013 +0100
add eina_str_convert_len() for converting from encodings which contain '\0'
characters
eina_str_convert() is GUARANTEED to break when doing any such encoding (eg.
UTF16->UTF8). I don't know who added the original function, but this is very
bad, and we should almost certainly deprecate eina_str_convert() so people are
not surprised when they are unable to convert strings as expected.
---
ChangeLog | 4 +++
NEWS | 1 +
src/lib/eina/eina_str.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
src/lib/eina/eina_str.h | 22 +++++++++++++++
4 files changed, 98 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 3d1bf4e..43896da 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-05-29 Mike Blumenkrantz
+
+ * Added eina_str_convert_len() to work around broken eina_str_convert()
+
2013-05-28 ChunEon Park (Hermet)
* Fix textblock to render pre again if it needs to relayouting.
diff --git a/NEWS b/NEWS
index dcf157a..1e75370 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ Additions:
- Add eina_log_timing()
- Add eina_inlist_first
- Add eina_inlist_last
+ - Added eina_str_convert_len() to work around broken eina_str_convert()
* Add Cserve2 scalecache support
* ecore_x:
- Add window profile support.
diff --git a/src/lib/eina/eina_str.c b/src/lib/eina/eina_str.c
index b6b0d9e..1b4d0dc 100644
--- a/src/lib/eina/eina_str.c
+++ b/src/lib/eina/eina_str.c
@@ -525,6 +525,77 @@ eina_str_convert(const char *enc_from EINA_UNUSED,
}
#endif
+#ifdef HAVE_ICONV
+EAPI char *
+eina_str_convert_len(const char *enc_from, const char *enc_to, const char
*text, size_t len, size_t *retlen)
+{
+ iconv_t ic;
+ char *new_txt, *inp, *outp;
+ size_t inb, outb, outlen, tob, outalloc;
+
+ if (retlen) *retlen = 0;
+ if (!text) return NULL;
+
+ ic = iconv_open(enc_to, enc_from);
+ if (ic == (iconv_t)(-1))
+ return NULL;
+
+ new_txt = malloc(64);
+ inb = len;
+ outb = 64;
+ inp = (char *)text;
+ outp = new_txt;
+ outalloc = 64;
+ outlen = 0;
+
+ for (;; )
+ {
+ size_t count;
+
+ tob = outb;
+ count = iconv(ic, &inp, &inb, &outp, &outb);
+ outlen += tob - outb;
+ if (count == (size_t)(-1))
+ {
+ if (errno == E2BIG)
+ {
+ new_txt = realloc(new_txt, outalloc + 64);
+ outp = new_txt + outlen;
+ outalloc += 64;
+ outb += 64;
+ }
+ else
+ {
+ if (new_txt)
+ free(new_txt);
+
+ new_txt = NULL;
+ break;
+ }
+ }
+
+ if (inb == 0)
+ {
+ if (outalloc == outlen)
+ new_txt = realloc(new_txt, outalloc + 1);
+
+ new_txt[outlen] = 0;
+ break;
+ }
+ }
+ iconv_close(ic);
+ if (retlen) *retlen = outlen;
+ return new_txt;
+}
+#else
+EAPI char *
+eina_str_convert_len(const char *enc_from EINA_UNUSED, const char *enc_to
EINA_UNUSED, const char *text EINA_UNUSED, size_t len EINA_UNUSED, size_t
*retlen)
+{
+ if (retlen) *retlen = 0;
+ return NULL;
+}
+#endif
+
EAPI char *
eina_str_escape(const char *str)
{
diff --git a/src/lib/eina/eina_str.h b/src/lib/eina/eina_str.h
index f199a9a..e083ec0 100644
--- a/src/lib/eina/eina_str.h
+++ b/src/lib/eina/eina_str.h
@@ -260,9 +260,31 @@ EAPI size_t eina_str_join_len(char *dst, size_t
size, char sep, const c
* failure, @c NULL is returned. Iconv is used to convert @p text. If
* Iconv is not available, @c NULL is returned. When not used anymore,
* the returned value must be freed.
+ *
+ * @warning This function is guaranteed to break when '\0' characters are in
@p text.
+ * DO NOT USE THIS FUNCTION IF YOUR TEXT CONTAINS NON-TERMINATING '\0'
CHARACTERS.
*/
EAPI char *eina_str_convert(const char *enc_from, const char
*enc_to, const char *text) EINA_WARN_UNUSED_RESULT EINA_MALLOC
EINA_ARG_NONNULL(1, 2, 3);
+/**
+ * @brief Use Iconv to convert a text string from one encoding to another.
+ *
+ * @param enc_from Encoding to convert from.
+ * @param enc_to Encoding to convert to.
+ * @param text The text to convert.
+ * @param text The length of the text to convert.
+ * @return The converted text.
+ *
+ * This function converts @p text, encoded in @p enc_from. On success,
+ * the converted text is returned and is encoded in @p enc_to. On
+ * failure, @c NULL is returned. Iconv is used to convert @p text. If
+ * Iconv is not available, @c NULL is returned. When not used anymore,
+ * the returned value must be freed.
+ *
+ * @since 1.8
+ */
+EAPI char *eina_str_convert_len(const char *enc_from, const char
*enc_to, const char *text, size_t len, size_t *retlen) EINA_WARN_UNUSED_RESULT
EINA_MALLOC EINA_ARG_NONNULL(1, 2, 3);
+
/**
* @brief Escape slashes, spaces and apostrophes in strings.
--
------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1