summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 10:33:44 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 10:33:44 +0800
commita2604d5ec5aa5e0701581a91b5ecb1c0a5c5b722 (patch)
tree53bea66888948a1252696c523f5798dfb558b87f
parenta41d5a24a0cc12dd7af1daac2dd55ccfcadf3a09 (diff)
iconv: provides a iconv implementions
-rw-r--r--iconv.c67
-rw-r--r--iconv.h28
2 files changed, 95 insertions, 0 deletions
diff --git a/iconv.c b/iconv.c
new file mode 100644
index 0000000..f13ba61
--- /dev/null
+++ b/iconv.c
@@ -0,0 +1,67 @@
+#include "iconv.h"
+#include "uniconv.h"
+
+#include <errno.h>
+
+iconv_t uc_iconv_open(const char *to, const char *from)
+{
+ uniconv_t *uc = uniconv_open(to, from);
+ if (!uc)
+ return (iconv_t)-1;
+ return uc;
+}
+
+size_t uc_iconv (iconv_t cd, char **inbuf,
+ size_t *inbytesleft,
+ char **outbuf,
+ size_t *outbytesleft)
+{
+ int ret;
+
+ if (cd == (iconv_t)-1 || !cd) {
+ errno = EBADF;
+ return (size_t)-1;
+ }
+
+ ret = uniconv_conv(cd, (const char **)inbuf, inbytesleft,
+ outbuf, outbytesleft);
+ if (ret == UNICONV_EBADF) {
+ errno = EBADF;
+ return (size_t)-1;
+ } else if (ret == UNICONV_EINVAL) {
+ errno = EINVAL;
+ return (size_t)-1;
+ } else if (ret == UNICONV_E2BIG) {
+ errno = E2BIG;
+ return (size_t)-1;
+ } else if (ret == UNICONV_EILSEQ) {
+ errno = EILSEQ;
+ return (size_t)-1;
+ }
+
+ return ret;
+}
+
+int uc_iconv_close (iconv_t cd)
+{
+ if (cd == (iconv_t)-1 || !cd) {
+ errno = EBADF;
+ return -1;
+ }
+
+ uniconv_close(cd);
+ return 0;
+}
+
+#ifdef __GNUC__
+#define weak_alias(name, aliasname) _weak_alias(name, aliasname)
+#define _weak_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
+#undef iconv_open
+#undef iconv
+#undef iconv_close
+weak_alias (uc_iconv_open, iconv_open)
+weak_alias (uc_iconv, iconv)
+weak_alias (uc_iconv_close, iconv_close)
+#endif
+
diff --git a/iconv.h b/iconv.h
new file mode 100644
index 0000000..0648fd3
--- /dev/null
+++ b/iconv.h
@@ -0,0 +1,28 @@
+#ifndef UNICONV_ICONV_H
+#define UNICONV_ICONV_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+#define extern "C" {
+#endif
+
+typedef void* iconv_t;
+
+extern iconv_t uc_iconv_open(const char *to, const char *from);
+#define iconv_open(to, from) uc_iconv(to, from)
+
+extern size_t uc_iconv (iconv_t cd, char **inbuf,
+ size_t *inbytesleft,
+ char **outbuf,
+ size_t *outbytesleft);
+#define iconv(cd, ib, ibl, ob, obl) uc_iconv(cd, ib, ibl, ob, obl)
+
+extern int uc_iconv_close (iconv_t cd);
+#define iconv_close(cd) uc_iconv_close(cd)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif