This source file includes following definitions.
- convert
- utf8_encode
- utf8_decode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #ifndef PHP_WIN32
38 #include <php_config.h>
39 #else
40 #include <config.w32.h>
41 #include <stdlib.h>
42 #endif
43
44 static const char rcsid[] = "#(@) $Id$";
45
46 #include <errno.h>
47
48 #ifdef HAVE_GICONV_H
49 #include <giconv.h>
50 #else
51 #include <iconv.h>
52 #endif
53
54 #include "encodings.h"
55
56 #ifndef ICONV_CSNMAXLEN
57 #define ICONV_CSNMAXLEN 64
58 #endif
59
60 static char* convert(const char* src, int src_len, int *new_len, const char* from_enc, const char* to_enc) {
61 char* outbuf = 0;
62
63 if(src && src_len && from_enc && to_enc) {
64 size_t outlenleft = src_len;
65 size_t inlenleft = src_len;
66 int outlen = src_len;
67 iconv_t ic;
68 char* out_ptr = 0;
69
70 if(strlen(to_enc) >= ICONV_CSNMAXLEN || strlen(from_enc) >= ICONV_CSNMAXLEN) {
71 return NULL;
72 }
73 ic = iconv_open(to_enc, from_enc);
74 if(ic != (iconv_t)-1) {
75 size_t st;
76 outbuf = (char*)malloc(outlen + 1);
77
78 if(outbuf) {
79 out_ptr = (char*)outbuf;
80 while(inlenleft) {
81 st = iconv(ic, (char**)&src, &inlenleft, &out_ptr, &outlenleft);
82 if(st == -1) {
83 if(errno == E2BIG) {
84 int diff = out_ptr - outbuf;
85 outlen += inlenleft;
86 outlenleft += inlenleft;
87 outbuf = (char*)realloc(outbuf, outlen + 1);
88 if(!outbuf) {
89 break;
90 }
91 out_ptr = outbuf + diff;
92 }
93 else {
94 free(outbuf);
95 outbuf = 0;
96 break;
97 }
98 }
99 }
100 }
101 iconv_close(ic);
102 }
103 outlen -= outlenleft;
104
105 if(new_len) {
106 *new_len = outbuf ? outlen : 0;
107 }
108 if(outbuf) {
109 outbuf[outlen] = 0;
110 }
111 }
112 return outbuf;
113 }
114
115
116 char* utf8_encode(const char *s, int len, int *newlen, const char* encoding)
117 {
118 return convert(s, len, newlen, encoding, "UTF-8");
119 }
120
121
122 char* utf8_decode(const char *s, int len, int *newlen, const char* encoding)
123 {
124 return convert(s, len, newlen, "UTF-8", encoding);
125 }
126