📄 pst-helpers.c
字号:
/* * Copyright (c) 2004 Jean-Yves Lefort * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include <Python.h>#define NO_IMPORT_PYGOBJECT#include <pygobject.h>#include <glib/gi18n.h>#include "streamtuner.h"#include "pst-helpers.h"#include "pst-category.h"#include "pst-stream.h"#include "pst-transfer-session.h"/*** function declarations ***************************************************/static gboolean pst_categories_sequence_as_gnode_real (PyObject *categories, GNode *parent);static gboolean pst_categories_sequence_as_gnode_free_cb (GNode *node, gpointer data);static gboolean pst_streams_mapping_as_ghashtable_insert (GHashTable *hash, PyObject *pair);/*** implementation **********************************************************/intpst_strings_as_gslist (PyObject *strings, GSList **gslist){ int i; int len; g_return_val_if_fail(strings != NULL, FALSE); g_return_val_if_fail(gslist != NULL, FALSE); len = PySequence_Length(strings); if (len == -1) return 0; *gslist = NULL; for (i = 0; i < len; i++) { PyObject *item; const char *str; item = PySequence_ITEM(strings, i); if (! item) goto exception; str = PyString_AsString(item); Py_DECREF(item); if (! str) /* exception raised by PyString_AsString() */ goto exception; *gslist = g_slist_append(*gslist, g_strdup(str)); } return 1; exception: g_slist_foreach(*gslist, (GFunc) g_free, NULL); g_slist_free(*gslist); return 0;}PyObject *pst_strings_from_gslist (GSList *gslist){ PyObject *tuple; GSList *l; int i = 0; tuple = PyTuple_New(g_slist_length(gslist)); if (! tuple) return NULL; for (l = gslist; l; l = l->next) { PyObject *str; str = PyString_FromString(l->data); if (! str) { Py_DECREF(tuple); return NULL; } PyTuple_SET_ITEM(tuple, i++, str); } return tuple;}PyObject *pst_none (void){ Py_INCREF(Py_None); return Py_None;}PyObject *pst_string_from_string_or_null (const char *str){ return str ? PyString_FromString(str) : pst_none();}PyObject *pst_string_take_string (char *str){ PyObject *pstr; g_return_val_if_fail(str != NULL, NULL); pstr = PyString_FromString(str); g_free(str); return pstr;}PyObject *pst_string_take_string_or_null (char *str){ return str ? pst_string_take_string(str) : pst_none();}intpst_string_dup_string_or_null (PyObject *value, char **str){ const char *_str = NULL; g_return_val_if_fail(str != NULL, -1); if (value) { _str = PyString_AsString(value); if (! _str) return -1; } g_free(*str); *str = g_strdup(_str); return 0;}gbooleanpst_categories_sequence_as_gnode (PyObject *categories, GNode **node){ GNode *_node; g_return_val_if_fail(categories != NULL, FALSE); g_return_val_if_fail(node != NULL, FALSE); _node = g_node_new(NULL); if (pst_categories_sequence_as_gnode_real(categories, _node)) { *node = _node; return TRUE; } else { g_node_traverse(_node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, pst_categories_sequence_as_gnode_free_cb, NULL); g_node_destroy(_node); return FALSE; }}static gbooleanpst_categories_sequence_as_gnode_real (PyObject *categories, GNode *parent){ GNode *prev = NULL; int len; int i; g_return_val_if_fail(categories != NULL, FALSE); g_return_val_if_fail(parent != NULL, FALSE); len = PySequence_Length(categories); if (len == -1) return FALSE; for (i = 0; i < len; i++) { PyObject *item; gboolean status = FALSE; item = PySequence_ITEM(categories, i); if (! item) return FALSE; if (PySequence_Check(item)) { if (pst_categories_sequence_as_gnode_real(item, prev ? prev : parent)) status = TRUE; } else if (PyObject_TypeCheck(item, &PSTCategory_Type)) { PythonCategory *category; category = pst_category_copy(((PSTCategory *) item)->category); if (category) { prev = g_node_append_data(parent, category); status = TRUE; } } else PyErr_Format(PyExc_TypeError, _("a list element is not a sequence or %s object"), PSTCategory_Type.tp_name); Py_DECREF(item); if (! status) return FALSE; } return TRUE;}static gbooleanpst_categories_sequence_as_gnode_free_cb (GNode *node, gpointer data){ if (node->data) pst_category_free_cb(node->data, NULL); return FALSE; /* continue */}gbooleanpst_streams_sequence_as_glist (PyObject *streams, GList **list){ int i; int len; g_return_val_if_fail(streams != NULL, FALSE); g_return_val_if_fail(list != NULL, FALSE); len = PySequence_Length(streams); if (len == -1) return FALSE; *list = NULL; for (i = 0; i < len; i++) { PyObject *item; gboolean status; item = PySequence_ITEM(streams, i); if (! item) return FALSE; if (PyObject_TypeCheck(item, &PSTStream_Type)) { *list = g_list_append(*list, pst_stream_copy(((PSTStream *) item)->stream)); status = TRUE; } else { PyErr_Format(PyExc_TypeError, _("element %i of the streams sequence is not a %s object"), i, PSTStream_Type.tp_name); status = FALSE; } Py_DECREF(item); if (! status) return FALSE; } return TRUE;}gbooleanpst_streams_mapping_as_ghashtable (PyObject *streams, GHashTable **hash){ PyObject *items; int len; int i; gboolean status = FALSE; g_return_val_if_fail(streams != NULL, FALSE); g_return_val_if_fail(hash != NULL, FALSE); items = PyMapping_Items(streams); if (! items) return FALSE; len = PySequence_Length(items); if (len == -1) goto end; *hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < len; i++) { PyObject *pair; gboolean this_status; pair = PySequence_ITEM(items, i); if (! pair) goto end; this_status = pst_streams_mapping_as_ghashtable_insert(*hash, pair); Py_DECREF(pair); if (! this_status) goto end; } status = TRUE; /* success */ end: Py_DECREF(items); return status;}static gbooleanpst_streams_mapping_as_ghashtable_insert (GHashTable *hash, PyObject *pair){ PyObject *key; PyObject *value; const char *ckey; GList *list; gboolean status = FALSE; g_return_val_if_fail(hash != NULL, FALSE); g_return_val_if_fail(pair != NULL, FALSE); key = PySequence_GetItem(pair, 0); if (! key) return FALSE; value = PySequence_GetItem(pair, 1); if (! value) goto end; ckey = PyString_AsString(key); if (! ckey) goto end; if (! pst_streams_sequence_as_glist(value, &list)) goto end; g_hash_table_insert(hash, g_strdup(ckey), list); status = TRUE; end: Py_DECREF(key); Py_DECREF(value); return status;}voidpst_set_error (GError **err){ if (PyErr_ExceptionMatches(PSTExc_AbortError)) PyErr_Clear(); else { PyObject *ptype; PyObject *pvalue; PyObject *ptraceback; const char *value; PyErr_Fetch(&ptype, &pvalue, &ptraceback); value = PyString_AsString(pvalue); if (! value) { PyErr_Print(); value = _("a Python exception has occurred"); } g_set_error(err, 0, 0, "%s", value); PyErr_Restore(ptype, pvalue, ptraceback); PyErr_Print(); }}/* http://bugzilla.gnome.org/show_bug.cgi?id=160452 */intpst_value_from_pyobject (GValue *value, PyObject *obj){ if (PySequence_Check(obj) && G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY)) { GValueArray *value_array; int len; int i; len = PySequence_Length(obj); if (len == -1) { PyErr_Clear(); return -1; } value_array = g_value_array_new(len); for (i = 0; i < len; i++) { PyObject *item; GType type; GValue item_value = { 0, }; item = PySequence_GetItem(obj, i); if (! item) { PyErr_Clear(); g_value_array_free(value_array); return -1; } type = pyg_type_from_object((PyObject *) item->ob_type); if (! type) { PyErr_Clear(); g_value_array_free(value_array); Py_DECREF(item); return -1; } g_value_init(&item_value, type); if (pst_value_from_pyobject(&item_value, item) == -1) { g_value_array_free(value_array); Py_DECREF(item); g_value_unset(&item_value); return -1; } Py_DECREF(item); g_value_array_append(value_array, &item_value); g_value_unset(&item_value); } g_value_take_boxed(value, value_array); return 0; } else { int status; status = pyg_value_from_pyobject(value, obj); if (PyErr_Occurred()) /* http://bugzilla.gnome.org/show_bug.cgi?id=160595 */ PyErr_Clear(); return status; }}PyTypeObject *pst_pygobject_lookup_class (GType type){ PyTypeObject *type_object; type_object = pygobject_lookup_class(type); if (! type_object) PyErr_Format(PyExc_SystemError, _("unable to lookup PyGTK object type of %s"), g_type_name(type)); return type_object;}intpst_convert_widget (PyObject *object, GtkWidget **widget){ *widget = (GtkWidget *) pst_pygobject_get(object, GTK_TYPE_WIDGET); return *widget ? 1 : 0;}GObject *pst_pygobject_get (PyObject *object, GType type){ PyTypeObject *ptype; ptype = pst_pygobject_lookup_class(type); if (! ptype) return NULL; if (! PyObject_TypeCheck(object, ptype)) { PyErr_Format(PyExc_TypeError, _("not a %s object"), ptype->tp_name); return NULL; } return pygobject_get(object);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -