Back to index

php5  5.3.10
encodings.c
Go to the documentation of this file.
00001 /*
00002   This file is part of libXMLRPC - a C library for xml-encoded function calls.
00003 
00004   Author: Dan Libby (dan@libby.com)
00005   Epinions.com may be contacted at feedback@epinions-inc.com
00006 */
00007 
00008 /*  
00009   Copyright 2000 Epinions, Inc. 
00010 
00011   Subject to the following 3 conditions, Epinions, Inc.  permits you, free 
00012   of charge, to (a) use, copy, distribute, modify, perform and display this 
00013   software and associated documentation files (the "Software"), and (b) 
00014   permit others to whom the Software is furnished to do so as well.  
00015 
00016   1) The above copyright notice and this permission notice shall be included 
00017   without modification in all copies or substantial portions of the 
00018   Software.  
00019 
00020   2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 
00021   ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 
00022   IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 
00023   PURPOSE OR NONINFRINGEMENT.  
00024 
00025   3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 
00026   SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 
00027   OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 
00028   NEGLIGENCE), EVEN IF EPINIONS, INC.  IS AWARE OF THE POSSIBILITY OF SUCH 
00029   DAMAGES.    
00030 
00031 */
00032 
00033 #ifdef HAVE_CONFIG_H
00034 #include "config.h"
00035 #endif
00036 
00037 #ifndef PHP_WIN32
00038 #include <php_config.h>
00039 #else
00040 #include <config.w32.h>
00041 #include <stdlib.h>
00042 #endif
00043 
00044 static const char rcsid[] = "#(@) $Id: encodings.c 242949 2007-09-26 15:44:16Z cvs2svn $";
00045 
00046 #include <errno.h>
00047 
00048 #ifdef HAVE_GICONV_H
00049 #include <giconv.h>
00050 #else
00051 #include <iconv.h>
00052 #endif
00053 
00054 #include "encodings.h"
00055 
00056 #ifndef ICONV_CSNMAXLEN
00057 #define ICONV_CSNMAXLEN 64
00058 #endif
00059 
00060 static char* convert(const char* src, int src_len, int *new_len, const char* from_enc, const char* to_enc) {
00061    char* outbuf = 0;
00062 
00063    if(src && src_len && from_enc && to_enc) {
00064       size_t outlenleft = src_len;
00065       size_t inlenleft = src_len;
00066       int outlen = src_len;
00067       iconv_t ic;
00068       char* out_ptr = 0;
00069 
00070       if(strlen(to_enc) >= ICONV_CSNMAXLEN || strlen(from_enc) >= ICONV_CSNMAXLEN) {
00071          return NULL;
00072       }
00073       ic = iconv_open(to_enc, from_enc);
00074       if(ic != (iconv_t)-1) {
00075          size_t st;
00076          outbuf = (char*)malloc(outlen + 1);
00077 
00078          if(outbuf) {
00079             out_ptr = (char*)outbuf;
00080             while(inlenleft) {
00081                st = iconv(ic, (char**)&src, &inlenleft, &out_ptr, &outlenleft);
00082                if(st == -1) {
00083                   if(errno == E2BIG) {
00084                      int diff = out_ptr - outbuf;
00085                      outlen += inlenleft;
00086                      outlenleft += inlenleft;
00087                      outbuf = (char*)realloc(outbuf, outlen + 1);
00088                      if(!outbuf) {
00089                         break;
00090                      }
00091                      out_ptr = outbuf + diff;
00092                   }
00093                   else {
00094                      free(outbuf);
00095                      outbuf = 0;
00096                      break;
00097                   }
00098                }
00099             }
00100          }
00101          iconv_close(ic);
00102       }
00103       outlen -= outlenleft;
00104 
00105       if(new_len) {
00106          *new_len = outbuf ? outlen : 0;
00107       }
00108       if(outbuf) {
00109          outbuf[outlen] = 0;
00110       }
00111    }
00112    return outbuf;
00113 }
00114 
00115 /* returns a new string that must be freed */
00116 char* utf8_encode(const char *s, int len, int *newlen, const char* encoding)
00117 {
00118    return convert(s, len, newlen, encoding, "UTF-8");
00119 }
00120 
00121 /* returns a new string, possibly decoded */
00122 char* utf8_decode(const char *s, int len, int *newlen, const char* encoding)
00123 {
00124    return convert(s, len, newlen, "UTF-8", encoding);
00125 }
00126