#if HAVE_CRT #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #endif //HAVE_CRT /* * Copyright (C) 2020, University of the Basque Country (UPV/EHU) * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com> * * The original file was part of Open Source Doubango Framework * Copyright (C) 2010-2011 Mamadou Diop. * Copyright (C) 2012 Doubango Telecom <http://doubango.org> * * This file is part of Open Source Doubango Framework. * * DOUBANGO 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. * * DOUBANGO 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 DOUBANGO. * */ /**@file txcap_node.c * @brief XCAP nodes. * * @author Mamadou Diop <diopmamadou(at)doubango.org> * */ #include "tinyxcap/txcap_node.h" #include "tsk_string.h" #include "tsk_buffer.h" #include "tsk_memory.h" #include "tsk_debug.h" #include <string.h> /* strlen() */ /**@ingroup txcap_selector_group * Gets the Node Url. * @param auid_id The id of the AUID (e.g 'resource-lists'). * @param ... Node selection steps. You must use @a TXCAP_SELECTOR_NODE_SET*() macros to set these steps. * The list of parameters must end with @ref TXCAP_SELECTOR_NODE_SET_NULL() even if there is no step.<br> * @retval The Url of the node (e.g. 'resource-lists/list[2]'). * * @code char* node = txcap_selector_get_node("resource-lists", TXCAP_SELECTOR_NODE_SET_ATTRIBUTE("list", "name", "rcs"), TXCAP_SELECTOR_NODE_SET_ATTRIBUTE("entry", "uri", "sip:bob@example.com"), TXCAP_SELECTOR_NODE_SET_NULL()); TSK_FREE(node); * @endcode * * @sa @ref txcap_selector_get_node_2<br>@ref txcap_selector_get_document<br> @ref txcap_selector_get_document_2<br>@ref txcap_selector_get_url */ char* txcap_selector_get_node(const char* auid_id, ...) { char* ret = tsk_null; va_list ap; va_start(ap, auid_id); ret = txcap_selector_get_node_2(auid_id, &ap); va_end(ap); return ret; } /**@ingroup txcap_selector_group * Gets the Node Url. * @param auid_id The id of the AUID (e.g 'resource-lists'). * @param app Node selection steps. You must use @a TXCAP_SELECTOR_NODE_SET*() macros to set these steps. * The list of parameters must end with @ref TXCAP_SELECTOR_NODE_SET_NULL() even if there is no step.<br> * @retval The Url of the node (e.g. 'resource-lists/list[2]'). * * @code * @endcode * * @sa @ref txcap_selector_get_node<br>@ref txcap_selector_get_document<br> @ref txcap_selector_get_document_2<br>@ref txcap_selector_get_url */ char* txcap_selector_get_node_2(const char* auid_id, va_list* app) { char* ret = tsk_null; char* namespace = tsk_null; tsk_buffer_t* buffer = tsk_buffer_create_null(); txcap_selector_param_type_t step; while((step = va_arg(*app, txcap_selector_param_type_t)) != xcapp_node_null){ switch(step){ case xcapp_node_name: { /* (const char*)QNAME_STR */ const char* QNAME_STR = va_arg(*app, const char*); if(tsk_buffer_append_2(buffer, "/%s", QNAME_STR)){ goto bail; } break; } case xcapp_node_pos: { /* (const char*)QNAME_STR, (unsigned int)POS_UINT */ const char* QNAME_STR = va_arg(*app, const char*); unsigned int POS_UINT = va_arg(*app, unsigned int); tsk_buffer_append_2(buffer, "/%s%%5B%u%%5D", QNAME_STR, POS_UINT); break; } case xcapp_node_attribute: { /* (const char*)QNAME_STR, (const char*)ATT_QNAME_STR, (const char*)ATT_VALUE_STR */ const char* QNAME_STR = va_arg(*app, const char*); const char* ATT_QNAME_STR = va_arg(*app, const char*); const char* ATT_VALUE_STR = va_arg(*app, const char*); tsk_buffer_append_2(buffer, "/%s%%5B@%s=%%22%s%%22%%5D", QNAME_STR, ATT_QNAME_STR, ATT_VALUE_STR); break; } case xcapp_node_pos_n_attribute: { /* (const char*)QNAME_STR, (unsigned int)POS_UINT, (const char*)ATT_QNAME_STR, (const char*)ATT_VALUE_STR */ const char* QNAME_STR = va_arg(*app, const char*); unsigned int POS_UINT = va_arg(*app, unsigned int); const char* ATT_QNAME_STR = va_arg(*app, const char*); const char* ATT_VALUE_STR = va_arg(*app, const char*); tsk_buffer_append_2(buffer, "/%s%%5B%u%%5D%%5B@%s=%%22%s%%22%%5D", QNAME_STR, POS_UINT, ATT_QNAME_STR, ATT_VALUE_STR); break; } case xcapp_node_namespace: { /* (const char*)PREFIX_STR, (const char*)VALUE_STR */ const char* PREFIX_STR = va_arg(*app, const char*); const char* VALUE_STR = va_arg(*app, const char*); char* temp = tsk_null; tsk_sprintf(&temp, "%sxmlns(%s=%%22%s%%22)", namespace?"":"%3F",PREFIX_STR, VALUE_STR); tsk_strcat(&namespace, temp); TSK_FREE(temp); break; } default: { TSK_DEBUG_ERROR("NOT SUPPORTED."); goto bail; } } /* switch */ } /* while */ /* append the namespace */ if(namespace){ tsk_buffer_append(buffer, namespace, tsk_strlen(namespace)); TSK_FREE(namespace); } bail: if(TSK_BUFFER_DATA(buffer) && TSK_BUFFER_SIZE(buffer)){ ret = tsk_strndup(TSK_BUFFER_DATA(buffer), TSK_BUFFER_SIZE(buffer)); } TSK_OBJECT_SAFE_FREE(buffer); return ret; }