Mercurial > hg > freeDiameter
view extensions/dbg_interactive/dictionary.i @ 1562:6219359a36a9 default tip
Merge latest changes from proposed branch
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Mon, 21 Jun 2021 19:08:18 +0800 |
parents | 1af09cc156d6 |
children |
line wrap: on
line source
/********************************************************************************************************* * Software License Agreement (BSD License) * * Author: Sebastien Decugis <sdecugis@freediameter.net> * * * * Copyright (c) 2013, WIDE Project and NICT * * All rights reserved. * * * * Redistribution and use of this software in source and binary forms, with or without modification, are * * permitted provided that the following conditions are met: * * * * * Redistributions of source code must retain the above * * copyright notice, this list of conditions and the * * following disclaimer. * * * * * Redistributions in binary form must reproduce the above * * copyright notice, this list of conditions and the * * following disclaimer in the documentation and/or other * * materials provided with the distribution. * * * * * Neither the name of the WIDE Project or NICT nor the * * names of its contributors may be used to endorse or * * promote products derived from this software without * * specific prior written permission of WIDE Project and * * NICT. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *********************************************************************************************************/ /* Do not include this directly, use dbg_interactive.i instead */ /****** DICTIONARY *********/ struct dictionary { }; %extend dictionary { dictionary() { struct dictionary * r = NULL; int ret = fd_dict_init(&r); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } return r; } ~dictionary() { struct dictionary *d = self; int ret = fd_dict_fini(&d); if (ret != 0) { DI_ERROR(ret, NULL, NULL); } return; } void dump() { char * buf = NULL; size_t len; printf("%s", fd_dict_dump(&buf, &len, NULL, $self)); free(buf); } PyObject * vendors_list() { uint32_t *list = NULL, *li; PyObject * ret; SWIG_PYTHON_THREAD_BEGIN_BLOCK; ret = PyList_New(0); list = fd_dict_get_vendorid_list($self); for (li = list; *li != 0; li++) { PyList_Append(ret, PyInt_FromLong((long)*li)); } free(list); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } struct dict_object * new_obj(enum dict_object_type type, void * data, struct dict_object * parent = NULL) { struct dict_object * obj = NULL; int ret = fd_dict_new($self, type, data, parent, &obj); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } return obj; } struct dict_object * search(enum dict_object_type type, int criteria, int what_by_val) { struct dict_object * obj = NULL; int ret = fd_dict_search ( $self, type, criteria, &what_by_val, &obj, ENOENT ); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } return obj; } struct dict_object * search(enum dict_object_type type, int criteria, char * what_by_string) { struct dict_object * obj = NULL; int ret = fd_dict_search ( $self, type, criteria, what_by_string, &obj, ENOENT ); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } return obj; } struct dict_object * search(enum dict_object_type type, int criteria, void * what) { struct dict_object * obj = NULL; int ret = fd_dict_search ( $self, type, criteria, what, &obj, ENOENT ); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } return obj; } struct dict_object * error_cmd() { struct dict_object * obj = NULL; int ret = fd_dict_get_error_cmd ( $self, &obj ); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } return obj; } } %nodefaultctor dict_object; struct dict_object { }; %extend dict_object { void dump() { char * buf = NULL; size_t len; printf("%s", fd_dict_dump_object(&buf, &len, NULL, $self)); free(buf); } enum dict_object_type gettype() { enum dict_object_type t; int ret = fd_dict_gettype ( $self, &t); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return 0; } return t; } struct dictionary * getdict() { struct dictionary *d; int ret = fd_dict_getdict ( $self, &d ); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } return d; } /* Since casting the pointer requires intelligence, we do it here instead of giving it to SWIG */ PyObject * getval() { /* first, get the type */ enum dict_object_type t; int ret = fd_dict_gettype ( $self, &t); if (ret != 0) { DI_ERROR(ret, NULL, NULL); return NULL; } switch (t) { %define %GETVAL_CASE(TYPE,STRUCT) case TYPE: { PyObject * v = NULL; struct STRUCT * data = NULL; data = malloc(sizeof(struct STRUCT)); if (!data) { DI_ERROR_MALLOC; return NULL; } ret = fd_dict_getval($self, data); if (ret != 0) { DI_ERROR(ret, NULL, NULL); free(data); return NULL; } SWIG_PYTHON_THREAD_BEGIN_BLOCK; v = SWIG_NewPointerObj((void *)data, SWIGTYPE_p_##STRUCT, SWIG_POINTER_OWN ); Py_XINCREF(v); SWIG_PYTHON_THREAD_END_BLOCK; return v; } break %enddef %GETVAL_CASE( DICT_VENDOR, dict_vendor_data ); %GETVAL_CASE( DICT_APPLICATION, dict_application_data ); %GETVAL_CASE( DICT_TYPE, dict_type_data ); %GETVAL_CASE( DICT_ENUMVAL, dict_enumval_data ); %GETVAL_CASE( DICT_AVP, dict_avp_data ); %GETVAL_CASE( DICT_COMMAND, dict_cmd_data ); %GETVAL_CASE( DICT_RULE, dict_rule_data ); default: DI_ERROR(EINVAL, PyExc_SystemError, "Internal error: Got invalid object type"); } return NULL; } } /* The following wrapper leaks memory each time an union avp_value is assigned an octet string. TODO: fix this leak by better understanding SWIG... -- the alternative is to uncomment the "free" statements below, but then it is easy to create a segmentation fault by assigning first an integer, then an octetstring. */ %extend avp_value { /* The following hack in the proxy file allows assigning the octet string directly like this: avp_value.os = "blabla" */ %pythoncode { __swig_setmethods__["os"] = _fDpy.avp_value_os_set if _newclass:os = _swig_property(_fDpy.avp_value_os_get, _fDpy.avp_value_os_set) } void os_set(char *STRING, size_t LENGTH) { /* free($self->os.data); -- do not free, in case the previous value was not an OS */ $self->os.data = malloc(LENGTH); if (!$self->os.data) { DI_ERROR_MALLOC; return; } memcpy($self->os.data, STRING, LENGTH); $self->os.len = LENGTH; } void os_set(avp_value_os * os) { /* free($self->os.data); -- do not free, in case the previous value was not an OS */ $self->os.data = malloc(os->len); if (!$self->os.data) { DI_ERROR_MALLOC; return; } memcpy($self->os.data, os->data, os->len); $self->os.len = os->len; } }; %extend avp_value_os { void dump() { %#define LEN_MAX 20 int i, n=LEN_MAX; if ($self->len < LEN_MAX) n = $self->len; fd_log_debug("l:%u, v:[", $self->len); for (i=0; i < n; i++) fd_log_debug("%02.2X", $self->data[i]); fd_log_debug("] '%.*s%s'", n, $self->data, n == LEN_MAX ? "..." : ""); } %cstring_output_allocate_size(char ** outbuffer, size_t * outlen, free(*$1)); void as_str ( char ** outbuffer, size_t * outlen ) { char * b; if (!$self->len) { *outlen = 0; *outbuffer = NULL; return; } b = malloc($self->len); if (!b) { DI_ERROR_MALLOC; return; } memcpy(b, $self->data, $self->len); *outlen = $self->len; *outbuffer = b; } } /* Allow constructors with parameters for the dict_*_data */ %extend dict_vendor_data { dict_vendor_data(uint32_t id = 0, char * name = NULL) { struct dict_vendor_data * d = (struct dict_vendor_data *)calloc(1, sizeof(struct dict_vendor_data)); if (!d) { DI_ERROR_MALLOC; return NULL; } d->vendor_id = id; if (name) { d->vendor_name = strdup(name); if (!d->vendor_name) { DI_ERROR_MALLOC; free(d); return NULL; } } return d; } } %extend dict_application_data { dict_application_data(uint32_t id = 0, char * name = NULL) { struct dict_application_data * d = (struct dict_application_data *)calloc(1, sizeof(struct dict_application_data)); if (!d) { DI_ERROR_MALLOC; return NULL; } d->application_id = id; if (name) { d->application_name = strdup(name); if (!d->application_name) { DI_ERROR_MALLOC; free(d); return NULL; } } return d; } } %extend dict_type_data { dict_type_data(enum dict_avp_basetype base = 0, char * name = NULL) { struct dict_type_data * d = (struct dict_type_data *)calloc(1, sizeof(struct dict_type_data)); if (!d) { DI_ERROR_MALLOC; return NULL; } d->type_base = base; if (name) { d->type_name = strdup(name); if (!d->type_name) { DI_ERROR_MALLOC; free(d); return NULL; } } return d; } } %extend dict_enumval_data { dict_enumval_data(char * name = NULL, uint32_t v = 0) { struct dict_enumval_data * d = (struct dict_enumval_data *)calloc(1, sizeof(struct dict_enumval_data)); if (!d) { DI_ERROR_MALLOC; return NULL; } if (name) { d->enum_name = strdup(name); if (!d->enum_name) { DI_ERROR_MALLOC; free(d); return NULL; } } d->enum_value.u32 = v; return d; } } %extend dict_avp_data { dict_avp_data(uint32_t code = 0, char * name = NULL, enum dict_avp_basetype basetype = 0, uint32_t vendor = 0, int mandatory=0) { struct dict_avp_data * d = (struct dict_avp_data *)calloc(1, sizeof(struct dict_avp_data)); if (!d) { DI_ERROR_MALLOC; return NULL; } if (name) { d->avp_name = strdup(name); if (!d->avp_name) { DI_ERROR_MALLOC; free(d); return NULL; } } d->avp_code = code; d->avp_basetype = basetype; d->avp_vendor = vendor; if (vendor) { d->avp_flag_val |= AVP_FLAG_VENDOR; d->avp_flag_mask |= AVP_FLAG_VENDOR; } d->avp_flag_mask |= AVP_FLAG_MANDATORY; if (mandatory) d->avp_flag_val |= AVP_FLAG_MANDATORY; return d; } } %extend dict_cmd_data { dict_cmd_data(uint32_t code = 0, char * name = NULL, int request = 1) { struct dict_cmd_data * d = (struct dict_cmd_data *)calloc(1, sizeof(struct dict_cmd_data)); if (!d) { DI_ERROR_MALLOC; return NULL; } if (name) { d->cmd_name = strdup(name); if (!d->cmd_name) { DI_ERROR_MALLOC; free(d); return NULL; } } d->cmd_code = code; d->cmd_flag_mask = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE; d->cmd_flag_val = CMD_FLAG_PROXIABLE | ( request ? CMD_FLAG_REQUEST : 0 ); return d; } } %extend dict_rule_data { dict_rule_data(struct dict_object *avp = NULL, enum rule_position pos = 0, int min = -1, int max = -1 ) { struct dict_rule_data * d = (struct dict_rule_data *)calloc(1, sizeof(struct dict_rule_data)); if (!d) { DI_ERROR_MALLOC; return NULL; } d->rule_avp = avp; d->rule_position = pos; d->rule_order = 1; d->rule_min = min; d->rule_max = max; return d; } }