Back to index

php5  5.3.10
formatter_parse.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | This source file is subject to version 3.01 of the PHP license,      |
00006    | that is bundled with this package in the file LICENSE, and is        |
00007    | available through the world-wide-web at the following url:           |
00008    | http://www.php.net/license/3_01.txt                                  |
00009    | If you did not receive a copy of the PHP license and are unable to   |
00010    | obtain it through the world-wide-web, please send a note to          |
00011    | license@php.net so we can mail you a copy immediately.               |
00012    +----------------------------------------------------------------------+
00013    | Authors: Stanislav Malyshev <stas@zend.com>                          |
00014    +----------------------------------------------------------------------+
00015  */
00016 
00017 #ifdef HAVE_CONFIG_H
00018 #include "config.h"
00019 #endif
00020 
00021 #include <unicode/ustring.h>
00022 #include <locale.h>
00023 
00024 #include "php_intl.h"
00025 #include "formatter_class.h"
00026 #include "formatter_format.h"
00027 #include "formatter_parse.h"
00028 #include "intl_convert.h"
00029 
00030 #define ICU_LOCALE_BUG 1
00031 
00032 /* {{{ proto mixed NumberFormatter::parse( string $str[, int $type, int &$position ])
00033  * Parse a number. }}} */
00034 /* {{{ proto mixed numfmt_parse( NumberFormatter $nf, string $str[, int $type, int &$position ])
00035  * Parse a number.
00036  */
00037 PHP_FUNCTION( numfmt_parse )
00038 {
00039        long type = FORMAT_TYPE_DOUBLE;
00040        UChar* sstr = NULL;
00041        int sstr_len = 0;
00042        char* str = NULL;
00043        int str_len;
00044        int32_t val32, position = 0;
00045        int64_t val64;
00046        double val_double;
00047        int32_t* position_p = NULL;
00048        zval *zposition = NULL;
00049        char *oldlocale;
00050        FORMATTER_METHOD_INIT_VARS;
00051 
00052        /* Parse parameters. */
00053        if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|lz!",
00054               &object, NumberFormatter_ce_ptr,  &str, &str_len, &type, &zposition ) == FAILURE )
00055        {
00056               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
00057                      "number_parse: unable to parse input params", 0 TSRMLS_CC );
00058 
00059               RETURN_FALSE;
00060        }
00061 
00062        /* Fetch the object. */
00063        FORMATTER_METHOD_FETCH_OBJECT;
00064 
00065        /* Convert given string to UTF-16. */
00066        intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo));
00067        INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" );
00068 
00069        if(zposition) {
00070               convert_to_long(zposition);
00071               position = (int32_t)Z_LVAL_P( zposition );
00072               position_p = &position;
00073        }
00074 
00075 #if ICU_LOCALE_BUG && defined(LC_NUMERIC)
00076        oldlocale = setlocale(LC_NUMERIC, "C");
00077 #endif
00078 
00079        switch(type) {
00080               case FORMAT_TYPE_INT32:
00081                      val32 = unum_parse(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
00082                      RETVAL_LONG(val32);
00083                      break;
00084               case FORMAT_TYPE_INT64:
00085                      val64 = unum_parseInt64(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
00086                      if(val64 > LONG_MAX || val64 < -LONG_MAX) {
00087                             RETVAL_DOUBLE(val64);
00088                      } else {
00089                             val32 = (int32_t)val64;
00090                             RETVAL_LONG(val32);
00091                      }
00092                      break;
00093               case FORMAT_TYPE_DOUBLE:
00094                      val_double = unum_parseDouble(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
00095                      RETVAL_DOUBLE(val_double);
00096                      break;
00097               default:
00098                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported format type %ld", type);
00099                      RETVAL_FALSE;
00100                      break;
00101        }
00102 #if ICU_LOCALE_BUG && defined(LC_NUMERIC)
00103        setlocale(LC_NUMERIC, oldlocale);
00104 #endif
00105        if(zposition) {
00106               zval_dtor(zposition);
00107               ZVAL_LONG(zposition, position);
00108        }
00109 
00110        if (sstr) {
00111               efree(sstr);
00112        }
00113 
00114        INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" );
00115 }
00116 /* }}} */
00117 
00118 /* {{{ proto double NumberFormatter::parseCurrency( string $str, string $&currency[, int $&position] )
00119  * Parse a number as currency. }}} */
00120 /* {{{ proto double numfmt_parse_currency( NumberFormatter $nf, string $str, string $&currency[, int $&position] )
00121  * Parse a number as currency.
00122  */
00123 PHP_FUNCTION( numfmt_parse_currency )
00124 {
00125        double number;
00126        UChar currency[5] = {0};
00127        UChar* sstr = NULL;
00128        int sstr_len = 0;
00129        char *currency_str = NULL;
00130        int currency_len = 0;
00131        char *str;
00132        int str_len;
00133        int32_t* position_p = NULL;
00134        int32_t position = 0;
00135        zval *zcurrency, *zposition = NULL;
00136        FORMATTER_METHOD_INIT_VARS;
00137 
00138        /* Parse parameters. */
00139        if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osz|z!",
00140               &object, NumberFormatter_ce_ptr,  &str, &str_len, &zcurrency, &zposition ) == FAILURE )
00141        {
00142               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
00143                      "number_parse_currency: unable to parse input params", 0 TSRMLS_CC );
00144 
00145               RETURN_FALSE;
00146        }
00147 
00148        /* Fetch the object. */
00149        FORMATTER_METHOD_FETCH_OBJECT;
00150 
00151        /* Convert given string to UTF-16. */
00152        intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo));
00153        INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" );
00154 
00155        if(zposition) {
00156               convert_to_long(zposition);
00157               position = (int32_t)Z_LVAL_P( zposition );
00158               position_p = &position;
00159        }
00160 
00161        number = unum_parseDoubleCurrency(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, currency, &INTL_DATA_ERROR_CODE(nfo));
00162        if(zposition) {
00163               zval_dtor(zposition);
00164               ZVAL_LONG(zposition, position);
00165        }
00166        if (sstr) {
00167               efree(sstr);
00168        }
00169        INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" );
00170 
00171        /* Convert parsed currency to UTF-8 and pass it back to caller. */
00172        intl_convert_utf16_to_utf8(&currency_str, &currency_len, currency, u_strlen(currency), &INTL_DATA_ERROR_CODE(nfo));
00173        INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-8 failed" );
00174        zval_dtor( zcurrency );
00175        ZVAL_STRINGL(zcurrency, currency_str, currency_len, 0);
00176 
00177        RETVAL_DOUBLE( number );
00178 }
00179 /* }}} */
00180 
00181 /*
00182  * Local variables:
00183  * tab-width: 4
00184  * c-basic-offset: 4
00185  * End:
00186  * vim600: noet sw=4 ts=4 fdm=marker
00187  * vim<600: noet sw=4 ts=4
00188  */