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: Gustavo Lopes <cataphract@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17 /* $Id$ */
18
19 #include "intl_cppshims.h"
20
21 #include "intl_convertcpp.h"
22 #include <unicode/ustring.h>
23 extern "C" {
24 #include <php.h>
25 }
26
27 /* {{{ intl_stringFromChar */
intl_stringFromChar(UnicodeString & ret,char * str,int32_t str_len,UErrorCode * status)28 int intl_stringFromChar(UnicodeString &ret, char *str, int32_t str_len, UErrorCode *status)
29 {
30 //the number of UTF-16 code units is not larger than that of UTF-8 code
31 //units, + 1 for the terminator
32 int32_t capacity = str_len + 1;
33
34 //no check necessary -- if NULL will fail ahead
35 UChar *utf16 = ret.getBuffer(capacity);
36 int32_t utf16_len = 0;
37 *status = U_ZERO_ERROR;
38 u_strFromUTF8WithSub(utf16, ret.getCapacity(), &utf16_len,
39 str, str_len, U_SENTINEL /* no substitution */, NULL,
40 status);
41 ret.releaseBuffer(utf16_len);
42 if (U_FAILURE(*status)) {
43 ret.setToBogus();
44 return FAILURE;
45 }
46 return SUCCESS;
47 }
48 /* }}} */
49
50 /* {{{ intl_charFromString
51 * faster than doing intl_convert_utf16_to_utf8(&res, &res_len,
52 * from.getBuffer(), from.length(), &status),
53 * but consumes more memory */
intl_charFromString(const UnicodeString & from,char ** res,int * res_len,UErrorCode * status)54 int intl_charFromString(const UnicodeString &from, char **res, int *res_len, UErrorCode *status)
55 {
56 if (from.isBogus()) {
57 return FAILURE;
58 }
59
60 //the number of UTF-8 code units is not larger than that of UTF-16 code
61 //units * 3 + 1 for the terminator
62 int32_t capacity = from.length() * 3 + 1;
63
64 if (from.isEmpty()) {
65 *res = (char*)emalloc(1);
66 **res = '\0';
67 *res_len = 0;
68 return SUCCESS;
69 }
70
71 *res = (char*)emalloc(capacity);
72 *res_len = 0; //tbd
73
74 const UChar *utf16buf = from.getBuffer();
75 int32_t actual_len;
76 u_strToUTF8WithSub(*res, capacity - 1, &actual_len, utf16buf, from.length(),
77 U_SENTINEL, NULL, status);
78
79 if (U_FAILURE(*status)) {
80 efree(*res);
81 *res = NULL;
82 return FAILURE;
83 }
84 (*res)[actual_len] = '\0';
85 *res_len = (int)actual_len;
86
87 return SUCCESS;
88 }
89 /* }}} */
90