root/ext/intl/msgformat/msgformat_format.c

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

DEFINITIONS

This source file includes following definitions.
  1. msgfmt_do_format
  2. PHP_FUNCTION
  3. 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 
  23 #include "php_intl.h"
  24 #include "msgformat_class.h"
  25 #include "msgformat_format.h"
  26 #include "msgformat_data.h"
  27 #include "msgformat_helpers.h"
  28 #include "intl_convert.h"
  29 
  30 #ifndef Z_ADDREF_P
  31 #define Z_ADDREF_P(z) ((z)->refcount++)
  32 #endif
  33 
  34 /* {{{ */
  35 static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *return_value)
  36 {
  37         int count;
  38         UChar* formatted = NULL;
  39         int32_t formatted_len = 0;
  40         HashTable *args_copy;
  41 
  42         count = zend_hash_num_elements(Z_ARRVAL_P(args));
  43 
  44         ALLOC_HASHTABLE(args_copy);
  45         zend_hash_init(args_copy, count, NULL, ZVAL_PTR_DTOR, 0);
  46         zend_hash_copy(args_copy, Z_ARRVAL_P(args), (copy_ctor_func_t)zval_add_ref);
  47 
  48         umsg_format_helper(mfo, args_copy, &formatted, &formatted_len);
  49 
  50         zend_hash_destroy(args_copy);
  51         efree(args_copy);
  52 
  53         if (formatted && U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
  54                         efree(formatted);
  55         }
  56 
  57         if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
  58                 RETURN_FALSE;
  59         } else {
  60                 INTL_METHOD_RETVAL_UTF8(mfo, formatted, formatted_len, 1);
  61         }
  62 }
  63 /* }}} */
  64 
  65 /* {{{ proto mixed MessageFormatter::format( array $args )
  66  * Format a message. }}} */
  67 /* {{{ proto mixed msgfmt_format( MessageFormatter $nf, array $args )
  68  * Format a message.
  69  */
  70 PHP_FUNCTION( msgfmt_format )
  71 {
  72         zval *args;
  73         MSG_FORMAT_METHOD_INIT_VARS;
  74 
  75 
  76         /* Parse parameters. */
  77         if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa",
  78                 &object, MessageFormatter_ce_ptr,  &args ) == FAILURE )
  79         {
  80                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
  81                         "msgfmt_format: unable to parse input params", 0 );
  82 
  83                 RETURN_FALSE;
  84         }
  85 
  86         /* Fetch the object. */
  87         MSG_FORMAT_METHOD_FETCH_OBJECT;
  88 
  89         msgfmt_do_format(mfo, args, return_value);
  90 }
  91 /* }}} */
  92 
  93 /* {{{ proto mixed MessageFormatter::formatMessage( string $locale, string $pattern, array $args )
  94  * Format a message. }}} */
  95 /* {{{ proto mixed msgfmt_format_message( string $locale, string $pattern, array $args )
  96  * Format a message.
  97  */
  98 PHP_FUNCTION( msgfmt_format_message )
  99 {
 100         zval       *args;
 101         UChar      *spattern = NULL;
 102         int         spattern_len = 0;
 103         char       *pattern = NULL;
 104         size_t      pattern_len = 0;
 105         const char *slocale = NULL;
 106         size_t      slocale_len = 0;
 107         MessageFormatter_object mf;
 108         MessageFormatter_object *mfo = &mf;
 109 
 110         /* Parse parameters. */
 111         if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "ssa",
 112                   &slocale, &slocale_len, &pattern, &pattern_len, &args ) == FAILURE )
 113         {
 114                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
 115                         "msgfmt_format_message: unable to parse input params", 0 );
 116 
 117                 RETURN_FALSE;
 118         }
 119 
 120         memset(mfo, 0, sizeof(*mfo));
 121         msgformat_data_init(&mfo->mf_data);
 122 
 123         if(pattern && pattern_len) {
 124                 intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo));
 125                 if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) )
 126                 {
 127                         intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
 128                                 "msgfmt_format_message: error converting pattern to UTF-16", 0 );
 129                         RETURN_FALSE;
 130                 }
 131         } else {
 132                 spattern_len = 0;
 133                 spattern = NULL;
 134         }
 135 
 136         if(slocale_len == 0) {
 137                 slocale = intl_locale_get_default();
 138         }
 139 
 140 #ifdef MSG_FORMAT_QUOTE_APOS
 141         if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) {
 142                 intl_error_set( NULL, U_INVALID_FORMAT_ERROR,
 143                         "msgfmt_format_message: error converting pattern to quote-friendly format", 0 );
 144                 RETURN_FALSE;
 145         }
 146 #endif
 147 
 148         /* Create an ICU message formatter. */
 149         MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, NULL, &INTL_DATA_ERROR_CODE(mfo));
 150         if(spattern && spattern_len) {
 151                 efree(spattern);
 152         }
 153         INTL_METHOD_CHECK_STATUS(mfo, "Creating message formatter failed");
 154 
 155         msgfmt_do_format(mfo, args, return_value);
 156 
 157         /* drop the temporary formatter */
 158         msgformat_data_free(&mfo->mf_data);
 159 }
 160 /* }}} */
 161 
 162 /*
 163  * Local variables:
 164  * tab-width: 4
 165  * c-basic-offset: 4
 166  * End:
 167  * vim600: noet sw=4 ts=4 fdm=marker
 168  * vim<600: noet sw=4 ts=4
 169  */

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