Blame ma_legacy_helpers.c

Packit Service 17f749
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
Packit Service 17f749
                 2016 MariaDB Corporation AB
Packit Service 17f749
   
Packit Service 17f749
   This library is free software; you can redistribute it and/or
Packit Service 17f749
   modify it under the terms of the GNU Library General Public
Packit Service 17f749
   License as published by the Free Software Foundation; either
Packit Service 17f749
   version 2 of the License, or (at your option) any later version.
Packit Service 17f749
   
Packit Service 17f749
   This library is distributed in the hope that it will be useful,
Packit Service 17f749
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 17f749
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 17f749
   Library General Public License for more details.
Packit Service 17f749
   
Packit Service 17f749
   You should have received a copy of the GNU Library General Public
Packit Service 17f749
   License along with this library; if not see <http://www.gnu.org/licenses>
Packit Service 17f749
   or write to the Free Software Foundation, Inc.,
Packit Service 17f749
   51 Franklin St., Fifth Floor, Boston, MA 02110, USA
Packit Service 17f749
*/
Packit Service 17f749
Packit Service 17f749
/********
Packit Service 17f749
 *
Packit Service 17f749
 * Code for lists, MADB_DynArray, and MADB_DynString copied (from C/C
Packit Service 17f749
 *
Packit Service 17f749
 ********/
Packit Service 17f749
Packit Service 17f749
/*
Packit Service 17f749
  *************** Code for handling dubble-linked lists in C *********
Packit Service 17f749
*/
Packit Service 17f749
Packit Service 17f749
#include <ma_odbc.h>
Packit Service 17f749
Packit Service 17f749
/*
Packit Service 17f749
How much overhead does malloc have. The code often allocates
Packit Service 17f749
something like 1024-MALLOC_OVERHEAD bytes
Packit Service 17f749
*/
Packit Service 17f749
#define MALLOC_OVERHEAD 8
Packit Service 17f749
Packit Service 17f749
/* Add a element to start of list */
Packit Service 17f749
Packit Service 17f749
MADB_List *MADB_ListAdd(MADB_List *root, MADB_List *element)
Packit Service 17f749
{
Packit Service 17f749
  if (root)
Packit Service 17f749
  {
Packit Service 17f749
    if (root->prev)			/* If add in mid of list */
Packit Service 17f749
      root->prev->next= element;
Packit Service 17f749
    element->prev=root->prev;
Packit Service 17f749
    root->prev=element;
Packit Service 17f749
  }
Packit Service 17f749
  else
Packit Service 17f749
    element->prev=0;
Packit Service 17f749
  element->next=root;
Packit Service 17f749
  return(element);			/* New root */
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
MADB_List *MADB_ListDelete(MADB_List *root, MADB_List *element)
Packit Service 17f749
{
Packit Service 17f749
  if (element->prev)
Packit Service 17f749
    element->prev->next=element->next;
Packit Service 17f749
  else
Packit Service 17f749
    root=element->next;
Packit Service 17f749
  if (element->next)
Packit Service 17f749
    element->next->prev=element->prev;
Packit Service 17f749
  return root;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_ListFree(MADB_List *root, unsigned int free_data)
Packit Service 17f749
{
Packit Service 17f749
  MADB_List *next;
Packit Service 17f749
  while (root)
Packit Service 17f749
  {
Packit Service 17f749
    next=root->next;
Packit Service 17f749
    if (free_data)
Packit Service 17f749
      free(root->data);
Packit Service 17f749
    free(root);
Packit Service 17f749
    root=next;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
MADB_List *MADB_ListCons(void *data, MADB_List *list)
Packit Service 17f749
{
Packit Service 17f749
  MADB_List *new_charset=(MADB_List*) malloc(sizeof(MADB_List));
Packit Service 17f749
  if (!new_charset)
Packit Service 17f749
    return 0;
Packit Service 17f749
  new_charset->data=data;
Packit Service 17f749
  return MADB_ListAdd(list,new_charset);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
MADB_List *MADB_ListReverse(MADB_List *root)
Packit Service 17f749
{
Packit Service 17f749
  MADB_List *last;
Packit Service 17f749
Packit Service 17f749
  last=root;
Packit Service 17f749
  while (root)
Packit Service 17f749
  {
Packit Service 17f749
    last=root;
Packit Service 17f749
    root=root->next;
Packit Service 17f749
    last->next=last->prev;
Packit Service 17f749
    last->prev=root;
Packit Service 17f749
  }
Packit Service 17f749
  return last;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
unsigned int MADB_ListLength(MADB_List *list)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int count;
Packit Service 17f749
  for (count=0 ; list ; list=list->next, count++) ;
Packit Service 17f749
  return count;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
int MADB_ListWalk(MADB_List *list, MADB_ListWalkAction action, char * argument)
Packit Service 17f749
{
Packit Service 17f749
  int error=0;
Packit Service 17f749
  while (list)
Packit Service 17f749
  {
Packit Service 17f749
    if ((error = (*action)(list->data,argument)))
Packit Service 17f749
      return error;
Packit Service 17f749
    list= MADB_LIST_REST(list);
Packit Service 17f749
  }
Packit Service 17f749
  return 0;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/************************** MADB_DynString ***************************/
Packit Service 17f749
/*
Packit Service 17f749
  Code for handling strings with can grow dynamicly.
Packit Service 17f749
  Copyright Monty Program KB.
Packit Service 17f749
  By monty.
Packit Service 17f749
*/
Packit Service 17f749
Packit Service 17f749
my_bool MADB_InitDynamicString(MADB_DynString *str, const char *init_str,
Packit Service 17f749
			    size_t init_alloc, size_t alloc_increment)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int length;
Packit Service 17f749
Packit Service 17f749
  if (!alloc_increment)
Packit Service 17f749
    alloc_increment=128;
Packit Service 17f749
  length=1;
Packit Service 17f749
  if (init_str && (length= (unsigned int) strlen(init_str)+1) < init_alloc)
Packit Service 17f749
    init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment;
Packit Service 17f749
  if (!init_alloc)
Packit Service 17f749
    init_alloc=alloc_increment;
Packit Service 17f749
Packit Service 17f749
  if (!(str->str=(char*) malloc(init_alloc)))
Packit Service 17f749
    return(TRUE);
Packit Service 17f749
  str->length=length-1;
Packit Service 17f749
  if (init_str)
Packit Service 17f749
    memcpy(str->str,init_str,length);
Packit Service 17f749
  str->max_length=init_alloc;
Packit Service 17f749
  str->alloc_increment=alloc_increment;
Packit Service 17f749
  return(FALSE);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynstrSet(MADB_DynString *str, const char *init_str)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int length;
Packit Service 17f749
Packit Service 17f749
  if (init_str && (length= (unsigned int) strlen(init_str)+1) > str->max_length)
Packit Service 17f749
  {
Packit Service 17f749
    str->max_length=((length+str->alloc_increment-1)/str->alloc_increment)*
Packit Service 17f749
      str->alloc_increment;
Packit Service 17f749
    if (!str->max_length)
Packit Service 17f749
      str->max_length=str->alloc_increment;
Packit Service 17f749
    if (!(str->str=(char*) realloc(str->str,str->max_length)))
Packit Service 17f749
      return(TRUE);
Packit Service 17f749
  }
Packit Service 17f749
  if (init_str)
Packit Service 17f749
  {
Packit Service 17f749
    str->length=length-1;
Packit Service 17f749
    memcpy(str->str,init_str,length);
Packit Service 17f749
  }
Packit Service 17f749
  else
Packit Service 17f749
    str->length=0;
Packit Service 17f749
  return(FALSE);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynstrRealloc(MADB_DynString *str, size_t additional_size)
Packit Service 17f749
{
Packit Service 17f749
  if (!additional_size) return(FALSE);
Packit Service 17f749
  if (str->length + additional_size > str->max_length)
Packit Service 17f749
  {
Packit Service 17f749
    str->max_length=((str->length + additional_size+str->alloc_increment-1)/
Packit Service 17f749
		     str->alloc_increment)*str->alloc_increment;
Packit Service 17f749
    if (!(str->str=(char*) realloc(str->str,str->max_length)))
Packit Service 17f749
      return(TRUE);
Packit Service 17f749
  }
Packit Service 17f749
  return(FALSE);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynstrAppend(MADB_DynString *str, const char *append)
Packit Service 17f749
{
Packit Service 17f749
  return MADB_DynstrAppendMem(str,append,strlen(append));
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_DynstrAppendMem(MADB_DynString *str, const char *append,
Packit Service 17f749
			  size_t length)
Packit Service 17f749
{
Packit Service 17f749
  char *new_ptr;
Packit Service 17f749
  if (str->length+length >= str->max_length)
Packit Service 17f749
  {
Packit Service 17f749
    size_t new_length=(str->length+length+str->alloc_increment)/
Packit Service 17f749
      str->alloc_increment;
Packit Service 17f749
    new_length*=str->alloc_increment;
Packit Service 17f749
    if (!(new_ptr=(char*) realloc(str->str,new_length)))
Packit Service 17f749
      return TRUE;
Packit Service 17f749
    str->str=new_ptr;
Packit Service 17f749
    str->max_length=new_length;
Packit Service 17f749
  }
Packit Service 17f749
  memcpy(str->str + str->length,append,length);
Packit Service 17f749
  str->length+=length;
Packit Service 17f749
  str->str[str->length]=0;			/* Safety for C programs */
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_DynstrFree(MADB_DynString *str)
Packit Service 17f749
{
Packit Service 17f749
  if (str->str)
Packit Service 17f749
  {
Packit Service 17f749
    free(str->str);
Packit Service 17f749
    str->str=0;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
char *MADB_DynstrMake(register char *dst, register const char *src, size_t length)
Packit Service 17f749
{
Packit Service 17f749
  while (length--)
Packit Service 17f749
    if (! (*dst++ = *src++))
Packit Service 17f749
      return dst-1;
Packit Service 17f749
  *dst=0;
Packit Service 17f749
  return dst;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/************* MADB_DynArray - Handling of arrays that can grow dynamicly. **************/
Packit Service 17f749
Packit Service 17f749
#undef SAFEMALLOC /* Problems with threads */
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
/*
Packit Service 17f749
  Initiate array and alloc space for init_alloc elements. Array is usable
Packit Service 17f749
  even if space allocation failed
Packit Service 17f749
*/
Packit Service 17f749
Packit Service 17f749
my_bool MADB_InitDynamicArray(MADB_DynArray *array, unsigned int element_size,
Packit Service 17f749
                              unsigned int init_alloc, unsigned int alloc_increment)
Packit Service 17f749
{
Packit Service 17f749
  if (!alloc_increment)
Packit Service 17f749
  {
Packit Service 17f749
    alloc_increment=MAX((8192-MALLOC_OVERHEAD)/element_size,16);
Packit Service 17f749
    if (init_alloc > 8 && alloc_increment > init_alloc * 2)
Packit Service 17f749
      alloc_increment=init_alloc*2;
Packit Service 17f749
  }
Packit Service 17f749
Packit Service 17f749
  if (!init_alloc)
Packit Service 17f749
    init_alloc=alloc_increment;
Packit Service 17f749
  array->elements=0;
Packit Service 17f749
  array->max_element=init_alloc;
Packit Service 17f749
  array->alloc_increment=alloc_increment;
Packit Service 17f749
  array->size_of_element=element_size;
Packit Service 17f749
  if (!(array->buffer=(char*) malloc(element_size*init_alloc)))
Packit Service 17f749
  {
Packit Service 17f749
    array->max_element=0;
Packit Service 17f749
    return(TRUE);
Packit Service 17f749
  }
Packit Service 17f749
  return(FALSE);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_InsertDynamic(MADB_DynArray *array, void *element)
Packit Service 17f749
{
Packit Service 17f749
  void *buffer;
Packit Service 17f749
  if (array->elements == array->max_element)
Packit Service 17f749
  {						/* Call only when nessesary */
Packit Service 17f749
    if (!(buffer=MADB_AllocDynamic(array)))
Packit Service 17f749
      return TRUE;
Packit Service 17f749
  }
Packit Service 17f749
  else
Packit Service 17f749
  {
Packit Service 17f749
    buffer=array->buffer+(array->elements * array->size_of_element);
Packit Service 17f749
    array->elements++;
Packit Service 17f749
  }
Packit Service 17f749
  memcpy(buffer,element,(size_t) array->size_of_element);
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
	/* Alloc room for one element */
Packit Service 17f749
Packit Service 17f749
unsigned char *MADB_AllocDynamic(MADB_DynArray *array)
Packit Service 17f749
{
Packit Service 17f749
  if (array->elements == array->max_element)
Packit Service 17f749
  {
Packit Service 17f749
    char *new_ptr;
Packit Service 17f749
    if (!(new_ptr=(char*) realloc(array->buffer,(array->max_element+
Packit Service 17f749
			          array->alloc_increment)*
Packit Service 17f749
				   array->size_of_element)))
Packit Service 17f749
      return 0;
Packit Service 17f749
    array->buffer=new_ptr;
Packit Service 17f749
    array->max_element+=array->alloc_increment;
Packit Service 17f749
  }
Packit Service 17f749
  return (unsigned char *)array->buffer+(array->elements++ * array->size_of_element);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
	/* remove last element from array and return it */
Packit Service 17f749
Packit Service 17f749
unsigned char *MADB_PopDynamic(MADB_DynArray *array)
Packit Service 17f749
{
Packit Service 17f749
  if (array->elements)
Packit Service 17f749
    return (unsigned char *)array->buffer+(--array->elements * array->size_of_element);
Packit Service 17f749
  return 0;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
my_bool MADB_SetDynamic(MADB_DynArray *array, void * element, unsigned int idx)
Packit Service 17f749
{
Packit Service 17f749
  if (idx >= array->elements)
Packit Service 17f749
  {
Packit Service 17f749
    if (idx >= array->max_element)
Packit Service 17f749
    {
Packit Service 17f749
      unsigned int size;
Packit Service 17f749
      char *new_ptr;
Packit Service 17f749
      size=(idx+array->alloc_increment)/array->alloc_increment;
Packit Service 17f749
      size*= array->alloc_increment;
Packit Service 17f749
      if (!(new_ptr=(char*) realloc(array->buffer,size*
Packit Service 17f749
			            array->size_of_element)))
Packit Service 17f749
	return TRUE;
Packit Service 17f749
      array->buffer=new_ptr;
Packit Service 17f749
      array->max_element=size;
Packit Service 17f749
    }
Packit Service 17f749
    memset((array->buffer+array->elements*array->size_of_element), 0,
Packit Service 17f749
	  (idx - array->elements)*array->size_of_element);
Packit Service 17f749
    array->elements=idx+1;
Packit Service 17f749
  }
Packit Service 17f749
  memcpy(array->buffer+(idx * array->size_of_element),element,
Packit Service 17f749
	 (size_t) array->size_of_element);
Packit Service 17f749
  return FALSE;
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_GetDynamic(MADB_DynArray *array, void * element, unsigned int idx)
Packit Service 17f749
{
Packit Service 17f749
  if (idx >= array->elements)
Packit Service 17f749
  {
Packit Service 17f749
    memset(element, 0, array->size_of_element);
Packit Service 17f749
    return;
Packit Service 17f749
  }
Packit Service 17f749
  memcpy(element,array->buffer+idx*array->size_of_element,
Packit Service 17f749
	 (size_t) array->size_of_element);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_DeleteDynamic(MADB_DynArray *array)
Packit Service 17f749
{
Packit Service 17f749
  if (array->buffer)
Packit Service 17f749
  {
Packit Service 17f749
    free(array->buffer);
Packit Service 17f749
    array->buffer=0;
Packit Service 17f749
    array->elements=array->max_element=0;
Packit Service 17f749
  }
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_DeleteDynamicElement(MADB_DynArray *array, unsigned int idx)
Packit Service 17f749
{
Packit Service 17f749
  char *ptr=array->buffer+array->size_of_element*idx;
Packit Service 17f749
  array->elements--;
Packit Service 17f749
  memmove(ptr,ptr+array->size_of_element,
Packit Service 17f749
	  (array->elements-idx)*array->size_of_element);
Packit Service 17f749
}
Packit Service 17f749
Packit Service 17f749
Packit Service 17f749
void MADB_FreezeSizeDynamic(MADB_DynArray *array)
Packit Service 17f749
{
Packit Service 17f749
  unsigned int elements=MAX(array->elements,1);
Packit Service 17f749
Packit Service 17f749
  if (array->buffer && array->max_element != elements)
Packit Service 17f749
  {
Packit Service 17f749
    array->buffer=(char*) realloc(array->buffer,
Packit Service 17f749
			          elements*array->size_of_element);
Packit Service 17f749
    array->max_element=elements;
Packit Service 17f749
  }
Packit Service 17f749
}