summaryrefslogtreecommitdiff
path: root/lib/util/charset
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2011-03-30 18:13:05 -0700
committerJeremy Allison <jra@samba.org>2011-03-31 04:09:09 +0200
commit21193c8eeba6d03f680ad34acbbb4cff14d87809 (patch)
treee4c654872f2e814f2009f73ea2760043accd1708 /lib/util/charset
parentf9a2f4f47c71e5054c05703e72c24f2f5a87d993 (diff)
downloadsamba-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/charset')
-rw-r--r--lib/util/charset/iconv.c41
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;