PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/intl/breakiterator - breakiterator_iterators.cpp (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 0 136 0.0 %
Date: 2014-04-16 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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: Gustavo Lopes <cataphract@php.net>                          |
      14             :    +----------------------------------------------------------------------+
      15             : */
      16             : 
      17             : #ifdef HAVE_CONFIG_H
      18             : #include "config.h"
      19             : #endif
      20             : 
      21             : #include <unicode/brkiter.h>
      22             : 
      23             : #include "breakiterator_iterators.h"
      24             : #include "../common/common_enum.h"
      25             : 
      26             : extern "C" {
      27             : #define USE_BREAKITERATOR_POINTER
      28             : #include "breakiterator_class.h"
      29             : #include "../intl_convert.h"
      30             : #include "../locale/locale.h"
      31             : #include <zend_exceptions.h>
      32             : }
      33             : 
      34             : static zend_class_entry *IntlPartsIterator_ce_ptr;
      35             : static zend_object_handlers IntlPartsIterator_handlers;
      36             : 
      37             : /* BreakIterator's iterator */
      38             : 
      39           0 : inline BreakIterator *_breakiter_prolog(zend_object_iterator *iter TSRMLS_DC)
      40             : {
      41             :         BreakIterator_object *bio;
      42             :         bio = (BreakIterator_object*)zend_object_store_get_object(
      43           0 :                         (const zval*)iter->data TSRMLS_CC);
      44           0 :         intl_errors_reset(BREAKITER_ERROR_P(bio) TSRMLS_CC);
      45           0 :         if (bio->biter == NULL) {
      46             :                 intl_errors_set(BREAKITER_ERROR_P(bio), U_INVALID_STATE_ERROR,
      47             :                         "The BreakIterator object backing the PHP iterator is not "
      48           0 :                         "properly constructed", 0 TSRMLS_CC);
      49             :         }
      50           0 :         return bio->biter;
      51             : }
      52             : 
      53           0 : static void _breakiterator_destroy_it(zend_object_iterator *iter TSRMLS_DC)
      54             : {
      55           0 :         zval_ptr_dtor((zval**)&iter->data);
      56           0 : }
      57             : 
      58           0 : static void _breakiterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
      59             : {
      60           0 :         BreakIterator *biter = _breakiter_prolog(iter TSRMLS_CC);
      61           0 :         zoi_with_current *zoi_iter = (zoi_with_current*)iter;
      62             : 
      63           0 :         iter->funcs->invalidate_current(iter TSRMLS_CC);
      64             : 
      65           0 :         if (biter == NULL) {
      66           0 :                 return;
      67             :         }
      68             : 
      69           0 :         int32_t pos = biter->next();
      70           0 :         if (pos != BreakIterator::DONE) {
      71           0 :                 MAKE_STD_ZVAL(zoi_iter->current);
      72           0 :                 ZVAL_LONG(zoi_iter->current, (long)pos);
      73             :         } //else we've reached the end of the enum, nothing more is required
      74             : }
      75             : 
      76           0 : static void _breakiterator_rewind(zend_object_iterator *iter TSRMLS_DC)
      77             : {
      78           0 :         BreakIterator *biter = _breakiter_prolog(iter TSRMLS_CC);
      79           0 :         zoi_with_current *zoi_iter = (zoi_with_current*)iter;
      80             : 
      81           0 :         int32_t pos = biter->first();
      82           0 :         MAKE_STD_ZVAL(zoi_iter->current);
      83           0 :         ZVAL_LONG(zoi_iter->current, (long)pos);
      84           0 : }
      85             : 
      86             : static zend_object_iterator_funcs breakiterator_iterator_funcs = {
      87             :         zoi_with_current_dtor,
      88             :         zoi_with_current_valid,
      89             :         zoi_with_current_get_current_data,
      90             :         NULL,
      91             :         _breakiterator_move_forward,
      92             :         _breakiterator_rewind,
      93             :         zoi_with_current_invalidate_current
      94             : };
      95             : 
      96           0 : U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
      97             :         zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
      98             : {
      99             :         BreakIterator_object *bio;
     100           0 :         if (by_ref) {
     101             :                 zend_throw_exception(NULL,
     102           0 :                         "Iteration by reference is not supported", 0 TSRMLS_CC);
     103           0 :                 return NULL;
     104             :         }
     105             : 
     106           0 :         bio = (BreakIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
     107           0 :         BreakIterator *biter = bio->biter;
     108             : 
     109           0 :         if (biter == NULL) {
     110             :                 zend_throw_exception(NULL,
     111           0 :                         "The BreakIterator is not properly constructed", 0 TSRMLS_CC);
     112           0 :                 return NULL;
     113             :         }
     114             : 
     115             :         zoi_with_current *zoi_iter =
     116           0 :                 static_cast<zoi_with_current*>(emalloc(sizeof *zoi_iter));
     117           0 :         zoi_iter->zoi.data = static_cast<void*>(object);
     118           0 :         zoi_iter->zoi.funcs = &breakiterator_iterator_funcs;
     119           0 :         zoi_iter->zoi.index = 0;
     120           0 :         zoi_iter->destroy_it = _breakiterator_destroy_it;
     121           0 :         zoi_iter->wrapping_obj = NULL; /* not used; object is in zoi.data */
     122           0 :         zoi_iter->current = NULL;
     123             : 
     124           0 :         zval_add_ref(&object);
     125             : 
     126           0 :         return reinterpret_cast<zend_object_iterator *>(zoi_iter);
     127             : }
     128             : 
     129             : /* BreakIterator parts iterator */
     130             : 
     131             : typedef struct zoi_break_iter_parts {
     132             :         zoi_with_current zoi_cur;
     133             :         parts_iter_key_type key_type;
     134             :         BreakIterator_object *bio; /* so we don't have to fetch it all the time */
     135             : } zoi_break_iter_parts;
     136             : 
     137           0 : static void _breakiterator_parts_destroy_it(zend_object_iterator *iter TSRMLS_DC)
     138             : {
     139           0 :         zval_ptr_dtor(reinterpret_cast<zval**>(&iter->data));
     140           0 : }
     141             : 
     142           0 : static void _breakiterator_parts_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
     143             : {
     144             :         /* the actual work is done in move_forward and rewind */
     145           0 :         ZVAL_LONG(key, iter->index);
     146           0 : }
     147             : 
     148           0 : static void _breakiterator_parts_move_forward(zend_object_iterator *iter TSRMLS_DC)
     149             : {
     150           0 :         zoi_break_iter_parts *zoi_bit = (zoi_break_iter_parts*)iter;
     151           0 :         BreakIterator_object *bio = zoi_bit->bio;
     152             : 
     153           0 :         iter->funcs->invalidate_current(iter TSRMLS_CC);
     154             : 
     155             :         int32_t cur,
     156             :                         next;
     157             : 
     158           0 :         cur = bio->biter->current();
     159           0 :         if (cur == BreakIterator::DONE) {
     160           0 :                 return;
     161             :         }
     162           0 :         next = bio->biter->next();
     163           0 :         if (next == BreakIterator::DONE) {
     164           0 :                 return;
     165             :         }
     166             : 
     167           0 :         if (zoi_bit->key_type == PARTS_ITERATOR_KEY_LEFT) {
     168           0 :                 iter->index = cur;
     169           0 :         } else if (zoi_bit->key_type == PARTS_ITERATOR_KEY_RIGHT) {
     170           0 :                 iter->index = next;
     171             :         }
     172             :         /* else zoi_bit->key_type == PARTS_ITERATOR_KEY_SEQUENTIAL
     173             :          * No need to do anything, the engine increments ->index */
     174             : 
     175           0 :         const char      *s = Z_STRVAL_P(bio->text);
     176           0 :         int32_t         slen = Z_STRLEN_P(bio->text),
     177             :                                 len;
     178             :         char            *res;
     179             : 
     180           0 :         if (next == BreakIterator::DONE) {
     181           0 :                 next = slen;
     182             :         }
     183             :         assert(next <= slen && next >= cur);
     184           0 :         len = next - cur;
     185           0 :         res = static_cast<char*>(emalloc(len + 1));
     186             : 
     187           0 :         memcpy(res, &s[cur], len);
     188           0 :         res[len] = '\0';
     189             : 
     190           0 :         MAKE_STD_ZVAL(zoi_bit->zoi_cur.current);
     191           0 :         ZVAL_STRINGL(zoi_bit->zoi_cur.current, res, len, 0);
     192             : }
     193             : 
     194           0 : static void _breakiterator_parts_rewind(zend_object_iterator *iter TSRMLS_DC)
     195             : {
     196           0 :         zoi_break_iter_parts *zoi_bit = (zoi_break_iter_parts*)iter;
     197           0 :         BreakIterator_object *bio = zoi_bit->bio;
     198             : 
     199           0 :         if (zoi_bit->zoi_cur.current) {
     200           0 :                 iter->funcs->invalidate_current(iter TSRMLS_CC);
     201             :         }
     202             : 
     203           0 :         bio->biter->first();
     204             : 
     205           0 :         iter->funcs->move_forward(iter TSRMLS_CC);
     206           0 : }
     207             : 
     208             : static zend_object_iterator_funcs breakiterator_parts_it_funcs = {
     209             :         zoi_with_current_dtor,
     210             :         zoi_with_current_valid,
     211             :         zoi_with_current_get_current_data,
     212             :         _breakiterator_parts_get_current_key,
     213             :         _breakiterator_parts_move_forward,
     214             :         _breakiterator_parts_rewind,
     215             :         zoi_with_current_invalidate_current
     216             : };
     217             : 
     218           0 : void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
     219             :                                                                                    zval *object,
     220             :                                                                                    parts_iter_key_type key_type TSRMLS_DC)
     221             : {
     222             :         IntlIterator_object *ii;
     223             : 
     224           0 :         zval_add_ref(&break_iter_zv);
     225             : 
     226           0 :         object_init_ex(object, IntlPartsIterator_ce_ptr);
     227           0 :         ii = (IntlIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
     228             : 
     229           0 :         ii->iterator = (zend_object_iterator*)emalloc(sizeof(zoi_break_iter_parts));
     230           0 :         ii->iterator->data = break_iter_zv;
     231           0 :         ii->iterator->funcs = &breakiterator_parts_it_funcs;
     232           0 :         ii->iterator->index = 0;
     233           0 :         ((zoi_with_current*)ii->iterator)->destroy_it = _breakiterator_parts_destroy_it;
     234           0 :         ((zoi_with_current*)ii->iterator)->wrapping_obj = object;
     235           0 :         ((zoi_with_current*)ii->iterator)->current = NULL;
     236             : 
     237             :         ((zoi_break_iter_parts*)ii->iterator)->bio = (BreakIterator_object*)
     238           0 :                 zend_object_store_get_object(break_iter_zv TSRMLS_CC);
     239             :         assert(((zoi_break_iter_parts*)ii->iterator)->bio->biter != NULL);
     240           0 :         ((zoi_break_iter_parts*)ii->iterator)->key_type = key_type;
     241           0 : }
     242             : 
     243           0 : U_CFUNC zend_object_value IntlPartsIterator_object_create(zend_class_entry *ce TSRMLS_DC)
     244             : {
     245             :         zend_object_value               retval;
     246             : 
     247           0 :         retval = IntlIterator_ce_ptr->create_object(ce TSRMLS_CC);
     248           0 :         retval.handlers = &IntlPartsIterator_handlers;
     249             : 
     250           0 :         return retval;
     251             : }
     252             : 
     253           0 : U_CFUNC zend_function *IntlPartsIterator_get_method(zval **object_ptr,
     254             :                 char *method, int method_len, const zend_literal *key TSRMLS_DC)
     255             : {
     256           0 :         zend_literal local_literal = {0};
     257             :         zend_function *ret;
     258             :         ALLOCA_FLAG(use_heap)
     259             : 
     260           0 :         if (key == NULL) {
     261             :                 Z_STRVAL(local_literal.constant) = static_cast<char*>(
     262           0 :                                 do_alloca(method_len + 1, use_heap));
     263             :                 zend_str_tolower_copy(Z_STRVAL(local_literal.constant),
     264           0 :                                 method, method_len);
     265             :                 local_literal.hash_value = zend_hash_func(
     266           0 :                                 Z_STRVAL(local_literal.constant), method_len + 1);
     267           0 :                 key = &local_literal;
     268             :         }
     269             : 
     270           0 :         if ((key->hash_value & 0xFFFFFFFF) == 0xA2B486A1 /* hash of getrulestatus\0 */
     271             :                         && method_len == sizeof("getrulestatus") - 1
     272             :                         && memcmp("getrulestatus", Z_STRVAL(key->constant),        method_len) == 0) {
     273             :                 IntlIterator_object *obj = (IntlIterator_object*)
     274           0 :                                 zend_object_store_get_object(*object_ptr TSRMLS_CC);
     275           0 :                 if (obj->iterator && obj->iterator->data) {
     276           0 :                         zval *break_iter_zv = static_cast<zval*>(obj->iterator->data);
     277           0 :                         *object_ptr = break_iter_zv;
     278             :                         ret = Z_OBJ_HANDLER_P(break_iter_zv, get_method)(object_ptr,
     279           0 :                                         method, method_len, key TSRMLS_CC);
     280           0 :                         goto end;
     281             :                 }
     282             :         }
     283             : 
     284             :         ret = std_object_handlers.get_method(object_ptr,
     285           0 :                         method, method_len, key TSRMLS_CC);
     286             : 
     287             : end:
     288           0 :         if (key == &local_literal) {
     289           0 :                 free_alloca(Z_STRVAL(local_literal.constant), use_heap);
     290             :         }
     291             : 
     292           0 :         return ret;
     293             : }
     294             : 
     295           0 : U_CFUNC PHP_METHOD(IntlPartsIterator, getBreakIterator)
     296             : {
     297           0 :         INTLITERATOR_METHOD_INIT_VARS;
     298             : 
     299           0 :         if (zend_parse_parameters_none() == FAILURE) {
     300             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     301           0 :                         "IntlPartsIterator::getBreakIterator: bad arguments", 0 TSRMLS_CC);
     302           0 :                 return;
     303             :         }
     304             : 
     305           0 :         INTLITERATOR_METHOD_FETCH_OBJECT;
     306             : 
     307           0 :         zval *biter_zval = static_cast<zval*>(ii->iterator->data);
     308           0 :         RETURN_ZVAL(biter_zval, 1, 0);
     309             : }
     310             : 
     311             : ZEND_BEGIN_ARG_INFO_EX(ainfo_parts_it_void, 0, 0, 0)
     312             : ZEND_END_ARG_INFO()
     313             : 
     314             : static const zend_function_entry IntlPartsIterator_class_functions[] = {
     315             :         PHP_ME(IntlPartsIterator,       getBreakIterator,       ainfo_parts_it_void,    ZEND_ACC_PUBLIC)
     316             :         PHP_FE_END
     317             : };
     318             : 
     319           0 : U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D)
     320             : {
     321             :         zend_class_entry ce;
     322             : 
     323             :         /* Create and register 'BreakIterator' class. */
     324           0 :         INIT_CLASS_ENTRY(ce, "IntlPartsIterator", IntlPartsIterator_class_functions);
     325             :         IntlPartsIterator_ce_ptr = zend_register_internal_class_ex(&ce,
     326           0 :                         IntlIterator_ce_ptr, NULL TSRMLS_CC);
     327           0 :         IntlPartsIterator_ce_ptr->create_object = IntlPartsIterator_object_create;
     328             : 
     329             :         memcpy(&IntlPartsIterator_handlers, &IntlIterator_handlers,
     330           0 :                         sizeof IntlPartsIterator_handlers);
     331           0 :         IntlPartsIterator_handlers.get_method = IntlPartsIterator_get_method;
     332             : 
     333             : #define PARTSITER_DECL_LONG_CONST(name) \
     334             :         zend_declare_class_constant_long(IntlPartsIterator_ce_ptr, #name, \
     335             :                 sizeof(#name) - 1, PARTS_ITERATOR_ ## name TSRMLS_CC)
     336             : 
     337           0 :         PARTSITER_DECL_LONG_CONST(KEY_SEQUENTIAL);
     338           0 :         PARTSITER_DECL_LONG_CONST(KEY_LEFT);
     339           0 :         PARTSITER_DECL_LONG_CONST(KEY_RIGHT);
     340             : 
     341             : #undef PARTSITER_DECL_LONG_CONST
     342           0 : }

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:48 +0000 (7 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.