<commit_before>/*
 * PHP-GTK - The PHP language bindings for GTK+
 *
 * Copyright (C) 2001-2004 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "php_gtk.h"

#if HAVE_PHP_GTK

/*
 * GValue related functions
 */

/* TODO
 * G_TYPE_PARAM
 */


/* {{{ PHP_GTK_API phpg_gvalue_to_zval() */
PHP_GTK_API int phpg_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed TSRMLS_DC)
{
    assert(value != NULL);

    switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) {
        case G_TYPE_NONE:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_NULL(*value);
            break;

        case G_TYPE_CHAR:
            {
                gchar val = g_value_get_char(gval);
                MAKE_ZVAL_IF_NULL(*value);
                ZVAL_STRINGL(*value, (char *)&val, 1, 1);
            }

        case G_TYPE_UCHAR:
            {
                guchar val = g_value_get_uchar(gval);
                MAKE_ZVAL_IF_NULL(*value);
                ZVAL_STRINGL(*value, (char *)&val, 1, 1);
            }
            break;

        case G_TYPE_BOOLEAN:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_BOOL(*value, g_value_get_boolean(gval));
            break;

        case G_TYPE_INT:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_int(gval));
            break;

        case G_TYPE_LONG:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_long(gval));
            break;

        case G_TYPE_UINT:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_uint(gval));
            break;

        case G_TYPE_ULONG:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_ulong(gval));
            break;

        case G_TYPE_FLOAT:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_DOUBLE(*value, (double)g_value_get_float(gval));
            break;

        case G_TYPE_DOUBLE:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_DOUBLE(*value, (double)g_value_get_double(gval));
            break;

        case G_TYPE_ENUM:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_enum(gval));
            break;

        case G_TYPE_FLAGS:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_flags(gval));
            break;

        case G_TYPE_STRING:
            {
                const gchar *str = g_value_get_string(gval);

                MAKE_ZVAL_IF_NULL(*value);
                if (str != NULL) {
                    ZVAL_STRING(*value, (char *)str, 1);
                } else
                    ZVAL_NULL(*value);
            }
            break;

        case G_TYPE_OBJECT:
            phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC);
            break;

        case G_TYPE_INTERFACE:
            if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT)) {
                phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC);
            } else {
                php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval)));
                MAKE_STD_ZVAL(*value);
                ZVAL_NULL(*value);
                return FAILURE;
            }
            break;

        case G_TYPE_POINTER:
            phpg_gpointer_new(value, G_VALUE_TYPE(gval), g_value_get_pointer(gval) TSRMLS_CC);
            break;

        case G_TYPE_BOXED:
        {
            phpg_gboxed_marshal_t *gbm;

            if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) {
                zval *object = (zval *) g_value_dup_boxed(gval);
                MAKE_ZVAL_IF_NULL(*value);
                if (object) {
                    REPLACE_ZVAL_VALUE(value, object, 1);
                    zval_ptr_dtor(&object);
                    return SUCCESS;
                } else {
                    ZVAL_NULL(*value);
                    return FAILURE;
                }
            } else if (G_VALUE_HOLDS(gval, G_TYPE_VALUE_ARRAY)) {
                int i;
                zval *item;
                int value_count;

                GValueArray *array = (GValueArray *) g_value_get_boxed(gval);
                MAKE_ZVAL_IF_NULL(*value);
                array_init(*value);
                value_count = array->n_values;

                for (i = 0; i < value_count; i++) {
                    MAKE_STD_ZVAL(item);
                    phpg_gvalue_to_zval(array->values + i, &item, copy_boxed TSRMLS_CC);
                    add_next_index_zval(*value, item);
                }
            } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) {
                MAKE_STD_ZVAL(*value);
                return gbm->to_zval(gval, value TSRMLS_CC);
            } else {
                if (copy_boxed) {
                    phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), TRUE, TRUE TSRMLS_CC);
                } else {
                    phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), FALSE, FALSE TSRMLS_CC);
                }
            }
            break;
        }

        default:
            php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval)));
            MAKE_STD_ZVAL(*value);
            ZVAL_NULL(*value);
            return FAILURE;
    }

    return SUCCESS;
}
/* }}} */

/* {{{ PHP_GTK_API phpg_gvalue_from_zval() */
PHP_GTK_API int phpg_gvalue_from_zval(GValue *gval, zval *value TSRMLS_DC)
{
    switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) {
        case G_TYPE_BOOLEAN:
            convert_to_boolean(value);
            g_value_set_boolean(gval, (gboolean)Z_BVAL_P(value));
            break;

        case G_TYPE_CHAR:
            convert_to_string(value);
            g_value_set_char(gval, Z_STRVAL_P(value)[0]);
            break;

        case G_TYPE_UCHAR:
            convert_to_string(value);
            g_value_set_uchar(gval, (guchar)Z_STRVAL_P(value)[0]);
            break;

        case G_TYPE_INT:
            convert_to_long(value);<commit_msg>Respect G_TYPE_INVALID/G_TYPE_NONE in phpg_gvalue_from_zval().<commit_after>/*
 * PHP-GTK - The PHP language bindings for GTK+
 *
 * Copyright (C) 2001-2004 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "php_gtk.h"

#if HAVE_PHP_GTK

/*
 * GValue related functions
 */

/* TODO
 * G_TYPE_PARAM
 */


/* {{{ PHP_GTK_API phpg_gvalue_to_zval() */
PHP_GTK_API int phpg_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed TSRMLS_DC)
{
    assert(value != NULL);

    switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) {
        case G_TYPE_NONE:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_NULL(*value);
            break;

        case G_TYPE_CHAR:
            {
                gchar val = g_value_get_char(gval);
                MAKE_ZVAL_IF_NULL(*value);
                ZVAL_STRINGL(*value, (char *)&val, 1, 1);
            }

        case G_TYPE_UCHAR:
            {
                guchar val = g_value_get_uchar(gval);
                MAKE_ZVAL_IF_NULL(*value);
                ZVAL_STRINGL(*value, (char *)&val, 1, 1);
            }
            break;

        case G_TYPE_BOOLEAN:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_BOOL(*value, g_value_get_boolean(gval));
            break;

        case G_TYPE_INT:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_int(gval));
            break;

        case G_TYPE_LONG:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_long(gval));
            break;

        case G_TYPE_UINT:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_uint(gval));
            break;

        case G_TYPE_ULONG:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_ulong(gval));
            break;

        case G_TYPE_FLOAT:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_DOUBLE(*value, (double)g_value_get_float(gval));
            break;

        case G_TYPE_DOUBLE:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_DOUBLE(*value, (double)g_value_get_double(gval));
            break;

        case G_TYPE_ENUM:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_enum(gval));
            break;

        case G_TYPE_FLAGS:
            MAKE_ZVAL_IF_NULL(*value);
            ZVAL_LONG(*value, (long)g_value_get_flags(gval));
            break;

        case G_TYPE_STRING:
            {
                const gchar *str = g_value_get_string(gval);

                MAKE_ZVAL_IF_NULL(*value);
                if (str != NULL) {
                    ZVAL_STRING(*value, (char *)str, 1);
                } else
                    ZVAL_NULL(*value);
            }
            break;

        case G_TYPE_OBJECT:
            phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC);
            break;

        case G_TYPE_INTERFACE:
            if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT)) {
                phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC);
            } else {
                php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval)));
                MAKE_STD_ZVAL(*value);
                ZVAL_NULL(*value);
                return FAILURE;
            }
            break;

        case G_TYPE_POINTER:
            phpg_gpointer_new(value, G_VALUE_TYPE(gval), g_value_get_pointer(gval) TSRMLS_CC);
            break;

        case G_TYPE_BOXED:
        {
            phpg_gboxed_marshal_t *gbm;

            if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) {
                zval *object = (zval *) g_value_dup_boxed(gval);
                MAKE_ZVAL_IF_NULL(*value);
                if (object) {
                    REPLACE_ZVAL_VALUE(value, object, 1);
                    zval_ptr_dtor(&object);
                    return SUCCESS;
                } else {
                    ZVAL_NULL(*value);
                    return FAILURE;
                }
            } else if (G_VALUE_HOLDS(gval, G_TYPE_VALUE_ARRAY)) {
                int i;
                zval *item;
                int value_count;

                GValueArray *array = (GValueArray *) g_value_get_boxed(gval);
                MAKE_ZVAL_IF_NULL(*value);
                array_init(*value);
                value_count = array->n_values;

                for (i = 0; i < value_count; i++) {
                    MAKE_STD_ZVAL(item);
                    phpg_gvalue_to_zval(array->values + i, &item, copy_boxed TSRMLS_CC);
                    add_next_index_zval(*value, item);
                }
            } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) {
                MAKE_STD_ZVAL(*value);
                return gbm->to_zval(gval, value TSRMLS_CC);
            } else {
                if (copy_boxed) {
                    phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), TRUE, TRUE TSRMLS_CC);
                } else {
                    phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), FALSE, FALSE TSRMLS_CC);
                }
            }
            break;
        }

        default:
            php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval)));
            MAKE_STD_ZVAL(*value);
            ZVAL_NULL(*value);
            return FAILURE;
    }

    return SUCCESS;
}
/* }}} */

/* {{{ PHP_GTK_API phpg_gvalue_from_zval() */
PHP_GTK_API int phpg_gvalue_from_zval(GValue *gval, zval *value TSRMLS_DC)
{
    switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) {
        /*
         * For whatever reason, we should apparently respect that the gval may be of these
         * types and they do not need a value.
         */
        case G_TYPE_INVALID:
        case G_TYPE_NONE:
            break;

        case G_TYPE_BOOLEAN:
            convert_to_boolean(value);
            g_value_set_boolean(gval, (gboolean)Z_BVAL_P(value));
            break;

        case G_TYPE_CHAR:
            convert_to_string(value);
            g_value_set_char(gval, Z_STRVAL_P(value)[0]);
            break;

        case G_TYPE_UCHAR:
            convert_to_string(value);
            g_value_set_uchar(gval, (guchar)Z_STRVAL_P(value)[0]);
            break;

        case G_TYPE_INT:
            convert_to_long(value);
{'fraction_non_alphanumeric': 0.09315960912052117, 'fraction_numerical': 0.004777415852334419, 'mean_word_length': 1.8311475409836067, 'pattern_counts': {'":': 0, '<': 11, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1412159', 'n_tokens_mistral': 4661, 'n_tokens_neox': 4411, 'n_words': 861}