From:             [EMAIL PROTECTED]
Operating system: Win32
PHP version:      4.1.1
PHP Bug Type:     Feature/Change Request
Bug description:  Need function to explicitly set a hash's internal pointer to a 
certain key pos

I have found it useful from time to time to have a function that will set
the internal pointer of an array to a particular key position. I therefore
propose the addition of the following function:

mixed setpos(array array, mixed keyval)

The function merely sets the internal pointer of the array to the element
referenced by keyval, and returns the value of the element at that
position.

I have included what I believe is source code that should add the
functionality, though it is untested. I have included only the actual C
code, but I think the header file lines to be added are pretty obvious. 

_______________________________________

ADDITIONS TO /EXT/STANDARD/ARRAY.C:
-----------------------------------

/* {{{ proto mixed setpos(array array_arg, mixed keyval)
   Set array argument's internal pointer to the element indexed by keyval
and return it */        
PHP_FUNCTION(setpos)
{
        pval **array, **entry;
        HashTable *target_hash;

        if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array) == FAILURE)
{
                WRONG_PARAM_COUNT;
        }
        target_hash = HASH_OF(*array);
        if (!target_hash) {
                php_error(E_WARNING, "Variable passed to setpos() is not an array or
object");
                RETURN_FALSE;
        }
        if(Z_TYPE_PP(keyval) == IS_LONG)
                zend_hash_internal_pointer_index_set(target_hash, keyval);
        else if(Z_TYPE_PP(keyval) == IS_STRING)
                zend_hash_internal_pointer_set(target_hash, keyval,
Z_STRLEN_PP(keyval)+1);
        else {
                php_error(E_WARNING, "Can only have STRING and INTEGER keys!");
        }

        if (return_value_used) {        
                if (zend_hash_get_current_data(target_hash, (void **) &entry) == 
FAILURE)
{
                        RETURN_FALSE;
                }

                *return_value = **entry;
                zval_copy_ctor(return_value);
        }
}
/* }}} */

________________________________________

ADDITIONS TO /ZEND/ZEND_HASH.C:
-------------------------------


/* Returns SUCCESS if found and FAILURE if not. If the key is found, the
internal pointer is set to point at that element. */
ZEND_API int zend_internal_pointer_set(HashTable *ht, char *arKey, uint
nKeyLength)
{
        ulong h;
        uint nIndex;
        Bucket *p;

        IS_CONSISTENT(ht);

        HANDLE_NUMERIC(arKey, nKeyLength, zend_internal_pointer_index_set(ht,
idx));

        h = ht->pHashFunction(arKey, nKeyLength);
        nIndex = h % ht->nTableSize;

        p = ht->arBuckets[nIndex];
        while (p != NULL) {
                if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
                        if (!memcmp(p->arKey, arKey, nKeyLength)) {
                                ht->pInternalPointer = p;
                                return SUCCESS;
                        }
                }
                p = p->pNext;
        }
        return FAILURE;
}


ZEND_API int zend_internal_pointer_index_set(HashTable *ht, ulong h)
{
        uint nIndex;
        Bucket *p;

        IS_CONSISTENT(ht);

        nIndex = h % ht->nTableSize;

        p = ht->arBuckets[nIndex];
        while (p != NULL) {
                if ((p->h == h) && (p->nKeyLength == 0)) {
                        ht->pInternalPointer = p;
                        return SUCCESS;
                }
                p = p->pNext;
        }
        return FAILURE;
}

-- 
Edit bug report at: http://bugs.php.net/?id=14918&edit=1


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to