diff options
Diffstat (limited to 'src/iconv.c')
-rw-r--r-- | src/iconv.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/iconv.c b/src/iconv.c new file mode 100644 index 0000000..1bf4d94 --- /dev/null +++ b/src/iconv.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020, yzrh <yzrh@tuta.io> + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <stdlib.h> +#include <string.h> + +#include <iconv.h> + +/* So, why would anyone use something other than UTF-8? */ +int +strconv(char **dst, + const char * restrict dst_code, + const char * restrict src, + const char * restrict src_code, + int *size) +{ + size_t dst_size = *size; + char *dst_conv = malloc(dst_size); + + if (dst_conv == NULL) + return 1; + + size_t src_size = strlen(src) + 1; + char *src_conv = malloc(src_size); + + if (src_conv == NULL) { + free(dst_conv); + return 1; + } + + strncpy(src_conv, src, src_size); + + char *dst_start = dst_conv; + char *src_start = src_conv; + + iconv_t conv_src_dst = iconv_open(dst_code, src_code); + + if (conv_src_dst == (iconv_t) - 1) { + free(dst_conv); + free(src_conv); + return 1; + } + + if (iconv(conv_src_dst, + &src_conv, &src_size, + &dst_conv, &dst_size) == (size_t) - 1) { + free(dst_start); + free(src_start); + return 1; + } else { + /* Not including NULL */ + *size -= dst_size + 2; + + *dst = malloc(*size); + + if (*dst != NULL) + memcpy(*dst, dst_start, *size); + + free(dst_start); + free(src_start); + } + + if (iconv_close(conv_src_dst) != 0 || *dst == NULL) + return 1; + + return 0; +} |