diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/util/charset/charcnv.c | 130 | ||||
-rw-r--r-- | lib/util/charset/charset.h | 6 |
2 files changed, 77 insertions, 59 deletions
diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c index 9dd68f05ea..1f3b1ac846 100644 --- a/lib/util/charset/charcnv.c +++ b/lib/util/charset/charcnv.c @@ -155,71 +155,21 @@ static smb_iconv_t get_conv_handle(struct smb_iconv_convenience *ic, return ic->conv_handles[from][to]; } - /** * Convert string from one encoding to another, making error checking etc * + * @param mem_ctx Memory context + * @param cd Iconv handle * @param src pointer to source string (multibyte or singlebyte) * @param srclen length of the source string in bytes * @param dest pointer to destination string (multibyte or singlebyte) * @param destlen maximal length allowed for string * @returns the number of bytes occupied in the destination **/ -_PUBLIC_ ssize_t convert_string_convenience(struct smb_iconv_convenience *ic, - charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t destlen) -{ - size_t i_len, o_len; - size_t retval; - const char* inbuf = (const char*)src; - char* outbuf = (char*)dest; - smb_iconv_t descriptor; - - if (srclen == (size_t)-1) - srclen = strlen(inbuf)+1; - - descriptor = get_conv_handle(ic, from, to); - - if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { - /* conversion not supported, use as is */ - size_t len = MIN(srclen,destlen); - memcpy(dest,src,len); - return len; - } - - i_len=srclen; - o_len=destlen; - retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); - if(retval==(size_t)-1) { - const char *reason; - switch(errno) { - case EINVAL: - reason="Incomplete multibyte sequence"; - return -1; - case E2BIG: - reason="No more room"; - if (from == CH_UNIX) { - DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen, - (const char *)src)); - } else { - DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen)); - } - return -1; - case EILSEQ: - reason="Illegal multibyte sequence"; - return -1; - } - /* smb_panic(reason); */ - } - return destlen-o_len; -} - -_PUBLIC_ ssize_t convert_string_talloc_descriptor(TALLOC_CTX *ctx, smb_iconv_t descriptor, void const *src, size_t srclen, void **dest) +_PUBLIC_ ssize_t iconv_talloc(TALLOC_CTX *ctx, + smb_iconv_t cd, + void const *src, size_t srclen, + void **dest) { size_t i_len, o_len, destlen; size_t retval; @@ -247,7 +197,7 @@ convert: end */ i_len = srclen; o_len = destlen-2; - retval = smb_iconv(descriptor, + retval = smb_iconv(cd, &inbuf, &i_len, &outbuf, &o_len); if(retval == (size_t)-1) { @@ -275,9 +225,73 @@ convert: *dest = ob; return destlen; + } /** + * Convert string from one encoding to another, making error checking etc + * + * @param src pointer to source string (multibyte or singlebyte) + * @param srclen length of the source string in bytes + * @param dest pointer to destination string (multibyte or singlebyte) + * @param destlen maximal length allowed for string + * @returns the number of bytes occupied in the destination + **/ +_PUBLIC_ ssize_t convert_string_convenience(struct smb_iconv_convenience *ic, + charset_t from, charset_t to, + void const *src, size_t srclen, + void *dest, size_t destlen) +{ + size_t i_len, o_len; + size_t retval; + const char* inbuf = (const char*)src; + char* outbuf = (char*)dest; + smb_iconv_t descriptor; + + if (srclen == (size_t)-1) + srclen = strlen(inbuf)+1; + + descriptor = get_conv_handle(ic, from, to); + + if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { + /* conversion not supported, use as is */ + size_t len = MIN(srclen,destlen); + memcpy(dest,src,len); + return len; + } + + i_len=srclen; + o_len=destlen; + retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); + if(retval==(size_t)-1) { + const char *reason; + switch(errno) { + case EINVAL: + reason="Incomplete multibyte sequence"; + return -1; + case E2BIG: + reason="No more room"; + if (from == CH_UNIX) { + DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n", + charset_name(ic, from), charset_name(ic, to), + (int)srclen, (int)destlen, + (const char *)src)); + } else { + DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n", + charset_name(ic, from), charset_name(ic, to), + (int)srclen, (int)destlen)); + } + return -1; + case EILSEQ: + reason="Illegal multibyte sequence"; + return -1; + } + /* smb_panic(reason); */ + } + return destlen-o_len; +} + +/** * Convert between character sets, allocating a new buffer using talloc for the result. * * @param srclen length of source buffer. @@ -310,7 +324,7 @@ _PUBLIC_ ssize_t convert_string_talloc_convenience(TALLOC_CTX *ctx, return -1; } - return convert_string_talloc_descriptor(ctx, descriptor, src, srclen, dest); + return iconv_talloc(ctx, descriptor, src, srclen, dest); } /* diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index cace79f949..b69bef2d61 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -122,6 +122,11 @@ ssize_t convert_string(charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen); +ssize_t iconv_talloc(TALLOC_CTX *mem_ctx, + smb_iconv_t cd, + void const *src, size_t srclen, + void **dest); + extern struct smb_iconv_convenience *global_iconv_convenience; codepoint_t next_codepoint(const char *str, size_t *size); @@ -145,7 +150,6 @@ ssize_t convert_string_convenience(struct smb_iconv_convenience *ic, charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen); -ssize_t convert_string_talloc_descriptor(TALLOC_CTX *ctx, smb_iconv_t descriptor, void const *src, size_t srclen, void **dest); ssize_t convert_string_talloc_convenience(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, charset_t from, charset_t to, |