/* netio/fget_netio_options.c. Generated from netio_options.c.in by configure. */
/*
** Copyright 2000-2004 University of Illinois Board of Trustees
** Copyright 2000-2004 Mark D. Roth
** All rights reserved.
**
** fget_netio_options.c - netio option code
**
** Mark D. Roth <roth@feep.net>
*/
#include <fget_netio_internal.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdarg.h>
# include <string.h>
#endif
/******************************************************************************
*** value type information
******************************************************************************/
/*
** value types for options
*/
enum value_types {
VAL_TYPE_UNSIGNED_SHORT = 1,
VAL_TYPE_TIME_T,
VAL_TYPE_LONG,
VAL_TYPE_NETIO_HOOKFUNC_T,
VAL_TYPE_CHAR_P,
VAL_TYPE_VOID_P
};
/*
** size for each type
*/
struct type_size
{
enum value_types ts_type;
size_t ts_size;
};
typedef struct type_size type_size_t;
/*
** table of sizes for each value type
*/
static const type_size_t type_sizes[] = {
{ VAL_TYPE_UNSIGNED_SHORT, sizeof(unsigned short) },
{ VAL_TYPE_TIME_T, sizeof(time_t) },
{ VAL_TYPE_LONG, sizeof(long) },
{ VAL_TYPE_NETIO_HOOKFUNC_T, sizeof(netio_hookfunc_t) },
{ VAL_TYPE_CHAR_P, sizeof(char *) },
{ VAL_TYPE_VOID_P, sizeof(void *) },
{ 0, 0 }
};
/*
** utility function for finding the size for a given type
*/
static size_t
_type_sizeof(enum value_types value_type)
{
int i;
for (i = 0; type_sizes[i].ts_type != 0; i++)
{
if (type_sizes[i].ts_type == value_type)
return type_sizes[i].ts_size;
}
return (size_t)0;
}
/******************************************************************************
*** option description information
******************************************************************************/
/*
** finds the offset within the NETIO handle of a given field
*/
#define netio_field_offset(field) \
((unsigned int) (((char *) (&(((NETIO *)NULL)->field))) - ((char *)NULL)))
/*
** description of an option
*/
struct netio_option_description
{
int o_option; /* option number */
size_t o_offset; /* offset of field into NETIO struct */
enum value_types o_type; /* value type */
};
typedef struct netio_option_description netio_option_description_t;
/*
** here's the actual table of option descriptions
*/
static const netio_option_description_t netio_option_descriptions[] = {
{
NETIO_OPT_DEFAULT_SERVICE,
netio_field_offset(n_default_service),
VAL_TYPE_CHAR_P
},
{
NETIO_OPT_DEFAULT_PORT,
netio_field_offset(n_default_port),
VAL_TYPE_UNSIGNED_SHORT
},
{
NETIO_OPT_SEND_HOOK,
netio_field_offset(n_sendhook),
VAL_TYPE_NETIO_HOOKFUNC_T
},
{
NETIO_OPT_RECV_HOOK,
netio_field_offset(n_recvhook),
VAL_TYPE_NETIO_HOOKFUNC_T
},
{
NETIO_OPT_HOOK_HANDLE,
netio_field_offset(n_hook_handle),
VAL_TYPE_VOID_P
},
{
NETIO_OPT_HOOK_DATA,
netio_field_offset(n_hook_data),
VAL_TYPE_VOID_P
},
{
0,
0,
0
}
};
/*
** utility function for finding the right option description in the table
*/
static const netio_option_description_t *
_find_option_description(int option)
{
int i;
for (i = 0; netio_option_descriptions[i].o_option != 0; i++)
{
if (netio_option_descriptions[i].o_option == option)
return &(netio_option_descriptions[i]);
}
return NULL;
}
/*
** set option defaults
*/
void
fget_netio_init_options(NETIO *netio)
{
/*
** netio_connect() uses calloc(3) to create the NETIO handle,
** so we only need to set those options that have a non-zero
** default value
*/
#if 0
netio_set_options(
netio,
NETIO_OPT_PASSIVE, (unsigned short)1,
NETIO_OPT_CACHE_MAXSIZE, (long)-1,
NETIO_OPT_CACHE_EXPIRE, (long)-1,
0
);
#endif
}
/******************************************************************************
*** code for setting options
******************************************************************************/
void
fget_netio_vset_options(NETIO *netio, va_list args)
{
const netio_option_description_t *netio_option_description;
int option;
void *ptr;
unsigned short val_unsigned_short;
unsigned short *ptr_unsigned_short;
time_t val_time_t;
time_t *ptr_time_t;
long val_long;
long *ptr_long;
netio_hookfunc_t val_netio_hookfunc_t;
netio_hookfunc_t *ptr_netio_hookfunc_t;
void *val_void_p;
void **ptr_void_p;
char **ptr_char_p;
char *cp;
while ((option = va_arg(args, int)) != 0)
{
#ifdef DEBUG
printf(" _vnetio_set_options(): option=%d\n", option);
#endif
netio_option_description = _find_option_description(option);
if (netio_option_description == NULL)
continue;
ptr = ((char *)netio + netio_option_description->o_offset);
switch (netio_option_description->o_type)
{
case VAL_TYPE_UNSIGNED_SHORT:
ptr_unsigned_short = (unsigned short *)ptr;
/*
** NOTE: we use int instead of short when
** calling va_arg() because short will be
** promoted to int when passed to a
** varags function
*/
*ptr_unsigned_short = va_arg(args, unsigned int);
#ifdef DEBUG
printf(" _vnetio_set_options(): value=%hu\n",
*ptr_unsigned_short);
#endif
break;
case VAL_TYPE_TIME_T:
ptr_time_t = (time_t *)ptr;
*ptr_time_t = va_arg(args, time_t);
#ifdef DEBUG
printf(" _vnetio_set_options(): value=%lu\n",
(unsigned long)*ptr_time_t);
#endif
break;
case VAL_TYPE_LONG:
ptr_long = (long *)ptr;
*ptr_long = va_arg(args, long);
#ifdef DEBUG
printf(" _vnetio_set_options(): value=%ld\n",
*ptr_long);
#endif
break;
case VAL_TYPE_NETIO_HOOKFUNC_T:
ptr_netio_hookfunc_t = (netio_hookfunc_t *)ptr;
*ptr_netio_hookfunc_t = va_arg(args, netio_hookfunc_t);
#ifdef DEBUG
printf(" _vnetio_set_options(): value=0x%lx\n",
*ptr_netio_hookfunc_t);
#endif
break;
case VAL_TYPE_CHAR_P:
ptr_char_p = (char **)ptr;
cp = va_arg(args, char *);
if (cp == NULL)
*ptr_char_p = cp;
else
{
if (*ptr_char_p != NULL)
free(*ptr_char_p);
*ptr_char_p = strdup(cp);
}
#ifdef DEBUG
printf(" _vnetio_set_options(): value=\"%s\"\n",
*ptr_char_p);
#endif
break;
case VAL_TYPE_VOID_P:
ptr_void_p = (void **)ptr;
*ptr_void_p = va_arg(args, void *);
#ifdef DEBUG
printf(" _vnetio_set_options(): value=0x%lx\n",
*ptr_void_p);
#endif
break;
default:
/* can't happen */
break;
}
}
}
/*
** set options
*/
void
fget_netio_set_options(NETIO *netio, ...)
{
va_list args;
va_start(args, netio);
fget_netio_vset_options(netio, args);
va_end(args);
}
/******************************************************************************
*** code for getting options
******************************************************************************/
static void
fget_netio_vget_options(NETIO *netio, va_list args)
{
const netio_option_description_t *netio_option_description;
int option;
void *opt_ptr, *arg_ptr;
size_t sz;
while ((option = va_arg(args, int)) != 0)
{
netio_option_description = _find_option_description(option);
if (netio_option_description == NULL)
return;
opt_ptr = ((char *)netio + netio_option_description->o_offset);
sz = _type_sizeof(netio_option_description->o_type);
arg_ptr = va_arg(args, void *);
#ifdef DEBUG
printf(" _vnetio_get_options(): option=%d sz=%lu\n",
option, (unsigned long)sz);
#endif
memcpy(arg_ptr, opt_ptr, sz);
}
}
/*
** get options
*/
void
fget_netio_get_options(NETIO *netio, ...)
{
va_list args;
va_start(args, netio);
fget_netio_vget_options(netio, args);
va_end(args);
}
syntax highlighted by Code2HTML, v. 0.9.1