<commit_before>
#include "php.h"

#include "php_msgpack.h"
#include "msgpack_convert.h"
#include "msgpack_errors.h"

#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3)
#   define Z_REFCOUNT_P(pz)    ((pz)->refcount)
#   define Z_SET_ISREF_P(pz)   (pz)->is_ref = 1
#   define Z_UNSET_ISREF_P(pz) (pz)->is_ref = 0
#endif

#define MSGPACK_CONVERT_COPY_ZVAL(_pz, _ppz)   \
    ALLOC_INIT_ZVAL(_pz);                      \
    *(_pz) = **(_ppz);                         \
    if (PZVAL_IS_REF(*(_ppz))) {               \
        if (Z_REFCOUNT_P(*(_ppz)) > 0) {       \
            zval_copy_ctor(_pz);               \
        } else {                               \
            FREE_ZVAL(*(_ppz));                \
        }                                      \
        INIT_PZVAL(_pz);                       \
        Z_SET_ISREF_P(_pz);                    \
    } else {                                   \
        zval_copy_ctor(_pz);                   \
        INIT_PZVAL(_pz);                       \
    }

#define MSGPACK_CONVERT_UPDATE_PROPERTY(_ht, _key, _key_len, _val, _var)  \
    if (zend_symtable_update(                                             \
            _ht, _key, _key_len, &_val, sizeof(_val), NULL) == SUCCESS) { \
        zend_hash_add(_var, _key, _key_len, &_val, sizeof(_val), NULL);   \
        return SUCCESS;                                                   \
    }

static inline int msgpack_convert_long_to_properties(
    HashTable *ht, HashTable **properties, HashPosition *prop_pos,
    uint key_index, zval *val, HashTable *var)
{
    TSRMLS_FETCH();

    if (*properties != NULL)
    {
        char *prop_key;
        uint prop_key_len;
        ulong prop_key_index;
        zval **data = NULL;
        zval *tplval = NULL;
        zval **dataval = NULL;

        for (;; zend_hash_move_forward_ex(*properties, prop_pos))
        {
            if (zend_hash_get_current_key_ex(
                    *properties, &prop_key, &prop_key_len,
                    &prop_key_index, 0, prop_pos) == HASH_KEY_IS_STRING)
            {
                if (var == NULL ||
                    !zend_hash_exists(var, prop_key, prop_key_len))
                {
                    if (zend_hash_find(
                            ht, prop_key, prop_key_len,
                            (void **)&data) == SUCCESS)
                    {
                        switch (Z_TYPE_PP(data))
                        {
                            case IS_ARRAY:
                            {
                                HashTable *dataht;
                                dataht = HASH_OF(val);
                                if (zend_hash_index_find(
                                        dataht, prop_key_index,
                                        (void **)dataval) != SUCCESS)
                                {
                                    MSGPACK_WARNING(
                                        "[msgpack] (%s) "
                                        "can't get data value by index",
                                        __FUNCTION__);
                                    return FAILURE;
                                }

                                ALLOC_INIT_ZVAL(tplval);
                                if (msgpack_convert_array(
                                        tplval, *data, dataval) == SUCCESS)
                                {
                                    zend_hash_move_forward_ex(
                                        *properties, prop_pos);

                                    return zend_symtable_update(
                                        ht, prop_key, prop_key_len,
                                        &tplval, sizeof(tplval), NULL);
                                }
                                // TODO: de we need to call dtor?
                                return FAILURE;
                                break;
                            }
                            case IS_OBJECT:
                            {
                                ALLOC_INIT_ZVAL(tplval);
                                if (msgpack_convert_object(
                                        tplval, *data, &val) == SUCCESS)
                                {
                                    zend_hash_move_forward_ex(
                                        *properties, prop_pos);

                                    return zend_symtable_update(
                                        ht, prop_key, prop_key_len,
                                        &tplval, sizeof(tplval), NULL);
                                }
                                // TODO: de we need to call dtor?
                                return FAILURE;
                                break;
                            }
                            default:
                                zend_hash_move_forward_ex(*properties, prop_pos);
                                return zend_symtable_update(
                                    ht, prop_key, prop_key_len,
                                    &val, sizeof(val), NULL);
                                break;
                        }
                    }
                }
            }
            else
            {
                break;
            }
        }

        *properties = NULL;
    }

    return zend_hash_index_update(ht, key_index, &val, sizeof(val), NULL);
}

static inline int msgpack_convert_string_to_properties(
    zval *object, char *key, uint key_len, zval *val, HashTable *var)
{
    zval **data = NULL;
    HashTable *ht;
    zend_class_entry *ce;
    char *prot_name, *priv_name;
    int prop_name_len;
    TSRMLS_FETCH();

    ht = HASH_OF(object);
    ce = zend_get_class_entry(object TSRMLS_CC);

    /* private */
    zend_mangle_property_name(
        &priv_name, &prop_name_len, ce->name, ce->name_length, key, key_len - 1, 1);
    if (zend_hash_find(
            ht, priv_name, prop_name_len + 1, (void **)&data) == SUCCESS)<commit_msg>Update msgpack_convert_long_to_properties to new hash table iteration API<commit_after>
#include "php.h"

#include "php_msgpack.h"
#include "msgpack_convert.h"
#include "msgpack_errors.h"

#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3)
#   define Z_REFCOUNT_P(pz)    ((pz)->refcount)
#   define Z_SET_ISREF_P(pz)   (pz)->is_ref = 1
#   define Z_UNSET_ISREF_P(pz) (pz)->is_ref = 0
#endif

#define MSGPACK_CONVERT_COPY_ZVAL(_pz, _ppz)   \
    ALLOC_INIT_ZVAL(_pz);                      \
    *(_pz) = **(_ppz);                         \
    if (PZVAL_IS_REF(*(_ppz))) {               \
        if (Z_REFCOUNT_P(*(_ppz)) > 0) {       \
            zval_copy_ctor(_pz);               \
        } else {                               \
            FREE_ZVAL(*(_ppz));                \
        }                                      \
        INIT_PZVAL(_pz);                       \
        Z_SET_ISREF_P(_pz);                    \
    } else {                                   \
        zval_copy_ctor(_pz);                   \
        INIT_PZVAL(_pz);                       \
    }

#define MSGPACK_CONVERT_UPDATE_PROPERTY(_ht, _key, _key_len, _val, _var)  \
    if (zend_symtable_update(                                             \
            _ht, _key, _key_len, &_val, sizeof(_val), NULL) == SUCCESS) { \
        zend_hash_add(_var, _key, _key_len, &_val, sizeof(_val), NULL);   \
        return SUCCESS;                                                   \
    }

static inline int  msgpack_convert_long_to_properties(
    HashTable *ht, HashTable **properties, HashPosition *prop_pos,
    uint key_index, zval *val, HashTable *var)
{
    TSRMLS_FETCH();

    if (*properties != NULL)
    {
        zend_string *key_str;
        ulong key_long;
        zval *data;

        //non-iteration
        zval *dataval = NULL, *tplval = NULL;

        ZEND_HASH_FOREACH_KEY_VAL(ht, key_long, key_str, data) {
            if(key_str) {
                switch (Z_TYPE_P(data))
                {
                    case IS_ARRAY:
                        {
                            HashTable *dataht;
                            dataht = HASH_OF(val);
                            if ((dataval = zend_hash_index_find(dataht, key_long)) != NULL) {
                                MSGPACK_WARNING(
                                        "[msgpack] (%s) "
                                        "can't get data value by index",
                                        __FUNCTION__);
                                return FAILURE;
                            }

                            if (msgpack_convert_array(tplval, data, &dataval) == SUCCESS) {
                                return (zend_symtable_update(ht, key_str, tplval) != NULL);
                            }
                            // TODO: de we need to call dtor?
                            return FAILURE;
                        }
                    case IS_OBJECT:
                        {
                            if (msgpack_convert_object(tplval, data, &val) == SUCCESS) {
                                return (zend_symtable_update(ht, key_str, tplval) != NULL);
                            }
                            // TODO: de we need to call dtor?
                            return FAILURE;
                        }
                    default:
                        return (zend_symtable_update(ht, key_str, tplval) != NULL);
                }
            }
        } ZEND_HASH_FOREACH_END();
        *properties = NULL;
    }
    return (zend_hash_index_update(ht, key_index, val) != NULL);
}

static inline int msgpack_convert_string_to_properties(
    zval *object, char *key, uint key_len, zval *val, HashTable *var)
{
    zval **data = NULL;
    HashTable *ht;
    zend_class_entry *ce;
    char *prot_name, *priv_name;
    int prop_name_len;
    TSRMLS_FETCH();

    ht = HASH_OF(object);
    ce = zend_get_class_entry(object TSRMLS_CC);

    /* private */
    zend_mangle_property_name(
        &priv_name, &prop_name_len, ce->name, ce->name_length, key, key_len - 1, 1);
    if (zend_hash_find(
            ht, priv_name, prop_name_len + 1, (void **)&data) == SUCCESS)
{'fraction_non_alphanumeric': 0.08781925343811395, 'fraction_numerical': 0.0016699410609037329, 'mean_word_length': 0.9908095424325382, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 47, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7202666', 'n_tokens_mistral': 2920, 'n_tokens_neox': 2806, 'n_words': 528}