 e5299e1eab
			
		
	
	e5299e1eab
	
	
	
		
			
			Keeping the parser state internal to a subclass makes the code more readable and allows the removal of most parameters. It also removes the need to return iterator ranges from the tokenization function thus making the Token class obsolete. Unit testing benefits from this as well as it more closely resembles usage in the wild as more of the code can be run without a live system.
		
			
				
	
	
		
			199 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2016 MariaDB Corporation Ab
 | |
|  *
 | |
|  * Use of this software is governed by the Business Source License included
 | |
|  * in the LICENSE.TXT file and at www.mariadb.com/bsl11.
 | |
|  *
 | |
|  * Change Date: 2022-01-01
 | |
|  *
 | |
|  * On the date above, in accordance with the Business Source License, use
 | |
|  * of this software will be governed by version 2 or later of the General
 | |
|  * Public License.
 | |
|  */
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <maxbase/assert.h>
 | |
| #include <maxscale/hint.h>
 | |
| #include <maxscale/alloc.h>
 | |
| 
 | |
| /**
 | |
|  * @file hint.c generic support routines for hints.
 | |
|  *
 | |
|  * @verbatim
 | |
|  * Revision History
 | |
|  *
 | |
|  * Date         Who             Description
 | |
|  * 25/07/14     Mark Riddoch    Initial implementation
 | |
|  *
 | |
|  * @endverbatim
 | |
|  */
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Duplicate a list of hints
 | |
|  *
 | |
|  * @param hint          The hint list to duplicate
 | |
|  * @return      A duplicate of the list
 | |
|  *
 | |
|  * Note : Optimize this to use version numbering instead of copying memory
 | |
|  */
 | |
| HINT* hint_dup(const HINT* hint)
 | |
| {
 | |
|     const HINT* ptr1 = hint;
 | |
|     HINT* nlhead = NULL, * nltail = NULL, * ptr2;
 | |
| 
 | |
|     while (ptr1)
 | |
|     {
 | |
|         if ((ptr2 = (HINT*)MXS_MALLOC(sizeof(HINT))) == NULL)
 | |
|         {
 | |
|             return nlhead;
 | |
|         }
 | |
|         ptr2->type = ptr1->type;
 | |
|         if (ptr1->data)
 | |
|         {
 | |
|             ptr2->data = MXS_STRDUP_A((const char*)ptr1->data);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             ptr2->data = NULL;
 | |
|         }
 | |
|         if (ptr1->value)
 | |
|         {
 | |
|             ptr2->value = MXS_STRDUP_A((const char*)ptr1->value);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             ptr2->value = NULL;
 | |
|         }
 | |
|         ptr2->next = NULL;
 | |
|         if (nltail)
 | |
|         {
 | |
|             nltail->next = ptr2;
 | |
|             nltail = ptr2;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             nlhead = ptr2;
 | |
|             nltail = ptr2;
 | |
|         }
 | |
|         ptr1 = ptr1->next;
 | |
|     }
 | |
|     return nlhead;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Create a ROUTE TO type hint
 | |
|  *
 | |
|  * @param head  The current hint list
 | |
|  * @param type  The HINT_TYPE
 | |
|  * @param data  Data may be NULL or the name of a server to route to
 | |
|  * @return The result hint list
 | |
|  */
 | |
| HINT* hint_create_route(HINT* head, HINT_TYPE type, const char* data)
 | |
| {
 | |
|     HINT* hint;
 | |
| 
 | |
|     if ((hint = (HINT*)MXS_MALLOC(sizeof(HINT))) == NULL)
 | |
|     {
 | |
|         return head;
 | |
|     }
 | |
|     hint->next = head;
 | |
|     hint->type = type;
 | |
|     if (data)
 | |
|     {
 | |
|         hint->data = MXS_STRDUP_A(data);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         hint->data = NULL;
 | |
|     }
 | |
|     hint->value = NULL;
 | |
|     return hint;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Insert a hint list before head.
 | |
|  *
 | |
|  * @param head  Element before which contents is inserted.
 | |
|  *              May be NULL, in which case the result is list.
 | |
|  * @param list  Hint list to prepend
 | |
|  * @return Head of list
 | |
|  */
 | |
| HINT* hint_splice(HINT* head, HINT* list)
 | |
| {
 | |
|     mxb_assert(list);
 | |
|     if (head)
 | |
|     {
 | |
|         HINT* tail = list;
 | |
|         while (tail->next)
 | |
|         {
 | |
|             tail = tail->next;
 | |
|         }
 | |
|         tail->next = head;
 | |
|     }
 | |
| 
 | |
|     return list;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Create name/value parameter hint
 | |
|  *
 | |
|  * @param head  The current hint list
 | |
|  * @param pname The parameter name
 | |
|  * @param value The parameter value
 | |
|  * @return The result hint list
 | |
|  */
 | |
| HINT* hint_create_parameter(HINT* head, const char* pname, const char* value)
 | |
| {
 | |
|     HINT* hint;
 | |
| 
 | |
|     if ((hint = (HINT*)MXS_MALLOC(sizeof(HINT))) == NULL)
 | |
|     {
 | |
|         return head;
 | |
|     }
 | |
|     hint->next = head;
 | |
|     hint->type = HINT_PARAMETER;
 | |
|     hint->data = MXS_STRDUP_A(pname);
 | |
|     hint->value = MXS_STRDUP_A(value);
 | |
|     return hint;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * free_hint - free a hint
 | |
|  *
 | |
|  * @param hint          The hint to free
 | |
|  */
 | |
| void hint_free(HINT* hint)
 | |
| {
 | |
|     if (hint)
 | |
|     {
 | |
|         if (hint->data)
 | |
|         {
 | |
|             MXS_FREE(hint->data);
 | |
|         }
 | |
|         if (hint->value)
 | |
|         {
 | |
|             MXS_FREE(hint->value);
 | |
|         }
 | |
|         MXS_FREE(hint);
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool hint_exists(HINT** p_hint,
 | |
|                  HINT_TYPE type)
 | |
| {
 | |
|     bool succp = false;
 | |
| 
 | |
|     while (*p_hint != NULL)
 | |
|     {
 | |
|         if ((*p_hint)->type == type)
 | |
|         {
 | |
|             succp = true;
 | |
|         }
 | |
|         p_hint = &(*p_hint)->next;
 | |
|     }
 | |
|     return succp;
 | |
| }
 |