| /* |
| * 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 <qpid/dispatch/python_embedded.h> |
| #include "config_private.h" |
| #include <qpid/dispatch/alloc.h> |
| #include <qpid/dispatch/log.h> |
| |
| #define PYTHON_MODULE "qpid_dispatch_internal.config" |
| |
| static const char *log_module = "CONFIG"; |
| |
| struct qd_config_t { |
| PyObject *pModule; |
| PyObject *pClass; |
| PyObject *pObject; |
| }; |
| |
| ALLOC_DECLARE(qd_config_t); |
| ALLOC_DEFINE(qd_config_t); |
| |
| void qd_config_initialize() |
| { |
| qd_python_start(); |
| } |
| |
| |
| void qd_config_finalize() |
| { |
| qd_python_stop(); |
| } |
| |
| |
| qd_config_t *qd_config(const char *filename) |
| { |
| qd_config_t *config = new_qd_config_t(); |
| |
| // |
| // Load the Python configuration module and get a reference to the config class. |
| // |
| PyObject *pName = PyString_FromString(PYTHON_MODULE); |
| config->pModule = PyImport_Import(pName); |
| Py_DECREF(pName); |
| |
| if (!config->pModule) { |
| PyErr_Print(); |
| free_qd_config_t(config); |
| qd_log(log_module, LOG_ERROR, "Unable to load configuration module: %s", PYTHON_MODULE); |
| return 0; |
| } |
| |
| config->pClass = PyObject_GetAttrString(config->pModule, "DispatchConfig"); |
| if (!config->pClass || !PyClass_Check(config->pClass)) { |
| PyErr_Print(); |
| Py_DECREF(config->pModule); |
| free_qd_config_t(config); |
| qd_log(log_module, LOG_ERROR, "Problem with configuration module: Missing DispatchConfig class"); |
| return 0; |
| } |
| |
| // |
| // Instantiate the DispatchConfig class, passing in the configuration file name. |
| // |
| PyObject *pArgs = PyTuple_New(1); |
| PyObject *fname = PyString_FromString(filename); |
| PyTuple_SetItem(pArgs, 0, fname); |
| config->pObject = PyInstance_New(config->pClass, pArgs, 0); |
| Py_DECREF(pArgs); |
| |
| if (config->pObject == 0) { |
| PyErr_Print(); |
| Py_DECREF(config->pModule); |
| free_qd_config_t(config); |
| qd_log(log_module, LOG_ERROR, "Configuration file '%s' could not be read", filename); |
| return 0; |
| } |
| |
| return config; |
| } |
| |
| |
| void qd_config_read(qd_config_t *config) |
| { |
| PyObject *pMethod; |
| PyObject *pArgs; |
| PyObject *pResult; |
| |
| if (!config) |
| return; |
| |
| pMethod = PyObject_GetAttrString(config->pObject, "read_file"); |
| if (!pMethod || !PyCallable_Check(pMethod)) { |
| qd_log(log_module, LOG_ERROR, "Problem with configuration module: No callable 'item_count'"); |
| if (pMethod) { |
| Py_DECREF(pMethod); |
| } |
| return; |
| } |
| |
| pArgs = PyTuple_New(0); |
| pResult = PyObject_CallObject(pMethod, pArgs); |
| Py_DECREF(pArgs); |
| if (pResult) { |
| Py_DECREF(pResult); |
| } else { |
| PyErr_Print(); |
| } |
| Py_DECREF(pMethod); |
| } |
| |
| |
| void qd_config_free(qd_config_t *config) |
| { |
| if (config) { |
| Py_DECREF(config->pClass); |
| Py_DECREF(config->pModule); |
| free_qd_config_t(config); |
| } |
| } |
| |
| |
| int qd_config_item_count(const qd_config_t *config, const char *section) |
| { |
| PyObject *pSection; |
| PyObject *pMethod; |
| PyObject *pArgs; |
| PyObject *pResult; |
| int result = 0; |
| |
| if (!config) |
| return 0; |
| |
| pMethod = PyObject_GetAttrString(config->pObject, "item_count"); |
| if (!pMethod || !PyCallable_Check(pMethod)) { |
| qd_log(log_module, LOG_ERROR, "Problem with configuration module: No callable 'item_count'"); |
| if (pMethod) { |
| Py_DECREF(pMethod); |
| } |
| return 0; |
| } |
| |
| pSection = PyString_FromString(section); |
| pArgs = PyTuple_New(1); |
| PyTuple_SetItem(pArgs, 0, pSection); |
| pResult = PyObject_CallObject(pMethod, pArgs); |
| Py_DECREF(pArgs); |
| if (pResult && PyInt_Check(pResult)) |
| result = (int) PyInt_AsLong(pResult); |
| if (pResult) { |
| Py_DECREF(pResult); |
| } |
| Py_DECREF(pMethod); |
| |
| return result; |
| } |
| |
| |
| static PyObject *item_value(const qd_config_t *config, const char *section, int index, const char* key, const char* method) |
| { |
| PyObject *pSection; |
| PyObject *pIndex; |
| PyObject *pKey; |
| PyObject *pMethod; |
| PyObject *pArgs; |
| PyObject *pResult; |
| |
| if (!config) |
| return 0; |
| |
| pMethod = PyObject_GetAttrString(config->pObject, method); |
| if (!pMethod || !PyCallable_Check(pMethod)) { |
| qd_log(log_module, LOG_ERROR, "Problem with configuration module: No callable '%s'", method); |
| if (pMethod) { |
| Py_DECREF(pMethod); |
| } |
| return 0; |
| } |
| |
| pSection = PyString_FromString(section); |
| pIndex = PyInt_FromLong((long) index); |
| pKey = PyString_FromString(key); |
| pArgs = PyTuple_New(3); |
| PyTuple_SetItem(pArgs, 0, pSection); |
| PyTuple_SetItem(pArgs, 1, pIndex); |
| PyTuple_SetItem(pArgs, 2, pKey); |
| pResult = PyObject_CallObject(pMethod, pArgs); |
| Py_DECREF(pArgs); |
| Py_DECREF(pMethod); |
| |
| return pResult; |
| } |
| |
| |
| const char *qd_config_item_value_string(const qd_config_t *config, const char *section, int index, const char* key) |
| { |
| PyObject *pResult = item_value(config, section, index, key, "value_string"); |
| char *value = 0; |
| |
| if (pResult && PyString_Check(pResult)) { |
| Py_ssize_t size = PyString_Size(pResult); |
| value = (char*) malloc(size + 1); |
| strncpy(value, PyString_AsString(pResult), size + 1); |
| } |
| |
| if (pResult) { |
| Py_DECREF(pResult); |
| } |
| |
| return value; |
| } |
| |
| |
| uint32_t qd_config_item_value_int(const qd_config_t *config, const char *section, int index, const char* key) |
| { |
| PyObject *pResult = item_value(config, section, index, key, "value_int"); |
| uint32_t value = 0; |
| |
| if (pResult && PyLong_Check(pResult)) |
| value = (uint32_t) PyLong_AsLong(pResult); |
| |
| if (pResult) { |
| Py_DECREF(pResult); |
| } |
| |
| return value; |
| } |
| |
| |
| int qd_config_item_value_bool(const qd_config_t *config, const char *section, int index, const char* key) |
| { |
| PyObject *pResult = item_value(config, section, index, key, "value_bool"); |
| int value = 0; |
| |
| if (pResult && pResult != Py_None) |
| value = 1; |
| |
| if (pResult) { |
| Py_DECREF(pResult); |
| } |
| |
| return value; |
| } |
| |
| |