summaryrefslogtreecommitdiffstats
path: root/source/lib
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2001-11-07 18:14:46 +0000
committerSimo Sorce <idra@samba.org>2001-11-07 18:14:46 +0000
commit8b494b0be323c983b7ea3d1dcf1f61216396caec (patch)
tree7210885f86ad3ba64ad15d38623e14eb415d5b62 /source/lib
parent39f9c78d07d7af6abc71b33a6018ac0237608b6a (diff)
downloadsamba-8b494b0be323c983b7ea3d1dcf1f61216396caec.tar.gz
samba-8b494b0be323c983b7ea3d1dcf1f61216396caec.tar.xz
samba-8b494b0be323c983b7ea3d1dcf1f61216396caec.zip
add convert_string_allocate() function
Diffstat (limited to 'source/lib')
-rw-r--r--source/lib/charcnv.c91
1 files changed, 86 insertions, 5 deletions
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index ebf316d9dd3..2929233388a 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -26,6 +26,8 @@ static pstring cvtbuf;
static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
+static int initialized;
+
/****************************************************************************
return the name of a charset to give to iconv()
****************************************************************************/
@@ -92,15 +94,14 @@ size_t convert_string(charset_t from, charset_t to,
{
size_t i_len, o_len;
size_t retval;
- const char* inbuf = (const char*)src;
+ char* inbuf = (char*)src;
char* outbuf = (char*)dest;
- static int initialised;
smb_iconv_t descriptor;
if (srclen == -1) srclen = strlen(src)+1;
- if (!initialised) {
- initialised = 1;
+ if (!initialized) {
+ initialized = 1;
load_case_tables();
init_iconv();
}
@@ -118,7 +119,8 @@ size_t convert_string(charset_t from, charset_t to,
o_len=destlen;
retval=smb_iconv(descriptor,&inbuf, &i_len, &outbuf, &o_len);
if(retval==-1)
- { char *reason="unknown error";
+ {
+ char *reason="unknown error";
switch(errno)
{ case EINVAL: reason="Incomplete multibyte sequence"; break;
case E2BIG: reason="No more room";
@@ -139,6 +141,85 @@ size_t convert_string(charset_t from, charset_t to,
return destlen-o_len;
}
+/* you must provide source lenght -1 is not accepted as lenght.
+ this function will return the size in bytes of the converted string
+ or -1 in case of error.
+ */
+size_t convert_string_allocate(charset_t from, charset_t to,
+ void const *src, size_t srclen, void **dest)
+{
+ size_t i_len, o_len, destlen;
+ size_t retval;
+ char* inbuf = (char *)src;
+ char *outbuf, *ob;
+ smb_iconv_t descriptor;
+
+ *dest = NULL;
+
+ if (src == NULL || srclen == -1) return -1;
+
+ if (!initialized) {
+ initialized = 1;
+ load_case_tables();
+ init_iconv();
+ }
+
+ descriptor = conv_handles[from][to];
+
+ if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
+ /* conversion not supported, return -1*/
+ return -1;
+ }
+
+ destlen = MAX(srclen, 1024);
+ outbuf = NULL;
+convert:
+ destlen = destlen * 2;
+ ob = (char *)realloc(outbuf, destlen);
+ if (!ob) {
+ DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
+ free(outbuf);
+ return -1;
+ }
+ else outbuf = ob;
+ i_len = srclen;
+ o_len = destlen;
+ retval = smb_iconv(descriptor,
+ &inbuf, &i_len,
+ &outbuf, &o_len);
+ if(retval == -1)
+ {
+ char *reason="unknown error";
+ switch(errno)
+ {
+ case EINVAL:
+ reason="Incomplete multibyte sequence";
+ break;
+ case E2BIG:
+ goto convert;
+ break;
+ case EILSEQ:
+ reason="Illegal myltibyte sequence";
+ break;
+ }
+ DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
+ /* smb_panic(reason); */
+ return -1;
+ }
+
+ destlen = destlen - o_len;
+ *dest = (char *)malloc(destlen);
+ if (!*dest) {
+ DEBUG(0, ("convert_string_allocate: out of memory!\n"));
+ free(outbuf);
+ return -1;
+ }
+ memcpy(*dest, outbuf, destlen);
+ free(outbuf);
+
+ return destlen;
+}
+
int unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
{
int size;