zoukankan      html  css  js  c++  java
  • php内置函数分析之current()、next()、prev()、reset()、end()

    1 current()初始指向插入到数组中的第一个单元
    2 next() 将数组的内部指针向前移动一位
    3 prev() 将数组的内部指针倒回一位
    4 reset() 将数组的内部指针指向第一个单元
    5 end() 将数组的内部指针指向最后一个单元

    current():

     1 PHP_FUNCTION(current)
     2 {
     3     HashTable *array;
     4     zval *entry;
     5 
     6 #ifndef FAST_ZPP
     7     if (zend_parse_parameters(ZEND_NUM_ARGS(), "H", &array) == FAILURE) {
     8         return;
     9     }
    10 #else
    11     ZEND_PARSE_PARAMETERS_START(1, 1)
    12         Z_PARAM_ARRAY_OR_OBJECT_HT(array)
    13     ZEND_PARSE_PARAMETERS_END();
    14 #endif
    15     // 获取内部指针指向的当前单元
    16     if ((entry = zend_hash_get_current_data(array)) == NULL) {
    17         RETURN_FALSE;
    18     }
    19 
    20     if (Z_TYPE_P(entry) == IS_INDIRECT) {
    21         entry = Z_INDIRECT_P(entry);
    22     }
    23 
    24     ZVAL_DEREF(entry);
    25     ZVAL_COPY(return_value, entry);
    26 }
    1 #define zend_hash_get_current_data(ht) 
    2     zend_hash_get_current_data_ex(ht, &(ht)->nInternalPointer)
     1 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
     2 {
     3     uint32_t idx = *pos;
     4     Bucket *p;
     5 
     6     IS_CONSISTENT(ht);
     7     if (idx != HT_INVALID_IDX) {
     8         p = ht->arData + idx; // 数组首地址加偏移量
     9         return &p->val;
    10     } else {
    11         return NULL;
    12     }
    13 }

    next():

     1 PHP_FUNCTION(next)
     2 {
     3     HashTable *array;
     4     zval *entry;
     5 
     6 #ifndef FAST_ZPP
     7     if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
     8         return;
     9     }
    10 #else
    11     ZEND_PARSE_PARAMETERS_START(1, 1)
    12         Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
    13     ZEND_PARSE_PARAMETERS_END();
    14 #endif
    15 
    16     // 向前移动指针
    17     zend_hash_move_forward(array);
    18 
    19     if (USED_RET()) {
    20         // 获取指针指向的单元
    21         if ((entry = zend_hash_get_current_data(array)) == NULL) {
    22             RETURN_FALSE;
    23         }
    24 
    25         if (Z_TYPE_P(entry) == IS_INDIRECT) {
    26             entry = Z_INDIRECT_P(entry);
    27         }
    28 
    29         ZVAL_DEREF(entry);
    30         ZVAL_COPY(return_value, entry);
    31     }
    32 }
    1 #define zend_hash_move_forward(ht) 
    2     zend_hash_move_forward_ex(ht, &(ht)->nInternalPointer)
     1 ZEND_API int ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
     2 {
     3     uint32_t idx = *pos;
     4 
     5     IS_CONSISTENT(ht);
     6     HT_ASSERT(&ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
     7 
     8     if (idx != HT_INVALID_IDX) {
     9         while (1) {
    10             idx++;
    11             if (idx >= ht->nNumUsed) { // 内部指针超出单元列表的末端(idx从0开始)
    12                 *pos = HT_INVALID_IDX; // 保存内部指针为HT_INVALID_IDX
    13                 return SUCCESS;
    14             }
    15             if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) { // 内部指针向前移动后,指向的是有效元素
    16                 *pos = idx; // 保存内部指针
    17                 return SUCCESS;
    18             }
    19         }
    20     } else {
    21          return FAILURE;
    22     }
    23 }

    prev():

     1 PHP_FUNCTION(prev)
     2 {
     3     HashTable *array;
     4     zval *entry;
     5 
     6 #ifndef FAST_ZPP
     7     if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
     8         return;
     9     }
    10 #else
    11     ZEND_PARSE_PARAMETERS_START(1, 1)
    12         Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
    13     ZEND_PARSE_PARAMETERS_END();
    14 #endif
    15     // 内部指针倒回一位
    16     zend_hash_move_backwards(array);
    17 
    18     if (USED_RET()) {
    19         // 获取当前指针指向的单元
    20         if ((entry = zend_hash_get_current_data(array)) == NULL) {
    21             RETURN_FALSE;
    22         }
    23 
    24         if (Z_TYPE_P(entry) == IS_INDIRECT) {
    25             entry = Z_INDIRECT_P(entry);
    26         }
    27 
    28         ZVAL_DEREF(entry);
    29         ZVAL_COPY(return_value, entry);
    30     }
    31 }
    1 #define zend_hash_move_backwards(ht) 
    2     zend_hash_move_backwards_ex(ht, &(ht)->nInternalPointer)
     1 ZEND_API int ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
     2 {
     3     uint32_t idx = *pos;
     4 
     5     IS_CONSISTENT(ht);
     6     HT_ASSERT(&ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
     7 
     8     if (idx != HT_INVALID_IDX) {
     9         while (idx > 0) {
    10             idx--;
    11             if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) { // 内部指针指向的单元有效
    12                 *pos = idx;
    13                 return SUCCESS;
    14             }
    15         }
    16         // 指针倒回一位后没有找到有效的单元
    17         *pos = HT_INVALID_IDX;
    18          return SUCCESS;
    19     } else {
    20          return FAILURE;
    21     }
    22 }

    reset():

     1 PHP_FUNCTION(reset)
     2 {
     3     HashTable *array;
     4     zval *entry;
     5 
     6 #ifndef FAST_ZPP
     7     if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
     8         return;
     9     }
    10 #else
    11     ZEND_PARSE_PARAMETERS_START(1, 1)
    12         Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
    13     ZEND_PARSE_PARAMETERS_END();
    14 #endif
    15 
    16     // 将内部指针指向第一个单元
    17     zend_hash_internal_pointer_reset(array);
    18 
    19     if (USED_RET()) {
    20         if ((entry = zend_hash_get_current_data(array)) == NULL) {
    21             RETURN_FALSE;
    22         }
    23 
    24         if (Z_TYPE_P(entry) == IS_INDIRECT) {
    25             entry = Z_INDIRECT_P(entry);
    26         }
    27 
    28         ZVAL_DEREF(entry);
    29         ZVAL_COPY(return_value, entry);
    30     }
    31 }
    1 #define zend_hash_internal_pointer_reset(ht) 
    2     zend_hash_internal_pointer_reset_ex(ht, &(ht)->nInternalPointer)
     1 ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
     2 {
     3     uint32_t idx;
     4 
     5     IS_CONSISTENT(ht);
     6     HT_ASSERT(&ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
     7 
     8     // 内部指针指向数组的一个第一个有效单元
     9     for (idx = 0; idx < ht->nNumUsed; idx++) {
    10         if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
    11             *pos = idx;
    12             return;
    13         }
    14     }
    15     *pos = HT_INVALID_IDX;
    16 }

    end():

     1 PHP_FUNCTION(end)
     2 {
     3     HashTable *array;
     4     zval *entry;
     5 
     6 #ifndef FAST_ZPP
     7     if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
     8         return;
     9     }
    10 #else
    11     ZEND_PARSE_PARAMETERS_START(1, 1)
    12         Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
    13     ZEND_PARSE_PARAMETERS_END();
    14 #endif
    15     // 将数组的内部指针指向最后一个单元
    16     zend_hash_internal_pointer_end(array);
    17 
    18     if (USED_RET()) {
    19         if ((entry = zend_hash_get_current_data(array)) == NULL) {
    20             RETURN_FALSE;
    21         }
    22 
    23         if (Z_TYPE_P(entry) == IS_INDIRECT) {
    24             entry = Z_INDIRECT_P(entry);
    25         }
    26 
    27         ZVAL_DEREF(entry);
    28         ZVAL_COPY(return_value, entry);
    29     }
    30 }
    1 #define zend_hash_internal_pointer_end(ht) 
    2     zend_hash_internal_pointer_end_ex(ht, &(ht)->nInternalPointer)
     1 ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos)
     2 {
     3     uint32_t idx;
     4 
     5     IS_CONSISTENT(ht);
     6     HT_ASSERT(&ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
     7 
     8     // idx从最后一个Bucket开始,第一个出现的有效单元就是数组的末元素
     9     idx = ht->nNumUsed;
    10     while (idx > 0) {
    11         idx--;
    12         if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
    13             *pos = idx;
    14             return;
    15         }
    16     }
    17     *pos = HT_INVALID_IDX;
    18 }
  • 相关阅读:
    面向对象的----多态性
    UIWebView控件
    UIImageView控件
    UIDatePicker控件
    UIActivityIndicatorView控件
    UIProgressView控件
    XIB文件链接controller文件&&加载rootviewcontroller
    UISegmentedControl控件
    UISlider控件
    UISwitch控件
  • 原文地址:https://www.cnblogs.com/natian-ws/p/9154264.html
Copyright © 2011-2022 走看看