Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
87 lines (77 sloc) 2.62 KB
/*
* Copyright (c) 2017 Cossack Labs Limited
*
* This file is a part of Hermes-core.
*
* Hermes-core is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Hermes-core 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Hermes-core. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "transport.h"
uint32_t transport_send(void *transport, const uint8_t *buf, const size_t buf_length) {
if (!transport || !buf || !buf_length) {
return HM_FAIL;
}
PyObject* buf_object = PyBytes_FromStringAndSize((char*)buf, buf_length);
if (!buf_object){
return HM_FAIL;
}
PyObject* method_name = PyUnicode_FromString("send");
if(!method_name){
Py_DECREF(buf_object);
return HM_FAIL;
}
PyObject* object = (PyObject*) transport;
Py_INCREF(object);
PyObject_CallMethodObjArgs(object, method_name, buf_object, NULL);
Py_DECREF(object);
Py_DECREF(method_name);
Py_DECREF(buf_object);
return HM_SUCCESS;
}
uint32_t transport_recv(void *transport, uint8_t *buf, size_t buf_length) {
if (!transport || !buf || !buf_length) {
return HM_FAIL;
}
PyObject *result = PyObject_CallMethod((PyObject *) transport, "receive", "I", buf_length);
if (!result) {
return HM_FAIL;
}
if (!(PyBytes_Check(result) || ((size_t) PyBytes_Size(result) != buf_length))) {
Py_DECREF(result);
return HM_FAIL;
}
memcpy(buf, PyBytes_AsString(result), buf_length);
return HM_SUCCESS;
}
hm_rpc_transport_t *transport_create(PyObject *transport) {
hm_rpc_transport_t *result = calloc(1, sizeof(hm_rpc_transport_t));
if (!result) {
return NULL;
}
// not assign transport itself to avoid free hm_rpc_transport_t->user_data without PY_DECREF
result->user_data = transport;
Py_INCREF(transport);
result->send = transport_send;
result->recv = transport_recv;
return result;
}
uint32_t transport_destroy(hm_rpc_transport_t **transport) {
if (!transport || !(*transport) || !((*transport)->user_data)) {
return HM_FAIL;
}
Py_DECREF((PyObject *) (*transport)->user_data);
free(*transport);
*transport = NULL;
return HM_SUCCESS;
}