diff options
author | Jeremy Allison <jra@samba.org> | 2011-03-30 18:13:05 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2011-03-31 04:09:09 +0200 |
commit | 21193c8eeba6d03f680ad34acbbb4cff14d87809 (patch) | |
tree | e4c654872f2e814f2009f73ea2760043accd1708 /lib/util | |
parent | f9a2f4f47c71e5054c05703e72c24f2f5a87d993 (diff) | |
download | samba-21193c8eeba6d03f680ad34acbbb4cff14d87809.tar.gz samba-21193c8eeba6d03f680ad34acbbb4cff14d87809.tar.bz2 samba-21193c8eeba6d03f680ad34acbbb4cff14d87809.zip |
Don't burn 2k of stack on every iconv, use the heap when it's a slow call.
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Thu Mar 31 04:09:09 CEST 2011 on sn-devel-104
Diffstat (limited to 'lib/util')
-rw-r--r-- | lib/util/charset/iconv.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/lib/util/charset/iconv.c b/lib/util/charset/iconv.c index e3cdbdfc8e..24434ec809 100644 --- a/lib/util/charset/iconv.c +++ b/lib/util/charset/iconv.c @@ -164,32 +164,41 @@ _PUBLIC_ size_t smb_iconv(smb_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { - char cvtbuf[2048]; - size_t bufsize; - /* in many cases we can go direct */ if (cd->direct) { return cd->direct(cd->cd_direct, inbuf, inbytesleft, outbuf, outbytesleft); } - /* otherwise we have to do it chunks at a time */ - while (*inbytesleft > 0) { - char *bufp1 = cvtbuf; - const char *bufp2 = cvtbuf; + { +#ifndef SMB_ICONV_BUFSIZE +#define SMB_ICONV_BUFSIZE 2048 +#endif + size_t bufsize; + char *cvtbuf = talloc_array(cd, char, SMB_ICONV_BUFSIZE); - bufsize = sizeof(cvtbuf); - - if (cd->pull(cd->cd_pull, - inbuf, inbytesleft, &bufp1, &bufsize) == -1 - && errno != E2BIG) return -1; + if (!cvtbuf) { + return (size_t)-1; + } - bufsize = sizeof(cvtbuf) - bufsize; + while (*inbytesleft > 0) { + char *bufp1 = cvtbuf; + const char *bufp2 = cvtbuf; - if (cd->push(cd->cd_push, - &bufp2, &bufsize, - outbuf, outbytesleft) == -1) return -1; + bufsize = SMB_ICONV_BUFSIZE; + + if (cd->pull(cd->cd_pull, + inbuf, inbytesleft, &bufp1, &bufsize) == -1 + && errno != E2BIG) return -1; + + bufsize = SMB_ICONV_BUFSIZE - bufsize; + + if (cd->push(cd->cd_push, + &bufp2, &bufsize, + outbuf, outbytesleft) == -1) return -1; + } + talloc_free(cvtbuf); } return 0; |