blob: 35328c035e84af148d9c44cfaebe3aaca1f3bbd0 [file] [log] [blame]
/**
* @file err.c
* @author Radek Krejci <rkrejci@cesnet.cz>
* @brief NETCONF reply errors
*
* Copyright (c) 2017 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*/
/* Python API header */
#include <Python.h>
#include <structmember.h>
/* standard headers */
#include <string.h>
#include "netconf.h"
#include "../src/messages_p.h"
static void
ncErrFree(ncErrObject *self)
{
nc_client_err_clean(self->err, self->ctx);
Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
ncErrStr(ncErrObject *self)
{
uint16_t u, f = 0;
char *str = NULL;
if (self->err->type) {
asprintf(&str, "\"type\":\"%s\"", self->err->type);
}
if (self->err->tag) {
asprintf(&str, "%s%s\"tag\":\"%s\"", str ? str : "", str ? "," : "", self->err->tag);
}
if (self->err->severity) {
asprintf(&str, "%s%s\"severity\":\"%s\"", str ? str : "", str ? "," : "", self->err->severity);
}
if (self->err->apptag) {
asprintf(&str, "%s%s\"app-tag\":\"%s\"", str ? str : "", str ? "," : "", self->err->apptag);
}
if (self->err->path) {
asprintf(&str, "%s%s\"path\":\"%s\"", str ? str : "", str ? "," : "", self->err->path);
}
if (self->err->message) {
asprintf(&str, "%s%s\"message\":\"%s", str ? str : "", str ? "," : "", self->err->message);
if (self->err->message_lang) {
asprintf(&str, "%s (%s)\"", str, self->err->message_lang);
} else {
asprintf(&str, "%s\"", str);
}
}
if (self->err->sid || self->err->attr || self->err->elem || self->err->ns || self->err->other) {
asprintf(&str, "%s%s\"info\":{", str ? str : "", str ? "," : "");
if (self->err->sid) {
asprintf(&str, "%s%s\"session-id\":\"%s\"", str, f ? "," : "", self->err->sid);
f = 1;
}
if (self->err->attr_count) {
asprintf(&str, "%s%s\"bad-attr\":[", str, f ? "," : "");
for (u = 0; u < self->err->attr_count; u++) {
asprintf(&str, "%s%s\"%s\"", str, u ? "," : "", self->err->attr[u]);
}
asprintf(&str, "%s]", str);
f = 1;
}
if (self->err->elem_count) {
asprintf(&str, "%s%s\"bad-element\":[", str, f ? "," : "");
for (u = 0; u < self->err->elem_count; u++) {
asprintf(&str, "%s%s\"%s\"", str, u ? "," : "", self->err->elem[u]);
}
asprintf(&str, "%s]", str);
f = 1;
}
if (self->err->ns_count) {
asprintf(&str, "%s%s\"bad-namespace\":[", str, f ? "," : "");
for (u = 0; u < self->err->ns_count; u++) {
asprintf(&str, "%s%s\"%s\"", str, u ? "," : "", self->err->ns[u]);
}
asprintf(&str, "%s]", str);
f = 1;
}
if (self->err->other_count) {
for (u = 0; u < self->err->other_count; u++) {
asprintf(&str, "%s%s\"%s\":\"%s\"", str, f ? "," : "", self->err->other[u]->name, self->err->other[u]->content);
}
f = 1;
}
asprintf(&str, "%s}", str);
}
return PyUnicode_FromFormat("{%s}", str);
}
/*
* tp_getset callbacs held by ncErrGetSetters[]
*/
static PyObject *
ncErrGetType(ncErrObject *self, void *closure)
{
if (!self->err->type) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->type);
}
static PyObject *
ncErrGetTag(ncErrObject *self, void *closure)
{
if (!self->err->tag) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->tag);
}
static PyObject *
ncErrGetSeverity(ncErrObject *self, void *closure)
{
if (!self->err->severity) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->severity);
}
static PyObject *
ncErrGetAppTag(ncErrObject *self, void *closure)
{
if (!self->err->apptag) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->apptag);
}
static PyObject *
ncErrGetPath(ncErrObject *self, void *closure)
{
if (!self->err->path) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->path);
}
static PyObject *
ncErrGetMessage(ncErrObject *self, void *closure)
{
if (!self->err->message) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->message);
}
static PyObject *
ncErrGetMessageLang(ncErrObject *self, void *closure)
{
if (!self->err->message_lang) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->message_lang);
}
static PyObject *
ncErrGetSID(ncErrObject *self, void *closure)
{
if (!self->err->sid) {
Py_RETURN_NONE;
}
return PyUnicode_FromString(self->err->sid);
}
static PyObject *
ncErrGetBadAttr(ncErrObject *self, void *closure)
{
PyObject *list;
uint16_t u;
if (!self->err->attr_count) {
Py_RETURN_NONE;
}
list = PyList_New(self->err->attr_count);
if (!list) {
return NULL;
}
for (u = 0; u < self->err->attr_count; u++) {
PyList_SET_ITEM(list, u, PyUnicode_FromString(self->err->attr[u]));
}
return list;
}
static PyObject *
ncErrGetBadElem(ncErrObject *self, void *closure)
{
PyObject *list;
uint16_t u;
if (!self->err->elem_count) {
Py_RETURN_NONE;
}
list = PyList_New(self->err->elem_count);
if (!list) {
return NULL;
}
for (u = 0; u < self->err->elem_count; u++) {
PyList_SET_ITEM(list, u, PyUnicode_FromString(self->err->elem[u]));
}
return list;
}
static PyObject *
ncErrGetBadNS(ncErrObject *self, void *closure)
{
PyObject *list;
uint16_t u;
if (!self->err->ns_count) {
Py_RETURN_NONE;
}
list = PyList_New(self->err->ns_count);
if (!list) {
return NULL;
}
for (u = 0; u < self->err->ns_count; u++) {
PyList_SET_ITEM(list, u, PyUnicode_FromString(self->err->ns[u]));
}
return list;
}
/*
* Callback structures
*/
static PyGetSetDef ncErrGetSetters[] = {
{"type", (getter)ncErrGetType, NULL, "<error-type>", NULL},
{"tag", (getter)ncErrGetTag, NULL, "<error-tag>", NULL},
{"severity", (getter)ncErrGetSeverity, NULL, "<error-severity>", NULL},
{"app-tag", (getter)ncErrGetAppTag, NULL, "<error-app-tag>", NULL},
{"path", (getter)ncErrGetPath, NULL, "<error-path>", NULL},
{"message", (getter)ncErrGetMessage, NULL, "<error-message>", NULL},
{"lang", (getter)ncErrGetMessageLang, NULL, "<error-message xml:lang=\" \">", NULL},
{"session-id", (getter)ncErrGetSID, NULL, "<error-info><session-id/></error-info>", NULL},
{"bad-attr", (getter)ncErrGetBadAttr, NULL, "<error-info><bad-attr/></error-info>", NULL},
{"bad-elem", (getter)ncErrGetBadElem, NULL, "<error-info><bad-element/></error-info>", NULL},
{"bad-namespace", (getter)ncErrGetBadNS, NULL, "<error-info><bad-namespace/></error-info>", NULL},
{NULL} /* Sentinel */
};
PyDoc_STRVAR(ncErrDoc,
"NETCONF Error Reply information.\n\n");
PyTypeObject ncErrType = {
PyVarObject_HEAD_INIT(NULL, 0)
"netconf2.Err", /* tp_name */
sizeof(ncErrObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)ncErrFree, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)ncErrStr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
(reprfunc)ncErrStr, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
ncErrDoc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
ncErrGetSetters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};