forked from enlightenment/efl
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.
This commit is contained in:
parent
6a4cdea904
commit
37aa26b977
|
@ -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.
|
||||
|
|
1
NEWS
1
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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue