Add toolchain and mbtk source
Change-Id: Ie12546301367ea59240bf23d5e184ad7e36e40b3
diff --git a/mbtk/test/iconv_demo.cc b/mbtk/test/iconv_demo.cc
new file mode 100755
index 0000000..de95454
--- /dev/null
+++ b/mbtk/test/iconv_demo.cc
@@ -0,0 +1,204 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iconv.h>
+#include <errno.h>
+#include <stddef.h>
+
+struct outbuf
+{
+ struct outbuf *next;
+ char *outptr;
+ size_t outbytesleft;
+ char buf[256];
+};
+
+char *eazyiconv(const char *to, const char *from,
+ char *str, size_t str_blen, size_t str_elemsize, size_t out_tailzero_blen, size_t *out_size,
+ const char *replchr)
+{
+ char *retstr = NULL;
+ struct outbuf *outhead = NULL;
+ struct outbuf *outtail = NULL;
+ struct outbuf *outiter = NULL;
+ iconv_t cd = NULL;
+ char *inptr = str;
+ size_t inbytesleft = str_blen;
+ int retval = 0;
+ int err = 0;
+ size_t blocksize = 0;
+ size_t totalsize = 0;
+ char *retiter = NULL;
+ unsigned int chrval = 0;
+ iconv_t cdreplchr = NULL;
+ char replchrfmtbuf[256] = "";
+ char replchrbuf[256] = "";
+ char *replchrfmtptr = replchrfmtbuf;
+ size_t replchrfmtleft = sizeof replchrfmtbuf;
+ char *replchrptr = replchrbuf;
+ size_t replchrleft = sizeof replchrbuf;
+ int replchr_blen = 0;
+
+ cd = iconv_open(to, from);
+ if (cd == (iconv_t)-1)
+ {
+ goto noclean;
+ }
+
+ outhead = outtail = calloc(1, sizeof(struct outbuf));
+ if (outtail == NULL)
+ {
+ goto clean_cd;
+ }
+ outtail->next = NULL;
+ outtail->outptr = outtail->buf;
+ outtail->outbytesleft = sizeof outtail->buf;
+ memset(outtail->buf, 0, sizeof outtail->buf);
+
+ while (1)
+ {
+ retval = iconv(cd, &inptr, &inbytesleft, &outtail->outptr, &outtail->outbytesleft);
+ if (retval == -1)
+ err = errno;
+ else
+ err = 0;
+ switch (err)
+ {
+ case 0:
+ outiter = calloc(1, sizeof(struct outbuf));
+ if (outiter == NULL)
+ {
+ goto clean_outbufs;
+ }
+ if (inptr == NULL) // succeeded cleanup iconv
+ {
+ goto succeeded;
+ }
+ else // fully succeeded iconv
+ {
+ inptr = NULL; // do cleanup iconv
+ inbytesleft = 0;
+ }
+ break;
+ case EINVAL: // incomplete tail sequence
+ case EILSEQ: // invalid sequence
+ chrval = 0;
+ memcpy(&chrval, inptr, str_elemsize > sizeof chrval ? sizeof chrval : str_elemsize);
+ snprintf(replchrfmtbuf, sizeof replchrfmtbuf, replchr, chrval);
+ inptr += str_elemsize;
+ inbytesleft -= str_elemsize;
+
+ cdreplchr = iconv_open(to, "UTF-8");
+ if (cdreplchr == (iconv_t)-1)
+ {
+ goto clean_outbufs;
+ }
+ replchrfmtptr = replchrfmtbuf;
+ replchrfmtleft = strlen(replchrfmtbuf);
+ replchrptr = replchrbuf;
+ replchrleft = sizeof replchrbuf;
+ iconv(cdreplchr, &replchrfmtptr, &replchrfmtleft, &replchrptr, &replchrleft);
+ iconv(cdreplchr, NULL, NULL, &replchrptr, &replchrleft);
+ iconv_close(cdreplchr);
+ replchr_blen = replchrptr - replchrbuf;
+
+ if (outtail->outbytesleft < replchr_blen)
+ {
+ outiter = calloc(1, sizeof(struct outbuf));
+ if (outiter == NULL)
+ {
+ goto clean_outbufs;
+ }
+ outtail->next = outiter;
+ outtail = outiter;
+ outtail->next = NULL;
+ outtail->outptr = outtail->buf;
+ outtail->outbytesleft = sizeof outtail->buf;
+ memset(outtail->buf, 0, sizeof outtail->buf);
+ }
+ memcpy(outtail->outptr, replchrbuf, replchr_blen);
+ outtail->outptr += replchr_blen;
+ outtail->outbytesleft -= replchr_blen;
+ break;
+ case E2BIG: // no enough space
+ outiter = calloc(1, sizeof(struct outbuf));
+ if (outiter == NULL)
+ {
+ goto clean_outbufs;
+ }
+ outtail->next = outiter;
+ outtail = outiter;
+ outtail->next = NULL;
+ outtail->outptr = outtail->buf;
+ outtail->outbytesleft = sizeof outtail->buf;
+ memset(outtail->buf, 0, sizeof outtail->buf);
+ break;
+ default:
+ break;
+ }
+ }
+
+succeeded:
+ totalsize = 0;
+ for (outiter = outhead; outiter != NULL; outiter = outiter->next)
+ {
+ blocksize = outiter->outptr - outiter->buf;
+ totalsize += blocksize;
+ }
+ retstr = calloc(totalsize + out_tailzero_blen, 1);
+ if (retstr == NULL)
+ {
+ goto clean_outbufs;
+ }
+ retiter = retstr;
+ for (outiter = outhead; outiter != NULL; outiter = outiter->next)
+ {
+ blocksize = outiter->outptr - outiter->buf;
+ memcpy(retiter, outiter->buf, blocksize);
+ retiter += blocksize;
+ }
+ memset(retiter, 0, out_tailzero_blen);
+ *out_size = totalsize;
+
+clean_outbufs:
+ while (outhead != NULL)
+ {
+ outiter = outhead;
+ outhead = outhead->next;
+ free(outiter);
+ }
+ outtail = NULL;
+clean_cd:
+ iconv_close(cd);
+noclean:
+ return retstr;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 7)
+ {
+ printf("usage: eiconv_test from_charset from_elemsize to_charset to_elemsize from_file to_file (no utf-16/32)\n");
+ return 0;
+ }
+ FILE *from_file = fopen(argv[5], "rb");
+ fseek(from_file, 0, SEEK_END);
+ off_t fsize = ftell(from_file);
+ fseek(from_file, 0, SEEK_SET);
+ char *from_str = malloc(fsize + 1);
+ fread(from_str, 1, fsize, from_file);
+ fclose(from_file);
+
+ size_t out_size = 0;
+ char *to_str = eazyiconv(argv[3], argv[1],
+ from_str, fsize, atoi(argv[2]), atoi(argv[4]), &out_size,
+ "<0x%02X>");
+
+ FILE *to_file = fopen(argv[6], "wb");
+ fwrite(to_str, 1, out_size, to_file);
+ free(to_str);
+ fclose(to_file);
+ return 0;
+}
+
+