diff options
Diffstat (limited to 'ext/xmlrpc/libxmlrpc/encodings.c')
-rw-r--r-- | ext/xmlrpc/libxmlrpc/encodings.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/ext/xmlrpc/libxmlrpc/encodings.c b/ext/xmlrpc/libxmlrpc/encodings.c new file mode 100644 index 0000000..f4cc212 --- /dev/null +++ b/ext/xmlrpc/libxmlrpc/encodings.c @@ -0,0 +1,126 @@ +/* + This file is part of libXMLRPC - a C library for xml-encoded function calls. + + Author: Dan Libby (dan@libby.com) + Epinions.com may be contacted at feedback@epinions-inc.com +*/ + +/* + Copyright 2000 Epinions, Inc. + + Subject to the following 3 conditions, Epinions, Inc. permits you, free + of charge, to (a) use, copy, distribute, modify, perform and display this + software and associated documentation files (the "Software"), and (b) + permit others to whom the Software is furnished to do so as well. + + 1) The above copyright notice and this permission notice shall be included + without modification in all copies or substantial portions of the + Software. + + 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF + ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY + IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE OR NONINFRINGEMENT. + + 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, + SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT + OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING + NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH + DAMAGES. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef PHP_WIN32 +#include <php_config.h> +#else +#include <config.w32.h> +#include <stdlib.h> +#endif + +static const char rcsid[] = "#(@) $Id$"; + +#include <errno.h> + +#ifdef HAVE_GICONV_H +#include <giconv.h> +#else +#include <iconv.h> +#endif + +#include "encodings.h" + +#ifndef ICONV_CSNMAXLEN +#define ICONV_CSNMAXLEN 64 +#endif + +static char* convert(const char* src, int src_len, int *new_len, const char* from_enc, const char* to_enc) { + char* outbuf = 0; + + if(src && src_len && from_enc && to_enc) { + size_t outlenleft = src_len; + size_t inlenleft = src_len; + int outlen = src_len; + iconv_t ic; + char* out_ptr = 0; + + if(strlen(to_enc) >= ICONV_CSNMAXLEN || strlen(from_enc) >= ICONV_CSNMAXLEN) { + return NULL; + } + ic = iconv_open(to_enc, from_enc); + if(ic != (iconv_t)-1) { + size_t st; + outbuf = (char*)malloc(outlen + 1); + + if(outbuf) { + out_ptr = (char*)outbuf; + while(inlenleft) { + st = iconv(ic, (char**)&src, &inlenleft, &out_ptr, &outlenleft); + if(st == -1) { + if(errno == E2BIG) { + int diff = out_ptr - outbuf; + outlen += inlenleft; + outlenleft += inlenleft; + outbuf = (char*)realloc(outbuf, outlen + 1); + if(!outbuf) { + break; + } + out_ptr = outbuf + diff; + } + else { + free(outbuf); + outbuf = 0; + break; + } + } + } + } + iconv_close(ic); + } + outlen -= outlenleft; + + if(new_len) { + *new_len = outbuf ? outlen : 0; + } + if(outbuf) { + outbuf[outlen] = 0; + } + } + return outbuf; +} + +/* returns a new string that must be freed */ +char* utf8_encode(const char *s, int len, int *newlen, const char* encoding) +{ + return convert(s, len, newlen, encoding, "UTF-8"); +} + +/* returns a new string, possibly decoded */ +char* utf8_decode(const char *s, int len, int *newlen, const char* encoding) +{ + return convert(s, len, newlen, "UTF-8", encoding); +} + |