pygi-cache.h 6.75 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 */

22 23 24 25 26 27
#ifndef __PYGI_CACHE_H__
#define __PYGI_CACHE_H__

#include <Python.h>
#include <girepository.h>

28 29
#include "pygi-invoke-state-struct.h"

30 31
G_BEGIN_DECLS

32
typedef struct _PyGICallableCache PyGICallableCache;
33 34
typedef struct _PyGIArgCache PyGIArgCache;

35 36 37 38 39
typedef gboolean (*PyGIMarshalFromPyFunc) (PyGIInvokeState   *state,
                                           PyGICallableCache *callable_cache,
                                           PyGIArgCache      *arg_cache,
                                           PyObject          *py_arg,
                                           GIArgument        *arg);
40

41 42 43 44
typedef PyObject *(*PyGIMarshalToPyFunc) (PyGIInvokeState   *state,
                                          PyGICallableCache *callable_cache,
                                          PyGIArgCache      *arg_cache,
                                          GIArgument        *arg);
45

46 47
typedef void (*PyGIMarshalCleanupFunc) (PyGIInvokeState *state,
                                        PyGIArgCache    *arg_cache,
48 49
                                        gpointer         data,
                                        gboolean         was_processed);
50 51

/* Argument meta types denote how we process the argument:
52
 *  - PYGI_META_ARG_TYPE_PARENT - parents may or may not have children
53 54 55
 *    but are always processed via the normal marshaller for their
 *    actual GI type.  If they have children the marshaller will
 *    also handle marshalling the children.
56
 *  - PYGI_META_ARG_TYPE_CHILD - Children without python argument are
57 58 59 60 61 62
 *    ignored by the marshallers and handled directly by their parents
 *    marshaller.
 *  - Children with pyargs (PYGI_META_ARG_TYPE_CHILD_WITH_PYARG) are processed
 *    the same as other child args but also have an index into the 
 *    python parameters passed to the invoker
 */
John (J5) Palmieri's avatar
John (J5) Palmieri committed
63
typedef enum {
64 65
    PYGI_META_ARG_TYPE_PARENT,
    PYGI_META_ARG_TYPE_CHILD,
66 67
    PYGI_META_ARG_TYPE_CHILD_WITH_PYARG,
    PYGI_META_ARG_TYPE_CLOSURE,
68 69
} PyGIMetaArgType;

70 71 72 73 74 75
/*
 * GI determines function types via a combination of flags and info classes.
 * Since for branching purposes they are mutually exclusive, the 
 * PyGIFunctionType enum consolidates them into one enumeration for ease of 
 * branching and debugging.
 */
76 77 78 79 80
typedef enum {
    PYGI_FUNCTION_TYPE_FUNCTION,
    PYGI_FUNCTION_TYPE_METHOD,
    PYGI_FUNCTION_TYPE_CONSTRUCTOR,
    PYGI_FUNCTION_TYPE_VFUNC,
81 82
    PYGI_FUNCTION_TYPE_CALLBACK,
    PYGI_FUNCTION_TYPE_CCALLBACK,
83
 } PyGIFunctionType;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
84

85 86 87 88 89 90 91 92
/*
 * In PyGI IN and OUT arguments mean different things depending on the context
 * of the callable (e.g. is it a callback that is being called from C or a
 * function that is being called from python).  We don't as much care if the
 * parameter is an IN or OUT C parameter, than we do if the parameter is being
 * marshalled into Python or from Python.
 */
typedef enum {
93 94 95
    PYGI_DIRECTION_TO_PYTHON     = 1 << 0,
    PYGI_DIRECTION_FROM_PYTHON   = 1 << 1,
    PYGI_DIRECTION_BIDIRECTIONAL = PYGI_DIRECTION_TO_PYTHON | PYGI_DIRECTION_FROM_PYTHON
96 97 98
 } PyGIDirection;


99 100
struct _PyGIArgCache
{
101 102
    const gchar *arg_name;

103
    PyGIMetaArgType meta_type;
104
    gboolean is_pointer;
105
    gboolean is_caller_allocates;
106
    gboolean is_skipped;
107
    gboolean allow_none;
108

109
    PyGIDirection direction;
110 111
    GITransfer transfer;
    GITypeTag type_tag;
112
    GITypeInfo *type_info;
113

114 115
    PyGIMarshalFromPyFunc from_py_marshaller;
    PyGIMarshalToPyFunc to_py_marshaller;
116

117 118
    PyGIMarshalCleanupFunc from_py_cleanup;
    PyGIMarshalCleanupFunc to_py_cleanup;
119

120 121
    GDestroyNotify destroy_notify;

122 123
    gssize c_arg_index;
    gssize py_arg_index;
124
};
125

126 127
typedef struct _PyGISequenceCache
{
128
    PyGIArgCache arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
129
    gssize fixed_size;
130
    gssize len_arg_index;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
131
    gboolean is_zero_terminated;
132
    gsize item_size;
133
    GIArrayType array_type;
134
    PyGIArgCache *item_cache;
135
} PyGISequenceCache;
136 137 138

typedef struct _PyGIInterfaceCache
{
139
    PyGIArgCache arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
140 141 142
    gboolean is_foreign;
    GType g_type;
    PyObject *py_type;
143
    GIInterfaceInfo *interface_info;
144
    gchar *type_name;
145 146 147 148
} PyGIInterfaceCache;

typedef struct _PyGIHashCache
{
149
    PyGIArgCache arg_cache;
150 151
    PyGIArgCache *key_cache;
    PyGIArgCache *value_cache;
152 153
} PyGIHashCache;

John (J5) Palmieri's avatar
John (J5) Palmieri committed
154
typedef struct _PyGICallbackCache
155
{
156
    PyGIArgCache arg_cache;
157 158
    gssize user_data_index;
    gssize destroy_notify_index;
159
    GIScopeType scope;
160
    GIInterfaceInfo *interface_info;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
161
} PyGICallbackCache;
162

163
struct _PyGICallableCache
164
{
165 166
    const gchar *name;

167
    PyGIFunctionType function_type;
168

169
    PyGIArgCache *return_cache;
170
    GPtrArray *args_cache;
171
    GSList *to_py_args;
172 173
    GSList *arg_name_list; /* for keyword arg matching */
    GHashTable *arg_name_hash;
174

175 176
    /* Number of in args passed to g_function_info_invoke.
     * This is used for the length of PyGIInvokeState.in_args */
177
    gssize n_from_py_args;
178 179 180

    /* Number of out args passed to g_function_info_invoke.
     * This is used for the length of PyGIInvokeState.out_values */
181
    gssize n_to_py_args;
182 183 184 185 186

    /* Number of out args for g_function_info_invoke that will be skipped
     * when marshaling to Python due to them being implicitly available
     * (list/array length).
     */
187
    gssize n_to_py_child_args;
188

189
    /* Number of Python arguments expected for invoking the gi function. */
190
    gssize n_py_args;
191
};
192 193

void _pygi_arg_cache_clear	(PyGIArgCache *cache);
194
void _pygi_callable_cache_free	(PyGICallableCache *cache);
195

196 197
PyGICallableCache *_pygi_callable_cache_new (GICallableInfo *callable_info,
                                             gboolean is_ccallback);
198

199 200 201 202 203 204 205 206 207 208 209 210
#define _pygi_callable_cache_args_len(cache) ((cache)->args_cache)->len

inline static PyGIArgCache *
_pygi_callable_cache_get_arg (PyGICallableCache *cache, guint index) {
    return (PyGIArgCache *) g_ptr_array_index (cache->args_cache, index);
}

inline static void
_pygi_callable_cache_set_arg (PyGICallableCache *cache, guint index, PyGIArgCache *arg_cache) {
    cache->args_cache->pdata[index] = arg_cache;
}

211
G_END_DECLS
212

213
#endif /* __PYGI_CACHE_H__ */