[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/litsand/Programs-Scripts/master/pywrapper/pywrapper.cpp [Back]  [Original]

/*      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 3 of the License, or
 *      (at your option) any later version.
 *      
 *      This program 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 General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 *      
 *      Author: 
 *      Matias Fontanini
 * 
 */

#include 
#include "pywrapper.h"

using std::runtime_error;
using std::string;

namespace Python {
Object::Object() {
    
}

Object::Object(PyObject *obj) : py_obj(make_pyshared(obj)) {
    
}

Python::Object::pyshared_ptr Object::make_pyshared(PyObject *obj) {
    return pyshared_ptr(obj, [](PyObject *obj) { Py_XDECREF(obj); });
}

Object Object::from_script(const string &script_path) {
    char arr[] = "path";
    PyObject *path(PySys_GetObject(arr));
    string base_path("."), file_path;
    size_t last_slash(script_path.rfind("/"));
    if(last_slash != string::npos) {
        if(last_slash >= script_path.size() - 2)
            throw runtime_error("Invalid script path");
        base_path = script_path.substr(0, last_slash);
        file_path = script_path.substr(last_slash + 1);
    }
    else
        file_path = script_path;
    if(file_path.rfind(".py") == file_path.size() - 3)
        file_path = file_path.substr(0, file_path.size() - 3);
    pyunique_ptr pwd(PyString_FromString(base_path.c_str()));
    
    PyList_Append(path, pwd.get());
    /* We don't need that string value anymore, so deref it */
    PyObject *py_ptr(PyImport_ImportModule(file_path.c_str()));
    if(!py_ptr) {
        print_error();
        throw runtime_error("Failed to load script"); 
    }
    return {py_ptr};
}

PyObject *Object::load_function(const std::string &name) {
    PyObject *obj(PyObject_GetAttrString(py_obj.get(), name.c_str()));
    if(!obj)
        throw std::runtime_error("Failed to find function");
    return obj;
}

Object Object::call_function(const std::string &name) {
    pyunique_ptr func(load_function(name));
    PyObject *ret(PyObject_CallObject(func.get(), 0));
    if(!ret)
        throw std::runtime_error("Failed to call function");
    return {ret};
}

Object Object::get_attr(const std::string &name) {
    PyObject *obj(PyObject_GetAttrString(py_obj.get(), name.c_str()));
    if(!obj)
        throw std::runtime_error("Unable to find attribute '" + name + '\'');
    return {obj};
}

bool Object::has_attr(const std::string &name) {
    try {
        get_attr(name);
        return true;
    } catch(std::runtime_error&) {
        return false;
    }
}

void initialize() {
    Py_Initialize();
}

void finalize() {
    Py_Finalize();
}

void clear_error() {
    PyErr_Clear();
}

void print_error() {
    PyErr_Print();
}

void print_object(PyObject *obj) {
    PyObject_Print(obj, stdout, 0);
}

// Allocation methods

PyObject *alloc_pyobject(const std::string &str) {
    return PyString_FromString(str.c_str());
}

PyObject *alloc_pyobject(const std::vector &val, size_t sz) {
    return PyByteArray_FromStringAndSize(val.data(), sz);
}

PyObject *alloc_pyobject(const std::vector &val) {
    return alloc_pyobject(val, val.size());
}

PyObject *alloc_pyobject(const char *cstr) {
    return PyString_FromString(cstr);
}

PyObject *alloc_pyobject(bool value) {
    return PyBool_FromLong(value);
}

PyObject *alloc_pyobject(double num) {
    return PyFloat_FromDouble(num);
}

bool is_py_int(PyObject *obj) {
    return PyInt_Check(obj);
}

bool is_py_float(PyObject *obj) {
    return PyFloat_Check(obj);
}

bool convert(PyObject *obj, std::string &val) {
    if(!PyString_Check(obj))
        return false;
    val = PyString_AsString(obj);
    return true;
}

bool convert(PyObject *obj, std::vector &val) {
    if(!PyByteArray_Check(obj))
        return false;
    if(val.size() < (size_t)PyByteArray_Size(obj))
        val.resize(PyByteArray_Size(obj));
    std::copy(PyByteArray_AsString(obj), 
      PyByteArray_AsString(obj) + PyByteArray_Size(obj), 
      val.begin());
    return true;
}

/*bool convert(PyObject *obj, Py_ssize_t &val) {
    return generic_convert(obj, is_py_int, PyInt_AsSsize_t, val);
}*/
bool convert(PyObject *obj, bool &value) {
    if(obj == Py_False)
        value = false;
    else if(obj == Py_True)
        value = true;
    else
        return false;
    return true;
}

bool convert(PyObject *obj, double &val) {
    return generic_convert(obj, is_py_float, PyFloat_AsDouble, val);
}

/*bool convert(PyObject *obj, size_t &val) {
    return generic_convert(obj, is_py_int, PyInt_AsLong, val);
}*/


}

Web Proxy Viewer  |  New URL  |  Original Page