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>