- size_t res;
- size_t outsize = out_len;
- char *wrptr = output_buffer;
- ICONV_CONST char *rdptr = (ICONV_CONST char*) conv_buf;
- char *retval = output_buffer;
- /* set up input buffer (concatenate to what was left previous time) */
- /* can't use strcpy, because possible null bytes from unicode */
- memcpy(conv_buf + conv_buf_size, str, len);
- conv_buf_size += len;
- /* set up output buffer (empty it) */
- memset(output_buffer, 0, out_len);
- /* do the conversion */
- res = iconv(cd_to_internal, &rdptr, &conv_buf_size, &wrptr, &outsize);
- if (res == (size_t)-1) {
- if (errno == EILSEQ) {
- /* restart from an empty state and return NULL */
- iconv(cd_to_internal, NULL, NULL, NULL, NULL);
- retval = NULL;
- rdptr++;
- conv_buf_size--;
- }
- else if (errno == EINVAL) {
- /* Do nothing, leave it to next iteration */
- }
- else {
- gedcom_error(_("Error in converting characters: %s"), strerror(errno));
- }
- }
- /* then shift what is left over to the head of the input buffer */
- memmove(conv_buf, rdptr, conv_buf_size);
- memset(conv_buf + conv_buf_size, 0, sizeof(conv_buf) - conv_buf_size);
- return retval;