current()初始指向插入到数组中的第一个单元
next() 将数组的内部指针向前移动一位
prev() 将数组的内部指针倒回一位
reset() 将数组的内部指针指向第一个单元
end() 将数组的内部指针指向最后一个单元
current():
PHP_FUNCTION(current)
{
HashTable *array;
zval *entry;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT(array)
ZEND_PARSE_PARAMETERS_END();
#endif
// 获取内部指针指向的当前单元
if ((entry = zend_hash_get_current_data(array)) == NULL) {
RETURN_FALSE;
}
if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {
entry = Z\_INDIRECT\_P(entry);
}
ZVAL\_DEREF(entry);
ZVAL\_COPY(return\_value, entry);
}
#define zend_hash_get_current_data(ht) \
zend_hash_get_current_data_ex(ht, &(ht)->nInternalPointer)
ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx = *pos;
Bucket *p;
IS\_CONSISTENT(ht);
if (idx != HT\_INVALID\_IDX) {
p = ht->arData + idx; // 数组首地址加偏移量
return &p->val;
} else {
return NULL;
}
}
next():
PHP_FUNCTION(next)
{
HashTable *array;
zval *entry;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif
// 向前移动指针
zend\_hash\_move\_forward(array);
if (USED\_RET()) {
// 获取指针指向的单元
if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {
RETURN\_FALSE;
}
if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {
entry = Z\_INDIRECT\_P(entry);
}
ZVAL\_DEREF(entry);
ZVAL\_COPY(return\_value, entry);
}
}
#define zend_hash_move_forward(ht) \
zend_hash_move_forward_ex(ht, &(ht)->nInternalPointer)
ZEND_API int ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx = *pos;
IS\_CONSISTENT(ht);
HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );
if (idx != HT\_INVALID\_IDX) {
while () {
idx++;
if (idx >= ht->nNumUsed) { // 内部指针超出单元列表的末端(idx从0开始)
\*pos = HT\_INVALID\_IDX; // 保存内部指针为HT\_INVALID\_IDX
return SUCCESS;
}
if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) { // 内部指针向前移动后,指向的是有效元素
\*pos = idx; // 保存内部指针
return SUCCESS;
}
}
} else {
return FAILURE;
}
}
prev():
PHP_FUNCTION(prev)
{
HashTable *array;
zval *entry;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif
// 内部指针倒回一位
zend_hash_move_backwards(array);
if (USED\_RET()) {
// 获取当前指针指向的单元
if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {
RETURN\_FALSE;
}
if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {
entry = Z\_INDIRECT\_P(entry);
}
ZVAL\_DEREF(entry);
ZVAL\_COPY(return\_value, entry);
}
}
#define zend_hash_move_backwards(ht) \
zend_hash_move_backwards_ex(ht, &(ht)->nInternalPointer)
ZEND_API int ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx = *pos;
IS\_CONSISTENT(ht);
HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );
if (idx != HT\_INVALID\_IDX) {
while (idx > ) {
idx--;
if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) { // 内部指针指向的单元有效
\*pos = idx;
return SUCCESS;
}
}
// 指针倒回一位后没有找到有效的单元
\*pos = HT\_INVALID\_IDX;
return SUCCESS;
} else {
return FAILURE;
}
}
reset():
PHP_FUNCTION(reset)
{
HashTable *array;
zval *entry;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif
// 将内部指针指向第一个单元
zend\_hash\_internal\_pointer\_reset(array);
if (USED\_RET()) {
if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {
RETURN\_FALSE;
}
if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {
entry = Z\_INDIRECT\_P(entry);
}
ZVAL\_DEREF(entry);
ZVAL\_COPY(return\_value, entry);
}
}
#define zend_hash_internal_pointer_reset(ht) \
zend_hash_internal_pointer_reset_ex(ht, &(ht)->nInternalPointer)
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx;
IS\_CONSISTENT(ht);
HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );
// 内部指针指向数组的一个第一个有效单元
for (idx = ; idx < ht->nNumUsed; idx++) {
if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) {
\*pos = idx;
return;
}
}
\*pos = HT\_INVALID\_IDX;
}
end():
PHP_FUNCTION(end)
{
HashTable *array;
zval *entry;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif
// 将数组的内部指针指向最后一个单元
zend_hash_internal_pointer_end(array);
if (USED\_RET()) {
if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {
RETURN\_FALSE;
}
if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {
entry = Z\_INDIRECT\_P(entry);
}
ZVAL\_DEREF(entry);
ZVAL\_COPY(return\_value, entry);
}
}
#define zend_hash_internal_pointer_end(ht) \
zend_hash_internal_pointer_end_ex(ht, &(ht)->nInternalPointer)
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx;
IS\_CONSISTENT(ht);
HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );
// idx从最后一个Bucket开始,第一个出现的有效单元就是数组的末元素
idx = ht->nNumUsed;
while (idx > ) {
idx--;
if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) {
\*pos = idx;
return;
}
}
\*pos = HT\_INVALID\_IDX;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章