int encode(int unicode, apr_pool_t *pool) { if (//(0xe000 <= unicode && unicode <= 0xf8ff) || // private use area (0xd800 <= unicode && unicode <= 0xdbff) || // high surrogate area (0xdc00 <= unicode && unicode <= 0xdfff)) { // low surrogate area return -1; } apr_size_t inbytesleft = 2; apr_size_t outbytesleft = 2; char inbuf_[2] = { (char)(unicode >> 8), (char)unicode }; char outbuf_[2]; const char *inbuf = inbuf_; char *outbuf = outbuf_; apr_iconv_t cd; if (apr_iconv_open("CP932", "UTF-16", pool, &cd) < 0) { return -1; } apr_size_t result = 0; if (apr_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft, &result) < 0) { return -1; } if (apr_iconv_close(cd, pool) < 0) { return -1; } if (result == 0 && inbytesleft == 0) { if (outbytesleft == 1) { int cp932 = (int)(byte)outbuf_[0]; if (cp932 == 0x5f && unicode != 0x5f) { // missing char is converted to 0x5f return -1; } return cp932; } else if (outbytesleft == 0) { return ((int)(byte)outbuf_[0] << 8) | (int)(byte)outbuf_[1]; } } return -1; }
int main(int argc, const char **argv) { apr_iconv_t cd; iconv_stream *is; const char *from = NULL, *to = NULL, *input = NULL; char opt; apr_pool_t *ctx; apr_status_t status; apr_getopt_t *options; const char *opt_arg; /* Initialize APR */ apr_initialize(); atexit(closeapr); if (apr_pool_create(&ctx, NULL) != APR_SUCCESS) { fprintf(stderr, "Couldn't allocate context.\n"); exit(-1); } apr_getopt_init(&options, ctx, argc, argv); status = apr_getopt(options, "f:s:t:v", &opt, &opt_arg); while (status == APR_SUCCESS) { switch (opt) { case 'f': from = opt_arg; break; case 't': to = opt_arg; break; case 's': input = opt_arg; break; case 'v': fprintf(stderr, "APR-iconv version " API_VERSION_STRING "\n"); exit(0); default: fprintf(stderr, "Usage: iconv -f <name> -t <name> [-s <input>]\n"); exit(3); } status = apr_getopt(options, "f:s:t:v",&opt, &opt_arg); } if (status == APR_BADCH || status == APR_BADARG) { fprintf(stderr, "Usage: iconv -f <name> -t <name> [-s <input>]\n"); exit(3); } if (from == NULL) { fprintf(stderr, "missing source charset (-f <name>)\n"); exit(4); } if (to == NULL) { fprintf(stderr, "missing destination charset (-t <name>)\n"); exit(5); } /* Use it */ status = apr_iconv_open(to, from, ctx, &cd); if (status) { fprintf(stderr, "unable to open specified converter\n"); exit(6); } if (!(is = iconv_ostream_fopen(cd, stdout))) { apr_iconv_close(cd,ctx); exit(7); } if (input) { if (iconv_bwrite(is, input, strlen(input)) <= 0) exit(8); } else if (optind < argc) { for (opt = optind; opt < argc; opt ++) convert_file(argv[opt], is); } else convert_file("-", is); if (iconv_write(is, NULL, 0) < 0) exit(9); iconv_stream_close(is); apr_iconv_close(cd,ctx); return 0; }