<commit_before>/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2005-2009 <NAME> <<EMAIL>>
 *
 *   pygi-argument.c: GIArgument - PyObject conversion functions.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include <Python.h>

#include <string.h>
#include <time.h>

#include "pygobject-internal.h"

#include <pygenum.h>
#include <pygflags.h>

#include "pygi-python-compat.h"
#include "pygi-argument.h"
#include "pygi-info.h"
#include "pygi-value.h"
#include "pygi-basictype.h"
#include "pygi-object.h"
#include "pygi-struct-marshal.h"
#include "pygi-error.h"
#include "pygi-foreign.h"
#include "pygi-type.h"
#include "pygi-util.h"


gboolean
pygi_argument_to_gssize (GIArgument *arg_in,
                         GITypeTag  type_tag,
                         gssize *gssize_out)
{
    switch (type_tag) {
      case GI_TYPE_TAG_INT8:
          *gssize_out = arg_in->v_int8;
          return TRUE;
      case GI_TYPE_TAG_UINT8:
          *gssize_out = arg_in->v_uint8;
          return TRUE;
      case GI_TYPE_TAG_INT16:
          *gssize_out = arg_in->v_int16;
          return TRUE;
      case GI_TYPE_TAG_UINT16:
          *gssize_out = arg_in->v_uint16;
          return TRUE;
      case GI_TYPE_TAG_INT32:
          *gssize_out = arg_in->v_int32;
          return TRUE;
      case GI_TYPE_TAG_UINT32:
          *gssize_out = arg_in->v_uint32;
          return TRUE;
      case GI_TYPE_TAG_INT64:
          if (arg_in->v_int64 > G_MAXSSIZE || arg_in->v_int64 < G_MINSSIZE) {
              PyErr_Format (PyExc_TypeError,
                            "Unable to marshal %s to gssize",
                            g_type_tag_to_string(type_tag));
              return FALSE;
          }
          *gssize_out = (gssize)arg_in->v_int64;
          return TRUE;
      case GI_TYPE_TAG_UINT64:
          if (arg_in->v_uint64 > G_MAXSSIZE) {
              PyErr_Format (PyExc_TypeError,
                            "Unable to marshal %s to gssize",
                            g_type_tag_to_string(type_tag));
              return FALSE;
          }
          *gssize_out = (gssize)arg_in->v_uint64;
          return TRUE;
      default:
          PyErr_Format (PyExc_TypeError,
                        "Unable to marshal %s to gssize",
                        g_type_tag_to_string(type_tag));
          return FALSE;
    }
}

static GITypeTag
_pygi_get_storage_type (GITypeInfo *type_info)
{
    GITypeTag type_tag = g_type_info_get_tag (type_info);

    if (type_tag == GI_TYPE_TAG_INTERFACE) {
        GIBaseInfo *interface = g_type_info_get_interface (type_info);
        switch (g_base_info_get_type (interface)) {
            case GI_INFO_TYPE_ENUM:
            case GI_INFO_TYPE_FLAGS:
                type_tag = g_enum_info_get_storage_type ((GIEnumInfo *)interface);
                break;
            default:
                /* FIXME: we might have something to do for other types */
                break;
        }
        g_base_info_unref (interface);
    }
    return type_tag;
}

void
_pygi_hash_pointer_to_arg (GIArgument *arg,
                           GITypeInfo *type_info)
{
    GITypeTag type_tag = _pygi_get_storage_type (type_info);

    switch (type_tag) {
        case GI_TYPE_TAG_INT8:
            arg->v_int8 = (gint8)GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_INT16:
            arg->v_int16 = (gint16)GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_INT32:
            arg->v_int32 = (gint32)GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT8:
            arg->v_uint8 = (guint8)GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT16:
            arg->v_uint16 = (guint16)GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT32:
            arg->v_uint32 = (guint32)GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_GTYPE:
            arg->v_size = GPOINTER_TO_SIZE (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
        case GI_TYPE_TAG_INTERFACE:
            break;
        default:
            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
    }
}

gpointer
_pygi_arg_to_hash_pointer (const GIArgument *arg,
                           GITypeInfo       *type_info)
{
    GITypeTag type_tag = _pygi_get_storage_type (type_info);

    switch (type_tag) {
        case GI_TYPE_TAG_INT8:
            return GINT_TO_POINTER (arg->v_int8);
        case GI_TYPE_TAG_UINT8:
            return GINT_TO_POINTER (arg->v_uint8);
        case GI_TYPE_TAG_INT16:
            return GINT_TO_POINTER (arg->v_int16);
        case GI_TYPE_TAG_UINT16:
            return GINT_TO_POINTER (arg->v_uint16);
        case GI_TYPE_TAG_INT32:
            return GINT_TO_POINTER (arg->v_int32);
        case GI_TYPE_TAG_UINT32:
            return GINT_TO_POINTER (arg->v_uint32);
        case GI_TYPE_TAG_GTYPE:
            return GSIZE_TO_POINTER (arg->v_size);
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
        case GI_TYPE_TAG_INTERFACE:
            return arg->v_pointer;
        default:
            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
            return arg->v_pointer;
    }
}


/**
 * _pygi_argument_array_length_marshal:
 * @length_arg_index: Index of length argument in the callables args list.
 * @user_data1: (type Array(GValue)): Array of GValue arguments to retrieve length
 * @user_data2: (type GICallableInfo): Callable info to get the argument from.
 *
 * Generic marshalling policy for array length arguments in callables.
 *
 * Returns: The length of the array or -1 on failure.
 */
gssize
_pygi_argument_array_length_marshal (gsize length_arg_index,
                                     void *user_data1,
                                     void *user_data2)
{
    GIArgInfo length_arg_info;<commit_msg>gi/pygi-argument: Squash critical warning when using array as hash value<commit_after>/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2005-2009 <NAME> <<EMAIL>>
 *
 *   pygi-argument.c: GIArgument - PyObject conversion functions.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include <Python.h>

#include <string.h>
#include <time.h>

#include "pygobject-internal.h"

#include <pygenum.h>
#include <pygflags.h>

#include "pygi-python-compat.h"
#include "pygi-argument.h"
#include "pygi-info.h"
#include "pygi-value.h"
#include "pygi-basictype.h"
#include "pygi-object.h"
#include "pygi-struct-marshal.h"
#include "pygi-error.h"
#include "pygi-foreign.h"
#include "pygi-type.h"
#include "pygi-util.h"


gboolean
pygi_argument_to_gssize (GIArgument *arg_in,
                         GITypeTag  type_tag,
                         gssize *gssize_out)
{
    switch (type_tag) {
      case GI_TYPE_TAG_INT8:
          *gssize_out = arg_in->v_int8;
          return TRUE;
      case GI_TYPE_TAG_UINT8:
          *gssize_out = arg_in->v_uint8;
          return TRUE;
      case GI_TYPE_TAG_INT16:
          *gssize_out = arg_in->v_int16;
          return TRUE;
      case GI_TYPE_TAG_UINT16:
          *gssize_out = arg_in->v_uint16;
          return TRUE;
      case GI_TYPE_TAG_INT32:
          *gssize_out = arg_in->v_int32;
          return TRUE;
      case GI_TYPE_TAG_UINT32:
          *gssize_out = arg_in->v_uint32;
          return TRUE;
      case GI_TYPE_TAG_INT64:
          if (arg_in->v_int64 > G_MAXSSIZE || arg_in->v_int64 < G_MINSSIZE) {
              PyErr_Format (PyExc_TypeError,
                            "Unable to marshal %s to gssize",
                            g_type_tag_to_string(type_tag));
              return FALSE;
          }
          *gssize_out = (gssize)arg_in->v_int64;
          return TRUE;
      case GI_TYPE_TAG_UINT64:
          if (arg_in->v_uint64 > G_MAXSSIZE) {
              PyErr_Format (PyExc_TypeError,
                            "Unable to marshal %s to gssize",
                            g_type_tag_to_string(type_tag));
              return FALSE;
          }
          *gssize_out = (gssize)arg_in->v_uint64;
          return TRUE;
      default:
          PyErr_Format (PyExc_TypeError,
                        "Unable to marshal %s to gssize",
                        g_type_tag_to_string(type_tag));
          return FALSE;
    }
}

static GITypeTag
_pygi_get_storage_type (GITypeInfo *type_info)
{
    GITypeTag type_tag = g_type_info_get_tag (type_info);

    if (type_tag == GI_TYPE_TAG_INTERFACE) {
        GIBaseInfo *interface = g_type_info_get_interface (type_info);
        switch (g_base_info_get_type (interface)) {
            case GI_INFO_TYPE_ENUM:
            case GI_INFO_TYPE_FLAGS:
                type_tag = g_enum_info_get_storage_type ((GIEnumInfo *)interface);
                break;
            default:
                /* FIXME: we might have something to do for other types */
                break;
        }
        g_base_info_unref (interface);
    }
    return type_tag;
}

void
_pygi_hash_pointer_to_arg (GIArgument *arg,
                           GITypeInfo *type_info)
{
    GITypeTag type_tag = _pygi_get_storage_type (type_info);

    switch (type_tag) {
        case GI_TYPE_TAG_INT8:
            arg->v_int8 = (gint8)GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_INT16:
            arg->v_int16 = (gint16)GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_INT32:
            arg->v_int32 = (gint32)GPOINTER_TO_INT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT8:
            arg->v_uint8 = (guint8)GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT16:
            arg->v_uint16 = (guint16)GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UINT32:
            arg->v_uint32 = (guint32)GPOINTER_TO_UINT (arg->v_pointer);
            break;
        case GI_TYPE_TAG_GTYPE:
            arg->v_size = GPOINTER_TO_SIZE (arg->v_pointer);
            break;
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
        case GI_TYPE_TAG_INTERFACE:
        case GI_TYPE_TAG_ARRAY:
            break;
        default:
            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
    }
}

gpointer
_pygi_arg_to_hash_pointer (const GIArgument *arg,
                           GITypeInfo       *type_info)
{
    GITypeTag type_tag = _pygi_get_storage_type (type_info);

    switch (type_tag) {
        case GI_TYPE_TAG_INT8:
            return GINT_TO_POINTER (arg->v_int8);
        case GI_TYPE_TAG_UINT8:
            return GINT_TO_POINTER (arg->v_uint8);
        case GI_TYPE_TAG_INT16:
            return GINT_TO_POINTER (arg->v_int16);
        case GI_TYPE_TAG_UINT16:
            return GINT_TO_POINTER (arg->v_uint16);
        case GI_TYPE_TAG_INT32:
            return GINT_TO_POINTER (arg->v_int32);
        case GI_TYPE_TAG_UINT32:
            return GINT_TO_POINTER (arg->v_uint32);
        case GI_TYPE_TAG_GTYPE:
            return GSIZE_TO_POINTER (arg->v_size);
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
        case GI_TYPE_TAG_INTERFACE:
        case GI_TYPE_TAG_ARRAY:
            return arg->v_pointer;
        default:
            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
            return arg->v_pointer;
    }
}


/**
 * _pygi_argument_array_length_marshal:
 * @length_arg_index: Index of length argument in the callables args list.
 * @user_data1: (type Array(GValue)): Array of GValue arguments to retrieve length
 * @user_data2: (type GICallableInfo): Callable info to get the argument from.
 *
 * Generic marshalling policy for array length arguments in callables.
 *
 * Returns: The length of the array or -1 on failure.
 */
gssize
_pygi_argument_array_length_marshal (gsize length_arg_index,
                                     void *user_data1,
                                     void *user_data2)
{
    GIArgInfo length_arg_info;
{'fraction_non_alphanumeric': 0.08411214953271028, 'fraction_numerical': 0.015551401869158878, 'mean_word_length': 2.2169312169312168, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3781863', 'n_tokens_mistral': 4630, 'n_tokens_neox': 4427, 'n_words': 992}