Annotation of embedaddon/php/ext/intl/msgformat/msgformat_helpers.cpp, revision 1.1.1.1
1.1 misho 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: Stanislav Malyshev <stas@zend.com> |
14: +----------------------------------------------------------------------+
15: */
16:
17: #ifdef HAVE_CONFIG_H
18: #include "config.h"
19: #endif
20:
21: #include <math.h>
22: #include <unicode/msgfmt.h>
23: #include <unicode/chariter.h>
24:
25: extern "C" {
26: #include "php_intl.h"
27: #include "msgformat_class.h"
28: #include "msgformat_format.h"
29: #include "msgformat_helpers.h"
30: #include "intl_convert.h"
31: }
32:
33: U_NAMESPACE_BEGIN
34: /**
35: * This class isolates our access to private internal methods of
36: * MessageFormat. It is never instantiated; it exists only for C++
37: * access management.
38: */
39: class MessageFormatAdapter {
40: public:
41: static const Formattable::Type* getArgTypeList(const MessageFormat& m,
42: int32_t& count);
43: };
44: const Formattable::Type*
45: MessageFormatAdapter::getArgTypeList(const MessageFormat& m,
46: int32_t& count) {
47: return m.getArgTypeList(count);
48: }
49: U_NAMESPACE_END
50:
51: U_CFUNC int32_t umsg_format_arg_count(UMessageFormat *fmt)
52: {
53: int32_t fmt_count = 0;
54: MessageFormatAdapter::getArgTypeList(*(const MessageFormat*)fmt, fmt_count);
55: return fmt_count;
56: }
57:
58: U_CFUNC void umsg_format_helper(UMessageFormat *fmt, int arg_count, zval **args, UChar **formatted, int *formatted_len, UErrorCode *status TSRMLS_DC)
59: {
60: int fmt_count = 0;
61: const Formattable::Type* argTypes =
62: MessageFormatAdapter::getArgTypeList(*(const MessageFormat*)fmt, fmt_count);
63: Formattable* fargs = new Formattable[fmt_count ? fmt_count : 1];
64:
65: for(int32_t i = 0; i < fmt_count; ++i) {
66: UChar *stringVal = NULL;
67: int stringLen = 0;
68: int64_t tInt64 = 0;
69:
70: switch(argTypes[i]) {
71: case Formattable::kDate:
72: convert_to_long_ex(&args[i]);
73: fargs[i].setDate(U_MILLIS_PER_SECOND * (double)Z_LVAL_P(args[i]));
74: break;
75:
76: case Formattable::kDouble:
77: convert_to_double_ex(&args[i]);
78: fargs[i].setDouble(Z_DVAL_P(args[i]));
79: break;
80:
81: case Formattable::kLong:
82: convert_to_long_ex(&args[i]);
83: fargs[i].setLong(Z_LVAL_P(args[i]));
84: break;
85:
86: case Formattable::kInt64:
87: if(Z_TYPE_P(args[i]) == IS_DOUBLE) {
88: tInt64 = (int64_t)Z_DVAL_P(args[i]);
89: } else if(Z_TYPE_P(args[i]) == IS_LONG) {
90: tInt64 = (int64_t)Z_LVAL_P(args[i]);
91: } else {
92: SEPARATE_ZVAL_IF_NOT_REF(&args[i]);
93: convert_scalar_to_number( args[i] TSRMLS_CC );
94: tInt64 = (Z_TYPE_P(args[i]) == IS_DOUBLE)?(int64_t)Z_DVAL_P(args[i]):Z_LVAL_P(args[i]);
95: }
96: fargs[i].setInt64(tInt64);
97: break;
98:
99: case Formattable::kString:
100: convert_to_string_ex(&args[i]);
101: intl_convert_utf8_to_utf16(&stringVal, &stringLen, Z_STRVAL_P(args[i]), Z_STRLEN_P(args[i]), status);
102: if(U_FAILURE(*status)){
103: delete[] fargs;
104: return;
105: }
106: fargs[i].setString(stringVal);
107: efree(stringVal);
108: break;
109:
110: case Formattable::kArray:
111: case Formattable::kObject:
112: *status = U_UNSUPPORTED_ERROR;
113: delete[] fargs;
114: return;
115: }
116: }
117:
118: UnicodeString resultStr;
119: FieldPosition fieldPosition(0);
120:
121: /* format the message */
122: ((const MessageFormat*)fmt)->format(fargs, fmt_count, resultStr, fieldPosition, *status);
123:
124: delete[] fargs;
125:
126: if(U_FAILURE(*status)){
127: return;
128: }
129:
130: *formatted_len = resultStr.length();
131: *formatted = eumalloc(*formatted_len+1);
132: resultStr.extract(*formatted, *formatted_len+1, *status);
133: }
134:
135: #define cleanup_zvals() for(int j=i;j>=0;j--) { zval_ptr_dtor((*args)+i); }
136:
137: U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args, UChar *source, int source_len, UErrorCode *status)
138: {
139: UnicodeString srcString(source, source_len);
140: Formattable *fargs = ((const MessageFormat*)fmt)->parse(srcString, *count, *status);
141:
142: if(U_FAILURE(*status)) {
143: return;
144: }
145:
146: *args = (zval **)safe_emalloc(*count, sizeof(zval *), 0);
147:
148: // assign formattables to varargs
149: for(int32_t i = 0; i < *count; i++) {
150: int64_t aInt64;
151: double aDate;
152: UnicodeString temp;
153: char *stmp;
154: int stmp_len;
155:
156: ALLOC_INIT_ZVAL((*args)[i]);
157:
158: switch(fargs[i].getType()) {
159: case Formattable::kDate:
160: aDate = ((double)fargs[i].getDate())/U_MILLIS_PER_SECOND;
161: if(aDate > LONG_MAX || aDate < -LONG_MAX) {
162: ZVAL_DOUBLE((*args)[i], aDate<0?ceil(aDate):floor(aDate));
163: } else {
164: ZVAL_LONG((*args)[i], (long)aDate);
165: }
166: break;
167:
168: case Formattable::kDouble:
169: ZVAL_DOUBLE((*args)[i], (double)fargs[i].getDouble());
170: break;
171:
172: case Formattable::kLong:
173: ZVAL_LONG((*args)[i], fargs[i].getLong());
174: break;
175:
176: case Formattable::kInt64:
177: aInt64 = fargs[i].getInt64();
178: if(aInt64 > LONG_MAX || aInt64 < -LONG_MAX) {
179: ZVAL_DOUBLE((*args)[i], (double)aInt64);
180: } else {
181: ZVAL_LONG((*args)[i], (long)aInt64);
182: }
183: break;
184:
185: case Formattable::kString:
186: fargs[i].getString(temp);
187: intl_convert_utf16_to_utf8(&stmp, &stmp_len, temp.getBuffer(), temp.length(), status);
188: if(U_FAILURE(*status)) {
189: cleanup_zvals();
190: return;
191: }
192: ZVAL_STRINGL((*args)[i], stmp, stmp_len, 0);
193: break;
194:
195: case Formattable::kObject:
196: case Formattable::kArray:
197: *status = U_ILLEGAL_ARGUMENT_ERROR;
198: cleanup_zvals();
199: break;
200: }
201: }
202: delete[] fargs;
203: }
204:
205: /*
206: * Local variables:
207: * tab-width: 4
208: * c-basic-offset: 4
209: * End:
210: * vim600: noet sw=4 ts=4 fdm=marker
211: * vim<600: noet sw=4 ts=4
212: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>