Extra arguments for the length of non-UTF-8 strings.
[gedcom-parse.git] / utf8 / utf8-convert.c
index 9db6fdf77fd2859d9b50ca90656c086b0c44d959..926e14c41305d7e4741caf3fc3eb27331c06544b 100644 (file)
 #define INTERNAL_BUFFER 0
 #define EXTERNAL_BUFFER 1
 
-void reset_conv_buffer(struct conv_buffer* buf)
+struct conv_buffer {
+  char*   buffer;
+  size_t  size;
+  int     type;  /* For internal use */
+};
+
+struct convert {
+  iconv_t from_utf8;
+  iconv_t to_utf8;
+  struct conv_buffer* inbuf;
+  size_t  insize;
+  struct conv_buffer* outbuf;
+  char*   unknown;
+};
+
+void reset_conv_buffer(conv_buffer_t buf)
 {
   memset(buf->buffer, 0, buf->size);
 }
 
-struct conv_buffer* create_conv_buffer(int size)
+conv_buffer_t create_conv_buffer(int size)
 {
   struct conv_buffer* buf = NULL;
 
@@ -47,7 +62,7 @@ struct conv_buffer* create_conv_buffer(int size)
   return buf;
 }
 
-void free_conv_buffer(struct conv_buffer* buf)
+void free_conv_buffer(conv_buffer_t buf)
 {
   if (buf) {
     free(buf->buffer);
@@ -55,7 +70,7 @@ void free_conv_buffer(struct conv_buffer* buf)
   }
 }
 
-char* grow_conv_buffer(struct conv_buffer* buf, char* curr_pos)
+char* grow_conv_buffer(conv_buffer_t buf, char* curr_pos)
 {
   size_t outlen, new_size;
   char*  new_buffer;
@@ -142,7 +157,7 @@ int conversion_set_unknown(convert_t conv, const char* unknown)
   return result;
 }
 
-int conversion_set_output_buffer(convert_t conv, struct conv_buffer* buf)
+int conversion_set_output_buffer(convert_t conv, conv_buffer_t buf)
 {
   if (!conv)
     return 0;
@@ -172,7 +187,8 @@ void cleanup_utf8_conversion(convert_t conv)
   }
 }
 
-char* convert_from_utf8(convert_t conv, const char* input, int* conv_fails)
+char* convert_from_utf8(convert_t conv, const char* input, int* conv_fails,
+                       size_t* output_len)
 {
   size_t insize = strlen(input);
   size_t outsize;
@@ -231,12 +247,12 @@ char* convert_from_utf8(convert_t conv, const char* input, int* conv_fails)
     }
     nconv = iconv(conv->from_utf8, &inptr, &insize, &outptr, &outsize);
   }
+  if (output_len) *output_len = outptr - outbuf->buffer;
   return outbuf->buffer;
 }
 
-char* convert_to_utf8(convert_t conv, const char* input)
+char* convert_to_utf8(convert_t conv, const char* input, size_t input_len)
 {
-  size_t insize  = strlen(input);
   size_t outsize;
   ICONV_CONST char *inptr  = (ICONV_CONST char*) input;
   char   *outptr;
@@ -252,7 +268,7 @@ char* convert_to_utf8(convert_t conv, const char* input)
   outptr  = outbuf->buffer;
   outsize = outbuf->size;
   reset_conv_buffer(conv->outbuf);
-  nconv = iconv(conv->to_utf8, &inptr, &insize, &outptr, &outsize);
+  nconv = iconv(conv->to_utf8, &inptr, &input_len, &outptr, &outsize);
   while (nconv == (size_t)-1) {
     if (errno == E2BIG) {
       /* grow the output buffer */
@@ -271,7 +287,7 @@ char* convert_to_utf8(convert_t conv, const char* input)
       /* EBADF is an error which should be captured by the first if above */
       return NULL;
     }
-    nconv = iconv(conv->to_utf8, &inptr, &insize, &outptr, &outsize);
+    nconv = iconv(conv->to_utf8, &inptr, &input_len, &outptr, &outsize);
   }
   return outbuf->buffer;  
 }