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 7                                                        |
   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         zend_long type = FORMAT_TYPE_DOUBLE;
  40         UChar* sstr = NULL;
  41         int32_t sstr_len = 0;
  42         char* str = NULL;
  43         size_t 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(), 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 );
  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                 ZVAL_DEREF(zposition);
  71                 convert_to_long(zposition);
  72                 position = (int32_t)Z_LVAL_P( zposition );
  73                 position_p = &position;
  74         }
  75 
  76 #if ICU_LOCALE_BUG && defined(LC_NUMERIC)
  77         /* need to copy here since setlocale may change it later */
  78         oldlocale = estrdup(setlocale(LC_NUMERIC, NULL));
  79         setlocale(LC_NUMERIC, "C");
  80 #endif
  81 
  82         switch(type) {
  83                 case FORMAT_TYPE_INT32:
  84                         val32 = unum_parse(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
  85                         RETVAL_LONG(val32);
  86                         break;
  87                 case FORMAT_TYPE_INT64:
  88                         val64 = unum_parseInt64(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
  89                         if(val64 > ZEND_LONG_MAX || val64 < ZEND_LONG_MIN) {
  90                                 RETVAL_DOUBLE(val64);
  91                         } else {
  92                                 RETVAL_LONG((zend_long)val64);
  93                         }
  94                         break;
  95                 case FORMAT_TYPE_DOUBLE:
  96                         val_double = unum_parseDouble(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo));
  97                         RETVAL_DOUBLE(val_double);
  98                         break;
  99                 default:
 100                         php_error_docref(NULL, E_WARNING, "Unsupported format type %pd", type);
 101                         RETVAL_FALSE;
 102                         break;
 103         }
 104 #if ICU_LOCALE_BUG && defined(LC_NUMERIC)
 105         setlocale(LC_NUMERIC, oldlocale);
 106         efree(oldlocale);
 107 #endif
 108         if(zposition) {
 109                 zval_dtor(zposition);
 110                 ZVAL_LONG(zposition, position);
 111         }
 112 
 113         if (sstr) {
 114                 efree(sstr);
 115         }
 116 
 117         INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" );
 118 }
 119 /* }}} */
 120 
 121 /* {{{ proto double NumberFormatter::parseCurrency( string $str, string $&currency[, int $&position] )
 122  * Parse a number as currency. }}} */
 123 /* {{{ proto double numfmt_parse_currency( NumberFormatter $nf, string $str, string $&currency[, int $&position] )
 124  * Parse a number as currency.
 125  */
 126 PHP_FUNCTION( numfmt_parse_currency )
 127 {
 128         double number;
 129         UChar currency[5] = {0};
 130         UChar* sstr = NULL;
 131         int32_t sstr_len = 0;
 132         zend_string *u8str;
 133         char *str;
 134         size_t 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(), 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 );
 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                 ZVAL_DEREF(zposition);
 159                 convert_to_long(zposition);
 160                 position = (int32_t)Z_LVAL_P( zposition );
 161                 position_p = &position;
 162         }
 163 
 164         number = unum_parseDoubleCurrency(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, currency, &INTL_DATA_ERROR_CODE(nfo));
 165         if(zposition) {
 166                 zval_dtor(zposition);
 167                 ZVAL_LONG(zposition, position);
 168         }
 169         if (sstr) {
 170                 efree(sstr);
 171         }
 172         INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" );
 173 
 174         /* Convert parsed currency to UTF-8 and pass it back to caller. */
 175         u8str = intl_convert_utf16_to_utf8(currency, u_strlen(currency), &INTL_DATA_ERROR_CODE(nfo));
 176         INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-8 failed" );
 177         zval_dtor( zcurrency );
 178         ZVAL_NEW_STR(zcurrency, u8str);
 179 
 180         RETVAL_DOUBLE( number );
 181 }
 182 /* }}} */
 183 
 184 /*
 185  * Local variables:
 186  * tab-width: 4
 187  * c-basic-offset: 4
 188  * End:
 189  * vim600: noet sw=4 ts=4 fdm=marker
 190  * vim<600: noet sw=4 ts=4
 191  */

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