1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | http://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Vadim Savchuk <vsavchuk@productengine.com> |
14 | Dmitry Lakhtyuk <dlakhtyuk@productengine.com> |
15 +----------------------------------------------------------------------+
16 */
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include <php.h>
23
24 #include "intl_common.h"
25 #include "intl_convert.h"
26
27 /* {{{ intl_convert_utf8_to_utf16
28 * Convert given string from UTF-8 to UTF-16 to *target buffer.
29 *
30 * It *target is NULL then we allocate a large enough buffer,
31 * store the converted string into it, and make target point to it.
32 *
33 * Otherwise, if *target is non-NULL, we assume that it points to a
34 * dynamically allocated buffer of *target_len bytes length.
35 * In this case the buffer will be used to store the converted string to,
36 * and may be resized (made larger) if needed.
37 *
38 * @param target Where to place the result.
39 * @param target_len Result length.
40 * @param source String to convert.
41 * @param source_len Length of the source string.
42 * @param status Conversion status.
43 *
44 * @return void This function does not return anything.
45 */
intl_convert_utf8_to_utf16(UChar ** target,int * target_len,const char * src,int src_len,UErrorCode * status)46 void intl_convert_utf8_to_utf16(
47 UChar** target, int* target_len,
48 const char* src, int src_len,
49 UErrorCode* status )
50 {
51 UChar* dst_buf = NULL;
52 uint32_t dst_len = 0;
53
54 /* If *target is NULL determine required destination buffer size (pre-flighting).
55 * Otherwise, attempt to convert source string; if *target buffer is not large enough
56 * it will be resized appropriately.
57 */
58 *status = U_ZERO_ERROR;
59
60 u_strFromUTF8( *target, *target_len, &dst_len, src, src_len, status );
61
62 if( *status == U_ZERO_ERROR )
63 {
64 /* String is converted successfuly */
65 (*target)[dst_len] = 0;
66 *target_len = dst_len;
67 return;
68 }
69
70 /* Bail out if an unexpected error occurred.
71 * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough).
72 * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty).
73 */
74 if( *status != U_BUFFER_OVERFLOW_ERROR && *status != U_STRING_NOT_TERMINATED_WARNING )
75 return;
76
77 /* Allocate memory for the destination buffer (it will be zero-terminated). */
78 dst_buf = eumalloc( dst_len + 1 );
79
80 /* Convert source string from UTF-8 to UTF-16. */
81 *status = U_ZERO_ERROR;
82 u_strFromUTF8( dst_buf, dst_len+1, NULL, src, src_len, status );
83 if( U_FAILURE( *status ) )
84 {
85 efree( dst_buf );
86 return;
87 }
88
89 dst_buf[dst_len] = 0;
90
91 if( *target )
92 efree( *target );
93
94 *target = dst_buf;
95 *target_len = dst_len;
96 }
97 /* }}} */
98
99 /* {{{ intl_convert_utf16_to_utf8
100 * Convert given string from UTF-16 to UTF-8.
101 *
102 * @param target Where to place the result.
103 * @param target_len Result length.
104 * @param source String to convert.
105 * @param source_len Length of the source string.
106 * @param status Conversion status.
107 *
108 * @return void This function does not return anything.
109 */
intl_convert_utf16_to_utf8(char ** target,int * target_len,const UChar * src,int src_len,UErrorCode * status)110 void intl_convert_utf16_to_utf8(
111 char** target, int* target_len,
112 const UChar* src, int src_len,
113 UErrorCode* status )
114 {
115 char* dst_buf = NULL;
116 int32_t dst_len;
117
118 /* Determine required destination buffer size (pre-flighting). */
119 *status = U_ZERO_ERROR;
120 u_strToUTF8( NULL, 0, &dst_len, src, src_len, status );
121
122 /* Bail out if an unexpected error occurred.
123 * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough).
124 * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty).
125 */
126 if( *status != U_BUFFER_OVERFLOW_ERROR && *status != U_STRING_NOT_TERMINATED_WARNING )
127 return;
128
129 /* Allocate memory for the destination buffer (it will be zero-terminated). */
130 dst_buf = emalloc( dst_len+1 );
131
132 /* Convert source string from UTF-8 to UTF-16. */
133 *status = U_ZERO_ERROR;
134 u_strToUTF8( dst_buf, dst_len, NULL, src, src_len, status );
135 if( U_FAILURE( *status ) )
136 {
137 efree( dst_buf );
138 return;
139 }
140
141 /* U_STRING_NOT_TERMINATED_WARNING is OK for us => reset 'status'. */
142 *status = U_ZERO_ERROR;
143
144 dst_buf[dst_len] = 0;
145 *target = dst_buf;
146 *target_len = dst_len;
147 }
148 /* }}} */
149
150 /*
151 * Local variables:
152 * tab-width: 4
153 * c-basic-offset: 4
154 * End:
155 * vim600: noet sw=4 ts=4 fdm=marker
156 * vim<600: noet sw=4 ts=4
157 */
158