| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| |
| #include <Python.h> |
| #include <qpid/dispatch/error.h> |
| #include "dispatch_private.h" |
| #include "entity.h" |
| |
| struct qd_entity_t { |
| PyObject py_object; /* Any object supporting __set/get_item__, e.g. dict. */ |
| }; |
| |
| static PyObject* qd_entity_get_py(qd_entity_t* entity, const char* attribute) { |
| PyObject *py_key = PyString_FromString(attribute); |
| if (!py_key) return NULL; /* Don't set qd_error, caller will set if needed. */ |
| PyObject *value = PyObject_GetItem((PyObject*)entity, py_key); |
| Py_DECREF(py_key); |
| return value; |
| } |
| |
| bool qd_entity_has(qd_entity_t* entity, const char *attribute) { |
| PyObject *value = qd_entity_get_py(entity, attribute); |
| Py_XDECREF(value); |
| PyErr_Clear(); /* Ignore errors */ |
| return value; |
| } |
| |
| char *qd_entity_get_string(qd_entity_t *entity, const char* attribute) { |
| qd_error_clear(); |
| PyObject *py_obj = qd_entity_get_py(entity, attribute); |
| PyObject *py_str = py_obj ? PyObject_Str(py_obj) : NULL; |
| const char *cstr = py_str ? PyString_AsString(py_str) : NULL; |
| char* str = cstr ? strdup(cstr) : NULL; |
| Py_XDECREF(py_obj); |
| Py_XDECREF(py_str); |
| if (!str) qd_error_py(); |
| return str; |
| } |
| |
| long qd_entity_get_long(qd_entity_t *entity, const char* attribute) { |
| qd_error_clear(); |
| PyObject *py_obj = qd_entity_get_py(entity, attribute); |
| long result = py_obj ? PyInt_AsLong(py_obj) : -1; |
| Py_XDECREF(py_obj); |
| qd_error_py(); |
| return result; |
| } |
| |
| bool qd_entity_get_bool(qd_entity_t *entity, const char* attribute) { |
| qd_error_clear(); |
| PyObject *py_obj = qd_entity_get_py(entity, attribute); |
| bool result = py_obj ? PyObject_IsTrue(py_obj) : false; |
| Py_XDECREF(py_obj); |
| qd_error_py(); |
| return result; |
| } |
| |
| |
| char *qd_entity_opt_string(qd_entity_t *entity, const char* attribute, const char* default_value) |
| { |
| if (qd_entity_has(entity, attribute)) |
| return qd_entity_get_string(entity, attribute); |
| else |
| return default_value ? strdup(default_value) : NULL; |
| } |
| |
| long qd_entity_opt_long(qd_entity_t *entity, const char* attribute, long default_value) { |
| if (qd_entity_has(entity, attribute)) { |
| long result = qd_entity_get_long(entity, attribute); |
| if (!qd_error_code()) |
| return result; |
| } |
| return default_value; |
| } |
| |
| bool qd_entity_opt_bool(qd_entity_t *entity, const char* attribute, bool default_value) { |
| if (qd_entity_has(entity, attribute)) { |
| bool result = qd_entity_get_bool(entity, attribute); |
| if (!qd_error_code()) |
| return result; |
| } |
| return default_value; |
| } |
| |
| |
| /** |
| * Set a value for an entity attribute. If py_value == NULL then clear the attribute. |
| * If the attribute exists and is a list, append this value to the list. |
| * |
| * NOTE: This function will Py_XDECREF(py_value). |
| */ |
| qd_error_t qd_entity_set_py(qd_entity_t* entity, const char* attribute, PyObject* py_value) { |
| qd_error_clear(); |
| |
| int result = 0; |
| PyObject *py_key = PyString_FromString(attribute); |
| if (py_key) { |
| if (py_value == NULL) { /* Delete the attribute */ |
| result = PyObject_DelItem((PyObject*)entity, py_key); |
| PyErr_Clear(); /* Ignore error if it isn't there. */ |
| } |
| else { |
| PyObject *old = PyObject_GetItem((PyObject*)entity, py_key); |
| PyErr_Clear(); /* Ignore error if it isn't there. */ |
| if (old && PyList_Check(old)) /* Add to list */ |
| result = PyList_Append(old, py_value); |
| else /* Set attribute */ |
| result = PyObject_SetItem((PyObject*)entity, py_key, py_value); |
| Py_XDECREF(old); |
| } |
| } |
| Py_XDECREF(py_key); |
| Py_XDECREF(py_value); |
| return (py_key == NULL || result < 0) ? qd_error_py() : QD_ERROR_NONE; |
| } |
| |
| qd_error_t qd_entity_set_string(qd_entity_t *entity, const char* attribute, const char *value) { |
| return qd_entity_set_py(entity, attribute, value ? PyString_FromString(value) : 0); |
| } |
| |
| qd_error_t qd_entity_set_longp(qd_entity_t *entity, const char* attribute, const long *value) { |
| return qd_entity_set_py(entity, attribute, value ? PyInt_FromLong(*value) : 0); |
| } |
| |
| qd_error_t qd_entity_set_boolp(qd_entity_t *entity, const char *attribute, const bool *value) { |
| return qd_entity_set_py(entity, attribute, value ? PyBool_FromLong(*value) : 0); |
| } |
| |
| qd_error_t qd_entity_set_long(qd_entity_t *entity, const char* attribute, long value) { |
| return qd_entity_set_longp(entity, attribute, &value); |
| } |
| |
| qd_error_t qd_entity_set_bool(qd_entity_t *entity, const char *attribute, bool value) { |
| return qd_entity_set_boolp(entity, attribute, &value); |
| } |
| |
| qd_error_t qd_entity_clear(qd_entity_t *entity, const char *attribute) { |
| return qd_entity_set_py(entity, attribute, 0); |
| } |
| |
| #define CHECK(err) if (err) return qd_error_code() |
| |
| qd_error_t qd_entity_set_list(qd_entity_t *entity, const char *attribute) { |
| CHECK(qd_entity_clear(entity, attribute)); |
| return qd_entity_set_py(entity, attribute, PyList_New(0)); |
| } |
| |
| qd_error_t qd_entity_set_stringf(qd_entity_t *entity, const char* attribute, const char *format, ...) |
| { |
| // Calculate the size |
| char dummy[1]; |
| va_list ap; |
| va_start(ap, format); |
| int len = vsnprintf(dummy, 1, format, ap); |
| va_end(ap); |
| |
| char buf[len+1]; |
| va_start(ap, format); |
| vsnprintf(buf, len+1, format, ap); |
| va_end(ap); |
| |
| return qd_entity_set_string(entity, attribute, buf); |
| } |