diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-10-11 03:26:17 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:59:46 -0500 |
commit | 4aebdb779a406bba6aa8d5665c608083e19fcf52 (patch) | |
tree | 66c8595d7dd9a2b43675fd6a461075456f7ab679 | |
parent | 173ec86fc05666690909a2ffe4721217fb3ceb51 (diff) | |
download | samba-4aebdb779a406bba6aa8d5665c608083e19fcf52.tar.gz samba-4aebdb779a406bba6aa8d5665c608083e19fcf52.tar.bz2 samba-4aebdb779a406bba6aa8d5665c608083e19fcf52.zip |
r2903: a considerably more efficient (both in terms of CPU and memory)
convert_string_talloc() implementation.
the previous version used a minimum of 512 bytes, which is way above the average
of what is needed.
(This used to be commit abcd841a8530ba3273d56c9001ea277611507be3)
-rw-r--r-- | source4/lib/charcnv.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/source4/lib/charcnv.c b/source4/lib/charcnv.c index 392ad3cc72..e5331b973e 100644 --- a/source4/lib/charcnv.c +++ b/source4/lib/charcnv.c @@ -168,7 +168,7 @@ ssize_t convert_string(charset_t from, charset_t to, **/ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, - void const *src, size_t srclen, void **dest) + void const *src, size_t srclen, void **dest) { size_t i_len, o_len, destlen; size_t retval; @@ -189,20 +189,25 @@ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, return -1; } - destlen = MAX(srclen, 512); + /* it is _very_ rare that a conversion increases the size by + more than 3x */ + destlen = srclen; outbuf = NULL; convert: - destlen = destlen * 2; + destlen = 2 + (destlen*3); ob = (char *)talloc_realloc(ctx, outbuf, destlen); if (!ob) { DEBUG(0, ("convert_string_talloc: realloc failed!\n")); talloc_free(outbuf); return (size_t)-1; - } - else + } else { outbuf = ob; + } + + /* we give iconv 2 less bytes to allow us to terminate at the + end */ i_len = srclen; - o_len = destlen; + o_len = destlen-2; retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); @@ -220,20 +225,15 @@ convert: } DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf)); talloc_free(ob); - /* smb_panic(reason); */ return (size_t)-1; } - destlen = destlen - o_len; - /* +2 for mandetory null termination, UTF8 or UTF16 */ - *dest = (char *)talloc_realloc(ctx, ob, destlen+2); - if (!*dest) { - DEBUG(0, ("convert_string_talloc: out of memory!\n")); - talloc_free(ob); - return (size_t)-1; - } - ((char *)*dest)[destlen] = '\0'; - ((char *)*dest)[destlen+1] = '\0'; + destlen = (destlen-2) - o_len; + + /* guarantee null termination in all charsets */ + SSVAL(ob, destlen, 0); + + *dest = ob; return destlen; } |