353a2d169e16e16de4f4853f9c0fdafd3dae6f1b
[platform/upstream/python-gobject.git] / gi / pygi-struct-marshal.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5  * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <Python.h>
22 #include <glib.h>
23 #include <pyglib-python-compat.h>
24
25 #include "pygi-struct-marshal.h"
26 #include "pygi-private.h"
27 #include "pygi-value.h"
28
29 /*
30  * _is_union_member - check to see if the py_arg is actually a member of the
31  * expected C union
32  */
33 static gboolean
34 _is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) {
35     gint i;
36     gint n_fields;
37     GIUnionInfo *union_info;
38     GIInfoType info_type;
39     gboolean is_member = FALSE;
40
41     info_type = g_base_info_get_type (interface_info);
42
43     if (info_type != GI_INFO_TYPE_UNION)
44         return FALSE;
45
46     union_info = (GIUnionInfo *) interface_info;
47     n_fields = g_union_info_get_n_fields (union_info);
48
49     for (i = 0; i < n_fields; i++) {
50         GIFieldInfo *field_info;
51         GITypeInfo *field_type_info;
52
53         field_info = g_union_info_get_field (union_info, i);
54         field_type_info = g_field_info_get_type (field_info);
55
56         /* we can only check if the members are interfaces */
57         if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
58             GIInterfaceInfo *field_iface_info;
59             PyObject *py_type;
60
61             field_iface_info = g_type_info_get_interface (field_type_info);
62             py_type = _pygi_type_import_by_gi_info ((GIBaseInfo *) field_iface_info);
63
64             if (py_type != NULL && PyObject_IsInstance (py_arg, py_type)) {
65                 is_member = TRUE;
66             }
67
68             Py_XDECREF (py_type);
69             g_base_info_unref ( ( GIBaseInfo *) field_iface_info);
70         }
71
72         g_base_info_unref ( ( GIBaseInfo *) field_type_info);
73         g_base_info_unref ( ( GIBaseInfo *) field_info);
74
75         if (is_member)
76             break;
77     }
78
79     return is_member;
80 }
81
82
83 /*
84  * GValue from Python
85  */
86
87 /* pygi_arg_gvalue_from_py_marshal:
88  * py_arg: (in):
89  * arg: (out):
90  * transfer:
91  * copy_reference: TRUE if arg should use the pointer reference held by py_arg
92  *                 when it is already holding a GValue vs. copying the value.
93  */
94 gboolean
95 pygi_arg_gvalue_from_py_marshal (PyObject *py_arg,
96                                  GIArgument *arg,
97                                  GITransfer transfer,
98                                  gboolean copy_reference) {
99     GValue *value;
100     GType object_type;
101
102     object_type = pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
103     if (object_type == G_TYPE_INVALID) {
104         PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType");
105         return FALSE;
106     }
107
108     /* if already a gvalue, use that, else marshal into gvalue */
109     if (object_type == G_TYPE_VALUE) {
110         GValue *source_value = pyg_boxed_get (py_arg, GValue);
111         if (copy_reference) {
112             value = source_value;
113         } else {
114             value = g_slice_new0 (GValue);
115             g_value_init (value, G_VALUE_TYPE (source_value));
116             g_value_copy (source_value, value);
117         }
118     } else {
119         value = g_slice_new0 (GValue);
120         g_value_init (value, object_type);
121         if (pyg_value_from_pyobject (value, py_arg) < 0) {
122             g_slice_free (GValue, value);
123             PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
124             return FALSE;
125         }
126     }
127
128     arg->v_pointer = value;
129     return TRUE;
130 }
131
132 void
133 pygi_arg_gvalue_from_py_cleanup (PyGIInvokeState *state,
134                                  PyGIArgCache    *arg_cache,
135                                  PyObject        *py_arg,
136                                  gpointer         data,
137                                  gboolean         was_processed)
138 {
139     /* Note py_arg can be NULL for hash table which is a bug. */
140     if (was_processed && py_arg != NULL) {
141         GType py_object_type =
142             pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
143
144         /* When a GValue was not passed, it means the marshalers created a new
145          * one to pass in, clean this up.
146          */
147         if (py_object_type != G_TYPE_VALUE) {
148             g_value_unset ((GValue *) data);
149             g_slice_free (GValue, data);
150         }
151     }
152 }
153
154 /* pygi_arg_gclosure_from_py_marshal:
155  * py_arg: (in):
156  * arg: (out):
157  */
158 static gboolean
159 pygi_arg_gclosure_from_py_marshal (PyObject   *py_arg,
160                                    GIArgument *arg,
161                                    GITransfer  transfer)
162 {
163     GClosure *closure;
164     GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE);
165
166     if ( !(PyCallable_Check(py_arg) ||
167            g_type_is_a (object_gtype, G_TYPE_CLOSURE))) {
168         PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
169                       py_arg->ob_type->tp_name);
170         return FALSE;
171     }
172
173     if (g_type_is_a (object_gtype, G_TYPE_CLOSURE)) {
174         closure = (GClosure *)pyg_boxed_get (py_arg, void);
175         /* Make sure we own a ref which is held until cleanup. */
176         if (closure != NULL) {
177             g_closure_ref (closure);
178         }
179     } else {
180         closure = pyg_closure_new (py_arg, NULL, NULL);
181         g_closure_ref (closure);
182         g_closure_sink (closure);
183     }
184
185     if (closure == NULL) {
186         PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
187         return FALSE;
188     }
189
190     /* Add an additional ref when transfering everything to the callee. */
191     if (transfer == GI_TRANSFER_EVERYTHING) {
192         g_closure_ref (closure);
193     }
194
195     arg->v_pointer = closure;
196     return TRUE;
197 }
198
199 static void
200 arg_gclosure_from_py_cleanup (PyGIInvokeState *state,
201                               PyGIArgCache    *arg_cache,
202                               PyObject        *py_arg,
203                               gpointer         cleanup_data,
204                               gboolean         was_processed)
205 {
206     if (cleanup_data != NULL) {
207         g_closure_unref (cleanup_data);
208     }
209 }
210
211 /* pygi_arg_struct_from_py_marshal:
212  *
213  * Dispatcher to various sub marshalers
214  */
215 gboolean
216 pygi_arg_struct_from_py_marshal (PyObject *py_arg,
217                                  GIArgument *arg,
218                                  const gchar *arg_name,
219                                  GIBaseInfo *interface_info,
220                                  GType g_type,
221                                  PyObject *py_type,
222                                  GITransfer transfer,
223                                  gboolean copy_reference,
224                                  gboolean is_foreign,
225                                  gboolean is_pointer)
226 {
227     gboolean is_union = FALSE;
228
229     if (py_arg == Py_None) {
230         arg->v_pointer = NULL;
231         return TRUE;
232     }
233
234     /* FIXME: handle this large if statement in the cache
235      *        and set the correct marshaller
236      */
237
238     if (g_type_is_a (g_type, G_TYPE_CLOSURE)) {
239         return pygi_arg_gclosure_from_py_marshal (py_arg, arg, transfer);
240     } else if (g_type_is_a (g_type, G_TYPE_VALUE)) {
241         return pygi_arg_gvalue_from_py_marshal(py_arg,
242                                                arg,
243                                                transfer,
244                                                copy_reference);
245     } else if (is_foreign) {
246         PyObject *success;
247         success = pygi_struct_foreign_convert_to_g_argument (py_arg,
248                                                              interface_info,
249                                                              transfer,
250                                                              arg);
251
252         return (success == Py_None);
253     } else if (!PyObject_IsInstance (py_arg, py_type)) {
254         /* first check to see if this is a member of the expected union */
255         is_union = _is_union_member (interface_info, py_arg);
256         if (!is_union) {
257             goto type_error;
258         }
259     }
260
261     if (g_type_is_a (g_type, G_TYPE_BOXED)) {
262         /* Additionally use pyg_type_from_object to pull the stashed __gtype__
263          * attribute off of the input argument for type checking. This is needed
264          * to work around type discrepancies in cases with aliased (typedef) types.
265          * e.g. GtkAllocation, GdkRectangle.
266          * See: https://bugzilla.gnomethere are .org/show_bug.cgi?id=707140
267          */
268         if (is_union || pyg_boxed_check (py_arg, g_type) ||
269                 g_type_is_a (pyg_type_from_object (py_arg), g_type)) {
270             arg->v_pointer = pyg_boxed_get (py_arg, void);
271             if (transfer == GI_TRANSFER_EVERYTHING) {
272                 arg->v_pointer = g_boxed_copy (g_type, arg->v_pointer);
273             }
274         } else {
275             goto type_error;
276         }
277
278     } else if (g_type_is_a (g_type, G_TYPE_POINTER) ||
279                g_type_is_a (g_type, G_TYPE_VARIANT) ||
280                g_type  == G_TYPE_NONE) {
281         g_warn_if_fail (g_type_is_a (g_type, G_TYPE_VARIANT) || !is_pointer || transfer == GI_TRANSFER_NOTHING);
282
283         if (g_type_is_a (g_type, G_TYPE_VARIANT) &&
284                 pyg_type_from_object (py_arg) != G_TYPE_VARIANT) {
285             PyErr_SetString (PyExc_TypeError, "expected GLib.Variant");
286             return FALSE;
287         }
288         arg->v_pointer = pyg_pointer_get (py_arg, void);
289         if (transfer == GI_TRANSFER_EVERYTHING) {
290             g_variant_ref ((GVariant *)arg->v_pointer);
291         }
292
293     } else {
294         PyErr_Format (PyExc_NotImplementedError,
295                       "structure type '%s' is not supported yet",
296                       g_type_name(g_type));
297         return FALSE;
298     }
299     return TRUE;
300
301 type_error:
302     {
303         gchar *type_name = _pygi_g_base_info_get_fullname (interface_info);
304         PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
305
306         PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s",
307                       arg_name ? arg_name : "self",
308                       type_name,
309                       module ? PYGLIB_PyUnicode_AsString(module) : "",
310                       module ? "." : "",
311                       py_arg->ob_type->tp_name);
312         if (module)
313             Py_DECREF (module);
314         g_free (type_name);
315         return FALSE;
316     }
317 }
318
319 static gboolean
320 arg_struct_from_py_marshal_adapter (PyGIInvokeState   *state,
321                                     PyGICallableCache *callable_cache,
322                                     PyGIArgCache      *arg_cache,
323                                     PyObject          *py_arg,
324                                     GIArgument        *arg,
325                                     gpointer          *cleanup_data)
326 {
327     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
328
329     gboolean res =  pygi_arg_struct_from_py_marshal (py_arg,
330                                                      arg,
331                                                      arg_cache->arg_name,
332                                                      iface_cache->interface_info,
333                                                      iface_cache->g_type,
334                                                      iface_cache->py_type,
335                                                      arg_cache->transfer,
336                                                      TRUE, /*copy_reference*/
337                                                      iface_cache->is_foreign,
338                                                      arg_cache->is_pointer);
339
340     /* Assume struct marshaling is always a pointer and assign cleanup_data
341      * here rather than passing it further down the chain.
342      */
343     *cleanup_data = arg->v_pointer;
344     return res;
345 }
346
347 static void
348 arg_foreign_from_py_cleanup (PyGIInvokeState *state,
349                              PyGIArgCache    *arg_cache,
350                              PyObject        *py_arg,
351                              gpointer         data,
352                              gboolean         was_processed)
353 {
354     if (state->failed && was_processed) {
355         pygi_struct_foreign_release (
356             ( (PyGIInterfaceCache *)arg_cache)->interface_info,
357             data);
358     }
359 }
360
361
362 PyObject *
363 pygi_arg_struct_to_py_marshal (GIArgument *arg,
364                                GIInterfaceInfo *interface_info,
365                                GType g_type,
366                                PyObject *py_type,
367                                GITransfer transfer,
368                                gboolean is_allocated,
369                                gboolean is_foreign)
370 {
371     PyObject *py_obj = NULL;
372
373     if (arg->v_pointer == NULL) {
374         Py_RETURN_NONE;
375     }
376
377     if (g_type_is_a (g_type, G_TYPE_VALUE)) {
378         py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
379     } else if (is_foreign) {
380         py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info,
381                                                               transfer,
382                                                               arg->v_pointer);
383     } else if (g_type_is_a (g_type, G_TYPE_BOXED)) {
384         if (py_type) {
385             /* Force a boxed copy if we are not transfered ownership and the
386              * memory is not caller allocated. */
387             py_obj = _pygi_boxed_new ((PyTypeObject *) py_type,
388                                       arg->v_pointer,
389                                       transfer == GI_TRANSFER_NOTHING && !is_allocated,
390                                       is_allocated ?
391                                               g_struct_info_get_size(interface_info) : 0);
392         }
393     } else if (g_type_is_a (g_type, G_TYPE_POINTER)) {
394         if (py_type == NULL ||
395                 !PyType_IsSubtype ((PyTypeObject *) py_type, &PyGIStruct_Type)) {
396             g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
397             py_obj = pyg_pointer_new (g_type, arg->v_pointer);
398         } else {
399             py_obj = _pygi_struct_new ( (PyTypeObject *) py_type,
400                                        arg->v_pointer,
401                                        transfer == GI_TRANSFER_EVERYTHING);
402         }
403     } else if (g_type_is_a (g_type, G_TYPE_VARIANT)) {
404         /* Note: sink the variant (add a ref) only if we are not transfered ownership.
405          * GLib.Variant overrides __del__ which will then call "g_variant_unref" for
406          * cleanup in either case. */
407         if (py_type) {
408             if (transfer == GI_TRANSFER_NOTHING) {
409                 g_variant_ref_sink (arg->v_pointer);
410             }
411             py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
412                                        arg->v_pointer,
413                                        FALSE);
414         }
415     } else if (g_type == G_TYPE_NONE) {
416         if (py_type) {
417             py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
418                                        arg->v_pointer,
419                                        transfer == GI_TRANSFER_EVERYTHING || is_allocated);
420         }
421     } else {
422         PyErr_Format (PyExc_NotImplementedError,
423                       "structure type '%s' is not supported yet",
424                       g_type_name (g_type));
425     }
426
427     return py_obj;
428 }
429
430 static PyObject *
431 arg_struct_to_py_marshal_adapter (PyGIInvokeState   *state,
432                                   PyGICallableCache *callable_cache,
433                                   PyGIArgCache      *arg_cache,
434                                   GIArgument        *arg)
435 {
436     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
437
438     return pygi_arg_struct_to_py_marshal (arg,
439                                           iface_cache->interface_info,
440                                           iface_cache->g_type,
441                                           iface_cache->py_type,
442                                           arg_cache->transfer,
443                                           arg_cache->is_caller_allocates,
444                                           iface_cache->is_foreign);
445 }
446
447 static PyObject *
448 arg_boxed_to_py_marshal_pass_by_ref (PyGIInvokeState   *state,
449                                      PyGICallableCache *callable_cache,
450                                      PyGIArgCache      *arg_cache,
451                                      GIArgument        *arg)
452 {
453     PyObject *py_obj = NULL;
454     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
455
456     if (arg->v_pointer == NULL) {
457         Py_RETURN_NONE;
458     }
459
460     if (g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
461         if (iface_cache->py_type) {
462             py_obj = _pygi_boxed_new ((PyTypeObject *) iface_cache->py_type,
463                                       arg->v_pointer,
464                                       FALSE, /* copy_boxed */
465                                       0);    /* slice_alloc */
466             ((PyGBoxed *)py_obj)->free_on_dealloc = FALSE;
467         }
468     } else {
469         PyErr_Format (PyExc_NotImplementedError,
470                       "expected boxed type but got %s",
471                       g_type_name (iface_cache->g_type));
472     }
473
474     return py_obj;
475 }
476
477 static void
478 arg_foreign_to_py_cleanup (PyGIInvokeState *state,
479                            PyGIArgCache    *arg_cache,
480                            PyObject        *dummy,
481                            gpointer         data,
482                            gboolean         was_processed)
483 {
484     if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
485         pygi_struct_foreign_release (
486             ( (PyGIInterfaceCache *)arg_cache)->interface_info,
487             data);
488     }
489 }
490
491 static gboolean
492 arg_type_class_from_py_marshal (PyGIInvokeState   *state,
493                                 PyGICallableCache *callable_cache,
494                                 PyGIArgCache      *arg_cache,
495                                 PyObject          *py_arg,
496                                 GIArgument        *arg,
497                                 gpointer          *cleanup_data)
498 {
499     GType gtype = pyg_type_from_object (py_arg);
500
501     if (G_TYPE_IS_CLASSED (gtype)) {
502         arg->v_pointer = g_type_class_ref (gtype);
503         *cleanup_data = arg->v_pointer;
504         return TRUE;
505     } else {
506         PyErr_Format (PyExc_TypeError,
507                       "Unable to retrieve a GObject type class from \"%s\".",
508                       Py_TYPE(py_arg)->tp_name);
509         return FALSE;
510     }
511 }
512
513 static void
514 arg_type_class_from_py_cleanup (PyGIInvokeState *state,
515                                 PyGIArgCache    *arg_cache,
516                                 PyObject        *py_arg,
517                                 gpointer         data,
518                                 gboolean         was_processed)
519 {
520     if (was_processed) {
521         g_type_class_unref (data);
522     }
523 }
524
525 static void
526 arg_struct_from_py_setup (PyGIArgCache     *arg_cache,
527                           GIInterfaceInfo  *iface_info,
528                           GITransfer        transfer)
529 {
530     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
531
532     if (g_struct_info_is_gtype_struct ((GIStructInfo*)iface_info)) {
533         arg_cache->from_py_marshaller = arg_type_class_from_py_marshal;
534         /* Since we always add a ref in the marshalling, only unref the
535          * GTypeClass when we don't transfer ownership. */
536         if (transfer == GI_TRANSFER_NOTHING) {
537             arg_cache->from_py_cleanup = arg_type_class_from_py_cleanup;
538         }
539
540     } else {
541         arg_cache->from_py_marshaller = arg_struct_from_py_marshal_adapter;
542
543         if (g_type_is_a (iface_cache->g_type, G_TYPE_CLOSURE)) {
544             arg_cache->from_py_cleanup = arg_gclosure_from_py_cleanup;
545
546         } else if (iface_cache->g_type == G_TYPE_VALUE) {
547             arg_cache->from_py_cleanup = pygi_arg_gvalue_from_py_cleanup;
548
549         } else if (iface_cache->is_foreign) {
550             arg_cache->from_py_cleanup = arg_foreign_from_py_cleanup;
551         }
552     }
553 }
554
555 static void
556 arg_struct_to_py_setup (PyGIArgCache     *arg_cache,
557                         GIInterfaceInfo  *iface_info,
558                         GITransfer        transfer,
559                         GIArgInfo        *arg_info)
560 {
561     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
562
563     /* HACK to force GtkTreeModel:iter_next() and iter_previous() vfunc implementations
564      * to receive their Gtk.TreeIter argument as pass-by-reference. We create a new
565      * PyGIBoxed wrapper which does not copy the memory and also does not free it.
566      * This is needed to hack the noted vfunc implementations so they can continue
567      * working with bug https://bugzilla.gnome.org/show_bug.cgi?id=722899
568      * being fixed. This hack should be removed once GTK+ has fixed bug
569      * https://bugzilla.gnome.org/show_bug.cgi?id=734465
570      * and we've moved to a new major version.
571      */
572     if (arg_info && g_strcmp0 (iface_cache->type_name, "Gtk.TreeIter") == 0) {
573
574         /* GICallbackInfo */
575         GIBaseInfo *info = g_base_info_get_container (arg_info);
576         if (info && g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK &&
577                 (g_strcmp0 (g_base_info_get_name (info), "iter_next") == 0 ||
578                  g_strcmp0 (g_base_info_get_name (info), "iter_previous") == 0)) {
579
580             /* GITypeInfo */
581             info = g_base_info_get_container (info);
582             if (info && g_base_info_get_type (info) == GI_INFO_TYPE_TYPE &&
583                     g_type_info_get_tag ((GITypeInfo *)info) == GI_TYPE_TAG_INTERFACE) {
584
585                 /* GIFieldInfo */
586                 info = g_base_info_get_container (info);
587                 if (info && g_base_info_get_type (info) == GI_INFO_TYPE_FIELD) {
588
589                     /* GIStructInfo */
590                     info = g_base_info_get_container (info);
591                     if (info && g_base_info_get_type (info) == GI_INFO_TYPE_STRUCT &&
592                             g_strcmp0 (g_base_info_get_name (info), "TreeModelIface") == 0) {
593                         arg_cache->to_py_marshaller = arg_boxed_to_py_marshal_pass_by_ref;
594                     }
595                 }
596             }
597         }
598     }
599
600     if (arg_cache->to_py_marshaller == NULL) {
601         arg_cache->to_py_marshaller = arg_struct_to_py_marshal_adapter;
602     }
603
604     if (iface_cache->is_foreign)
605         arg_cache->to_py_cleanup = arg_foreign_to_py_cleanup;
606 }
607
608 PyGIArgCache *
609 pygi_arg_struct_new_from_info (GITypeInfo      *type_info,
610                                GIArgInfo       *arg_info,
611                                GITransfer       transfer,
612                                PyGIDirection    direction,
613                                GIInterfaceInfo *iface_info)
614 {
615     PyGIArgCache *cache = NULL;
616     PyGIInterfaceCache *iface_cache;
617
618     cache = pygi_arg_interface_new_from_info (type_info,
619                                               arg_info,
620                                               transfer,
621                                               direction,
622                                               iface_info);
623     if (cache == NULL)
624         return NULL;
625
626     iface_cache = (PyGIInterfaceCache *)cache;
627     iface_cache->is_foreign = (g_base_info_get_type ((GIBaseInfo *) iface_info) == GI_INFO_TYPE_STRUCT) &&
628                               (g_struct_info_is_foreign ((GIStructInfo*) iface_info));
629
630     if (direction & PYGI_DIRECTION_FROM_PYTHON) {
631         arg_struct_from_py_setup (cache, iface_info, transfer);
632     }
633
634     if (direction & PYGI_DIRECTION_TO_PYTHON) {
635         arg_struct_to_py_setup (cache, iface_info, transfer, arg_info);
636     }
637
638     return cache;
639 }