andrei          Tue Feb  7 20:01:29 2006 UTC

  Modified files:              
    /php-src/ext/unicode        unicode_iterators.c 
  Log:
  Implement reverse iteration for codeunits and codepoints. Combining
  sequences are next.
  
  # This is ugly, though.
  # foreach (new TextIterator($a, # 
TextIterator::CODE_POINT|TextIterator::REVERSE) as $k => $c) {
  #    var_dump("$k: $c");
  # }
  # Any suggestions?
  
  
http://cvs.php.net/viewcvs.cgi/php-src/ext/unicode/unicode_iterators.c?r1=1.15&r2=1.16&diff_format=u
Index: php-src/ext/unicode/unicode_iterators.c
diff -u php-src/ext/unicode/unicode_iterators.c:1.15 
php-src/ext/unicode/unicode_iterators.c:1.16
--- php-src/ext/unicode/unicode_iterators.c:1.15        Tue Feb  7 00:13:54 2006
+++ php-src/ext/unicode/unicode_iterators.c     Tue Feb  7 20:01:28 2006
@@ -14,7 +14,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: unicode_iterators.c,v 1.15 2006/02/07 00:13:54 andrei Exp $ */
+/* $Id: unicode_iterators.c,v 1.16 2006/02/07 20:01:28 andrei Exp $ */
 
 /*
  * TODO
@@ -36,8 +36,8 @@
        ITER_TYPE_LAST,
 } text_iter_type;
 
-const uint32_t ITER_REVERSE = 0x100;
-const uint32_t ITER_TYPE_MASK = 0xFF;
+static const uint32_t ITER_REVERSE = 0x100;
+static const uint32_t ITER_TYPE_MASK = 0xFF;
 
 typedef struct {
        zend_object             std;
@@ -46,13 +46,14 @@
        text_iter_type  type;
        zval*                   current;
        size_t                  current_alloc;
+       long                    flags;
        union {
                struct {
                        uint32_t index;
                        uint32_t offset;
                } cp;
                struct {
-                       uint32_t index;
+                       int32_t index;
                } cu;
                struct {
                        uint32_t index;
@@ -82,7 +83,11 @@
 
 static int text_iter_cu_valid(text_iter_obj* object TSRMLS_DC)
 {
-       return (object->u.cu.index < object->text_len);
+       if (object->flags & ITER_REVERSE) {
+               return (object->u.cu.index >= 0);
+       } else {
+               return (object->u.cu.index < object->text_len);
+       }
 }
 
 static void text_iter_cu_current(text_iter_obj* object TSRMLS_DC)
@@ -94,17 +99,33 @@
 
 static int text_iter_cu_key(text_iter_obj* object TSRMLS_DC)
 {
-       return object->u.cu.index;
+       if (object->flags & ITER_REVERSE) {
+               return object->text_len - object->u.cu.index - 1;
+       } else {
+               return object->u.cu.index;
+       }
 }
 
 static void text_iter_cu_next(text_iter_obj* object TSRMLS_DC)
 {
-       object->u.cu.index++;
+       if (object->flags & ITER_REVERSE) {
+               if (object->u.cu.index >= 0) {
+                       object->u.cu.index--;
+               }
+       } else {
+               if (object->u.cu.index < object->text_len) {
+                       object->u.cu.index++;
+               }
+       }
 }
 
 static void text_iter_cu_rewind(text_iter_obj *object TSRMLS_DC)
 {
-       object->u.cu.index  = 0;
+       if (object->flags & ITER_REVERSE) {
+               object->u.cu.index = object->text_len-1;
+       } else {
+               object->u.cu.index = 0;
+       }
 }
 
 static text_iter_ops text_iter_cu_ops = {
@@ -119,7 +140,11 @@
 
 static int text_iter_cp_valid(text_iter_obj* object TSRMLS_DC)
 {
-       return (object->u.cp.offset < object->text_len);
+       if (object->flags & ITER_REVERSE) {
+               return (object->u.cp.offset > 0);
+       } else {
+               return (object->u.cp.offset < object->text_len);
+       }
 }
 
 static void text_iter_cp_current(text_iter_obj* object TSRMLS_DC)
@@ -128,7 +153,11 @@
        int32_t tmp, buf_len;
 
        tmp = object->u.cp.offset;
-       U16_NEXT(object->text, tmp, object->text_len, cp);
+       if (object->flags & ITER_REVERSE) {
+               U16_PREV(object->text, 0, tmp, cp);
+       } else {
+               U16_NEXT(object->text, tmp, object->text_len, cp);
+       }
        buf_len = zend_codepoint_to_uchar(cp, Z_USTRVAL_P(object->current));
        Z_USTRVAL_P(object->current)[buf_len] = 0;
        Z_USTRLEN_P(object->current) = buf_len;
@@ -141,13 +170,21 @@
 
 static void text_iter_cp_next(text_iter_obj* object TSRMLS_DC)
 {
-       U16_FWD_1(object->text, object->u.cp.offset, object->text_len);
+       if (object->flags & ITER_REVERSE) {
+               U16_BACK_1(object->text, 0, object->u.cp.offset);
+       } else {
+               U16_FWD_1(object->text, object->u.cp.offset, object->text_len);
+       }
        object->u.cp.index++;
 }
 
 static void text_iter_cp_rewind(text_iter_obj *object TSRMLS_DC)
 {
-       object->u.cp.offset = 0;
+       if (object->flags & ITER_REVERSE) {
+               object->u.cp.offset = object->text_len;
+       } else {
+               object->u.cp.offset = 0;
+       }
        object->u.cp.index  = 0;
 }
 
@@ -371,11 +408,12 @@
        intern->text_len = text_len;
        if (ZEND_NUM_ARGS() > 1) {
                ti_type = flags & ITER_TYPE_MASK;
-               if (flags < ITER_TYPE_LAST) { 
+               if (ti_type < ITER_TYPE_LAST) { 
                        intern->type = ti_type;
                } else {
                        php_error(E_WARNING, "Invalid iterator type in 
TextIterator constructor");
                }
+               intern->flags = flags;
        }
 
        iter_ops[intern->type]->rewind(intern TSRMLS_CC);
@@ -445,6 +483,8 @@
        zend_declare_class_constant_long(text_iterator_ce, "CODE_UNIT", 
sizeof("CODE_UNIT")-1, ITER_CODE_UNIT TSRMLS_CC);
        zend_declare_class_constant_long(text_iterator_ce, "CODE_POINT", 
sizeof("CODE_POINT")-1, ITER_CODE_POINT TSRMLS_CC);
        zend_declare_class_constant_long(text_iterator_ce, "COMB_SEQUENCE", 
sizeof("COMB_SEQUENCE")-1, ITER_COMB_SEQUENCE TSRMLS_CC);
+
+       zend_declare_class_constant_long(text_iterator_ce, "REVERSE", 
sizeof("REVERSE")-1, ITER_REVERSE TSRMLS_CC);
 }
 
 /*

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to