#include <ffi_platypus.h>
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
/*
* Question: this is the documented way of creating a struct type.
* we already compute the size and alignment for the Perl interface
* to the members, can we use that instead?
*/
EXPORT
ffi_pl_record_meta_t *
ffi_platypus_record_meta__new(ffi_type *list[], int safe_to_return_from_closure)
{
int size, i;
ffi_pl_record_meta_t *t;
for(size=0; list[size] != NULL; size++)
;
t = malloc(sizeof(ffi_pl_record_meta_t) + sizeof(ffi_type*)*(size+1) );
if(t == NULL)
return NULL;
t->ffi_type.size = 0;
t->ffi_type.alignment = 0;
t->ffi_type.type = FFI_TYPE_STRUCT;
t->ffi_type.elements = (ffi_type**) &t->elements;
t->can_return_from_closure = safe_to_return_from_closure;
for(i=0; i<size+1; i++)
{
t->elements[i] = list[i];
}
return t;
}
EXPORT
ffi_type *
ffi_platypus_record_meta__ffi_type(ffi_pl_record_meta_t *t)
{
return &t->ffi_type;
}
EXPORT
size_t
ffi_platypus_record_meta__size(ffi_pl_record_meta_t *t)
{
return t->ffi_type.size;
}
EXPORT
unsigned short
ffi_platypus_record_meta__alignment(ffi_pl_record_meta_t *t)
{
return t->ffi_type.alignment;
}
EXPORT
ffi_type **
ffi_platypus_record_meta__element_pointers(ffi_pl_record_meta_t *t)
{
return t->ffi_type.elements;
}
EXPORT
void
ffi_platypus_record_meta__DESTROY(ffi_pl_record_meta_t *t)
{
free(t);
}
EXPORT
ffi_type *
ffi_platypus_record_meta___find_symbol(const char *name)
{
if(!strcmp(name, "sint8"))
return &ffi_type_sint8;
else if(!strcmp(name, "sint16"))
return &ffi_type_sint16;
else if(!strcmp(name, "sint32"))
return &ffi_type_sint32;
else if(!strcmp(name, "sint64"))
return &ffi_type_sint64;
else if(!strcmp(name, "uint8"))
return &ffi_type_uint8;
else if(!strcmp(name, "uint16"))
return &ffi_type_uint16;
else if(!strcmp(name, "uint32"))
return &ffi_type_uint32;
else if(!strcmp(name, "uint64"))
return &ffi_type_uint64;
else if(!strcmp(name, "pointer"))
return &ffi_type_pointer;
else if(!strcmp(name, "float"))
return &ffi_type_float;
else if(!strcmp(name, "double"))
return &ffi_type_double;
/* TODO: longdouble, complex_float, complex_duble, complex_longdouble */
else
return NULL;
}