root/ext/intl/formatter/formatter_parse.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHP_FUNCTION
  2. PHP_FUNCTION

   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 <unicode/ustring.h>
  22 #include <locale.h>
  23 
  24 #include "php_intl.h"
  25 #include "formatter_class.h"
  26 #include "formatter_format.h"
  27 #include "formatter_parse.h"
  28 #include "intl_convert.h"
  29 
  30 #define ICU_LOCALE_BUG 1
  31 
  32 /* {{{ proto mixed NumberFormatter::parse( string $str[, int $type, int &$position ])
  33  * Parse a number. }}} */
  34 /* {{{ proto mixed numfmt_parse( NumberFormatter $nf, string $str[, int $type, int &$position ])
  35  * Parse a number.
  36  */
  37 PHP_FUNCTION( numfmt_parse )
  38 {
  39         long type = FORMAT_TYPE_DOUBLE;
  40         UChar* sstr = NULL;
  41         int sstr_len = 0;
  42         char* str = NULL;
  43         int str_len;
  44         int32_t val32, position = 0;
  45         int64_t val64;
  46         double val_double;
  47         int32_t* position_p = NULL;
  48         zval *zposition = NULL;
  49         char *oldlocale;
  50         FORMATTER_METHOD_INIT_VARS;
  51 
  52         /* Parse parameters. */
  53         if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|lz!",
  54                 &object, NumberFormatter_ce_ptr,  &str, &str_len, &type, &zposition ) == FAILURE )
  55         {
  56                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
  57                         "number_parse: unable to parse input params", 0 TSRMLS_CC );
  58 
  59                 RETURN_FALSE;
  60         }
  61 
  62         /* Fetch the object. */
  63         FORMATTER_METHOD_FETCH_OBJECT;
  64 
  65         /* Convert given string to UTF-16. */
  66         intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo));
  67         INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" );
  68 
  69         if(zposition) {
  70                 convert_to_long(zposition);
  71                 position = (int32_t)Z_LVAL_P( zposition );
  72                 position_p = &position;
  73         }
  74 
  75 #if ICU_LOCALE_BUG && defined(LC_NUMERIC)
  76         /* need to copy here since setlocale may change it later */
  77         oldlocale = estrdup(setlocale(LC_NUMERIC, NULL));
  78         setlocale(LC_NUMERIC, "C");
  79 #endif
  80 
  81         switch(type) {
  82                 case FORMAT_TYPE_INT32:
  83                         val32 = unum_parse(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
  84                         RETVAL_LONG(val32);
  85                         break;
  86                 case FORMAT_TYPE_INT64:
  87                         val64 = unum_parseInt64(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
  88                         if(val64 > LONG_MAX || val64 < LONG_MIN) {
  89                                 RETVAL_DOUBLE(val64);
  90                         } else {
  91                                 RETVAL_LONG((long)val64);
  92                         }
  93                         break;
  94                 case FORMAT_TYPE_DOUBLE:
  95                         val_double = unum_parseDouble(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
  96                         RETVAL_DOUBLE(val_double);
  97                         break;
  98                 default:
  99                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported format type %ld", type);
 100                         RETVAL_FALSE;
 101                         break;
 102         }
 103 #if ICU_LOCALE_BUG && defined(LC_NUMERIC)
 104         setlocale(LC_NUMERIC, oldlocale);
 105         efree(oldlocale);
 106 #endif
 107         if(zposition) {
 108                 zval_dtor(zposition);
 109                 ZVAL_LONG(zposition, position);
 110         }
 111 
 112         if (sstr) {
 113                 efree(sstr);
 114         }
 115 
 116         INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" );
 117 }
 118 /* }}} */
 119 
 120 /* {{{ proto double NumberFormatter::parseCurrency( string $str, string $&currency[, int $&position] )
 121  * Parse a number as currency. }}} */
 122 /* {{{ proto double numfmt_parse_currency( NumberFormatter $nf, string $str, string $&currency[, int $&position] )
 123  * Parse a number as currency.
 124  */
 125 PHP_FUNCTION( numfmt_parse_currency )
 126 {
 127         double number;
 128         UChar currency[5] = {0};
 129         UChar* sstr = NULL;
 130         int sstr_len = 0;
 131         char *currency_str = NULL;
 132         int currency_len = 0;
 133         char *str;
 134         int str_len;
 135         int32_t* position_p = NULL;
 136         int32_t position = 0;
 137         zval *zcurrency, *zposition = NULL;
 138         FORMATTER_METHOD_INIT_VARS;
 139 
 140         /* Parse parameters. */
 141         if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osz|z!",
 142                 &object, NumberFormatter_ce_ptr,  &str, &str_len, &zcurrency, &zposition ) == FAILURE )
 143         {
 144                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
 145                         "number_parse_currency: unable to parse input params", 0 TSRMLS_CC );
 146 
 147                 RETURN_FALSE;
 148         }
 149 
 150         /* Fetch the object. */
 151         FORMATTER_METHOD_FETCH_OBJECT;
 152 
 153         /* Convert given string to UTF-16. */
 154         intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo));
 155         INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" );
 156 
 157         if(zposition) {
 158                 convert_to_long(zposition);
 159                 position = (int32_t)Z_LVAL_P( zposition );
 160                 position_p = &position;
 161         }
 162 
 163         number = unum_parseDoubleCurrency(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, currency, &INTL_DATA_ERROR_CODE(nfo));
 164         if(zposition) {
 165                 zval_dtor(zposition);
 166                 ZVAL_LONG(zposition, position);
 167         }
 168         if (sstr) {
 169                 efree(sstr);
 170         }
 171         INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" );
 172 
 173         /* Convert parsed currency to UTF-8 and pass it back to caller. */
 174         intl_convert_utf16_to_utf8(&currency_str, &currency_len, currency, u_strlen(currency), &INTL_DATA_ERROR_CODE(nfo));
 175         INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-8 failed" );
 176         zval_dtor( zcurrency );
 177         ZVAL_STRINGL(zcurrency, currency_str, currency_len, 0);
 178 
 179         RETVAL_DOUBLE( number );
 180 }
 181 /* }}} */
 182 
 183 /*
 184  * Local variables:
 185  * tab-width: 4
 186  * c-basic-offset: 4
 187  * End:
 188  * vim600: noet sw=4 ts=4 fdm=marker
 189  * vim<600: noet sw=4 ts=4
 190  */

/* [<][>][^][v][top][bottom][index][help] */