== livido-utils.c ==

This is a set of generic utilites for LiViDO. It could become a library.

==== Code ====
{{{
/* LiViDO is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   LiViDO 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this source code; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


   LiViDO is developed by:

   Niels Elburg - http://veejay.sf.net

   Gabriel "Salsaman" Finch - http://lives.sourceforge.net

   Denis "Jaromil" Rojo - http://freej.dyne.org

   Tom Schouten - http://zwizwa.fartit.com

   Andraz Tori - http://cvs.cinelerra.org

   reviewed with suggestions and contributions from:

   Silvano "Kysucix" Galliani - http://freej.dyne.org

   Kentaro Fukuchi - http://megaui.net/fukuchi

   Jun Iio - http://www.malib.net

   Carlo Prelz - http://www2.fluido.as:8080/

*/

/* (C) Gabriel "Salsaman" Finch, 2005 */


/////////////////////////////////////////////////////////////////

int livido_has_property (livido_port_t *port, const char *key) {
  if (livido_property_get(port,key,0,NULL)==LIVIDO_ERROR_NOSUCH_PROPERTY) return 0;
  return 1;
}

/////////////////////////////////////////////////////////////////
// property setters

int livido_set_int_value (livido_port_t *port, const char *key, int value) {
  // returns a LIVIDO_ERROR
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_INT,1,&value,NULL);
}

int livido_set_float_value (livido_port_t *port, const char *key, float value) {
  // returns a LIVIDO_ERROR
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_FLOAT,1,&value,NULL);
}

int livido_set_long_value (livido_port_t *port, const char *key, long value) {
  // returns a LIVIDO_ERROR
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_LONG,1,&value,NULL);
}

int livido_set_boolean_value (livido_port_t *port, const char *key, int value) {
  // returns a LIVIDO_ERROR
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_BOOLEAN,1,&value,NULL);
}

int livido_set_string_value (livido_port_t *port, const char *key, char *value) {
  // returns a LIVIDO_ERROR
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_STRING,1,&value,NULL);
}

int livido_set_portptr_value (livido_port_t *port, const char *key, void *value) {
  // returns a LIVIDO_ERROR
  size_t size=sizeof(livido_port_t);
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_PORTPTR,1,&value,&size);
}

int livido_set_filterptr_value (livido_port_t *port, const char *key, void *value) {
  // returns a LIVIDO_ERROR
  size_t size=sizeof(livido_filter_t);
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_FILTERPTR,1,&value,&size);
}

/////////// this function needs a size ////////////

int livido_set_voidptr_value (livido_port_t *port, const char *key, void *value, size_t size) {
  // returns a LIVIDO_ERROR
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_VOIDPTR,1,&value,&size);
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// general property getter

inline int livido_get_value (livido_port_t *port, const char *key, void *value) {
  // returns a LIVIDO_ERROR
  return livido_property_get( port, key, 0, value);
}

////////////////////////////////////////////////////////////

int livido_get_int_value (livido_port_t *port, const char *key, int *error) {
  int retval=0;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_INT) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return retval;
  }
  else *error=livido_get_value (port,key,&retval);
  return retval;
}

float livido_get_float_value (livido_port_t *port, const char *key, int *error) {
  float retval=0.;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_FLOAT) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return retval;
  }
  *error=livido_get_value (port,key,&retval);
  return retval;
}

long livido_get_long_value (livido_port_t *port, const char *key, int *error) {
  long retval=0l;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_LONG) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return retval;
  }
  *error=livido_get_value (port,key,&retval);
  return retval;
}

int livido_get_boolean_value (livido_port_t *port, const char *key, int *error) {
  int retval=0;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_BOOLEAN) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return retval;
  }
  *error=livido_get_value (port,key,&retval);
  return retval;
}

char *livido_get_string_value (livido_port_t *port, const char *key, int *error) {
  char *retval=NULL;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_STRING) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }
  if ((retval=(char *)livido_malloc_f(livido_property_element_size(port,key,0)+1))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }
  if ((*error=livido_get_value (port,key,&retval))!=LIVIDO_NO_ERROR) {
    livido_free_f (retval);
    return NULL;
  }
  return retval;
}

void *livido_get_voidptr_value (livido_port_t *port, const char *key, int *error) {
  void *retval=NULL;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_VOIDPTR) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return retval;
  }
  *error=livido_get_value (port,key,&retval);
  return retval;
}

livido_port_t *livido_get_portptr_value (livido_port_t *port, const char *key, int *error) {
  livido_port_t *retval=NULL;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_PORTPTR) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return retval;
  }
  *error=livido_get_value (port,key,&retval);
  return retval;
}

livido_filter_t *livido_get_filterptr_value (livido_port_t *port, const char *key, int *error) {
  livido_filter_t *retval=NULL;
  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_FILTERPTR) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return retval;
  }
  *error=livido_get_value (port,key,&retval);
  return retval;
}

////////////////////////////////////////////////////////////

int *livido_get_int_array (livido_port_t *port, const char *key, int *error) {
  int i;
  int num_elems;
  int *retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_INT) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }

  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(int *)livido_malloc_f(num_elems*sizeof(int)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

float *livido_get_float_array (livido_port_t *port, const char *key, int *error) {
  int i;
  int num_elems;
  float *retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_FLOAT) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }
  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(float *)livido_malloc_f(num_elems*sizeof(float)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

long *livido_get_long_array (livido_port_t *port, const char *key, int *error) {
  int i;
  int num_elems;
  long *retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_LONG) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }

  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(long *)livido_malloc_f(num_elems*sizeof(long)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

int *livido_get_boolean_array (livido_port_t *port, const char *key, int *error) {
  int i;
  int num_elems;
  int *retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_BOOLEAN) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }

  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(int *)livido_malloc_f(num_elems*sizeof(int)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

char **livido_get_string_array (livido_port_t *port, const char *key, int *error) {
  int i;
  int num_elems;
  char **retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_STRING) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }

  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(char **)livido_malloc_f(num_elems*sizeof(char *)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((retval[i]=(char *)livido_malloc_f(livido_property_element_size(port,key,i)+1))==NULL) {
      for (--i;i>=0;i--) livido_free_f(retval[i]);
      *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
      livido_free_f (retval);
      return NULL;
    }
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      for (--i;i>=0;i--) livido_free_f(retval[i]);
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

void **livido_get_voidptr_array (livido_port_t *port, const char *key, int *error) {
  int i;
  int num_elems;
  void **retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_VOIDPTR) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }

  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(void **)livido_malloc_f(num_elems*sizeof(void *)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

livido_port_t **livido_get_portptr_array (livido_port_t *port, const char *key, int *error) {
  // not used in LiViDO
  int i;
  int num_elems;
  livido_port_t **retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_PORTPTR) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }

  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(livido_port_t **)livido_malloc_f(num_elems*sizeof(livido_port_t *)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

livido_filter_t **livido_get_filterptr_array (livido_port_t *port, const char *key, int *error) {
  int i;
  int num_elems;
  livido_filter_t **retval;

  if (livido_has_property(port,key)&&livido_property_atom_type(port,key)!=LIVIDO_ATOM_TYPE_FILTERPTR) {
    *error=LIVIDO_ERROR_WRONG_ATOM_TYPE;
    return NULL;
  }

  if ((num_elems=livido_property_num_elements (port,key))==0) return NULL;

  if ((retval=(livido_filter_t **)livido_malloc_f(num_elems*sizeof(livido_filter_t *)))==NULL) {
    *error=LIVIDO_ERROR_MEMORY_ALLOCATION;
    return NULL;
  }

  for (i=0;i<num_elems;i++) {
    if ((*error=livido_property_get(port, key, i, &retval[i]))!=LIVIDO_NO_ERROR) {
      livido_free_f (retval);
      return NULL;
    }
  }
  return retval;
}

/////////////////////////////////////////////////////

int livido_set_int_array (livido_port_t *port, const char *key, int num_elems, int *values) {
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_INT,num_elems,values,NULL);
}

int livido_set_float_array (livido_port_t *port, const char *key, int num_elems, float *values) {
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_FLOAT,num_elems,values,NULL);
}

int livido_set_long_array (livido_port_t *port, const char *key, int num_elems, long *values) {
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_LONG,num_elems,values,NULL);
}

int livido_set_boolean_array (livido_port_t *port, const char *key, int num_elems, int *values) {
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_BOOLEAN,num_elems,values,NULL);
}

int livido_set_string_array (livido_port_t *port, const char *key, int num_elems, char **values) {
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_STRING,num_elems,values,NULL);
}

int livido_set_voidptr_array (livido_port_t *port, const char *key, int num_elems, void **values, size_t *sizes) {
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_VOIDPTR,num_elems,values,sizes);
}

int livido_set_portptr_array (livido_port_t *port, const char *key, int num_elems, livido_port_t **values, size_t *sizes) {
  // not used in LiViDO
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_PORTPTR,num_elems,values,sizes);
}

int livido_set_filterptr_array (livido_port_t *port, const char *key, int num_elems, livido_filter_t **values, size_t *sizes) {
  return livido_property_set (port,key,LIVIDO_ATOM_TYPE_FILTERPTR,num_elems,values,sizes);
}
}}}