#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "INLINE.h"
# include "src/Writable.h"
# include "src/Identifiable.h"
void initialize_writable(Writable* self){
initialize_identifiable((Identifiable*)self);
self->attributes = newHV();
self->meta = newAV();
self->url = NULL;
self->xml_id = NULL;
self->is_identifiable = 1;
self->is_suppress_ns = 0;
}
Writable* set_attributes(Writable* self, ...) {
Inline_Stack_Vars; // handle variable argument list
// get either a hash ref or key/value pairs
HV* newValues;
if ( Inline_Stack_Items == 2 ) {
newValues = (HV*)SvRV(Inline_Stack_Item(1));
}
else {
newValues = newHV();
int i;
for ( i = 1; i < Inline_Stack_Items - 1; i += 2 ) {
SV* key = Inline_Stack_Item(i);
SV* value = Inline_Stack_Item(i+1);
char* keystr = SvPV_nolen(key);
hv_store(newValues, keystr, strlen(keystr), value, 0);
}
}
// iterate over keys
I32 keys = hv_iterinit(newValues);
I32 i;
for ( i = 0; i < keys; i++ ) {
char * key = NULL;
I32 key_length = 0;
SV* value = hv_iternextsv(newValues, &key, &key_length);
// verify namespace prefixes
char * pch = strchr( key, ':' );
if ( pch != NULL ) {
int pos = pch - key;
char * prefix = (char*) malloc(pos);
strncpy( prefix, key, pos );
char * msg = "Unbound attribute prefix '%s'\n";
// should use logger, and should be conditional on:
// 1. it not being 'xmlns',
// 2. it not being known in global set of namespaces
printf(msg,prefix);
}
// store value
hv_store(self->attributes, key, strlen(key), value, 0);
}
return self;
}
HV* get_attributes(Writable* self) {
return self->attributes;
}
Writable* set_link(Writable* self, char* url) {
self->url = savepv(url);
return self;
}
char* get_link(Writable* self) {
return self->url;
}
Writable* set_name(Writable* self, char* name) {
hv_store(self->attributes, "label", 5, newSVpv(name,0), 0);
return self;
}
char* get_name(Writable* self) {
if ( hv_exists(self->attributes, "label", 5) ) {
SV* label = *(hv_fetch(self->attributes, "label", 5, 0));
char * retval = SvPV_nolen(label);
return retval;
}
else {
return NULL;
}
}
Writable* set_suppress_ns(Writable* self) {
self->is_suppress_ns = 1;
return self;
}
Writable* clear_suppress_ns(Writable* self) {
self->is_suppress_ns = 0;
return self;
}
int is_ns_suppressed(Writable* self) {
return self->is_suppress_ns;
}
int get_suppress_ns(Writable* self) {
return self->is_suppress_ns;
}
Writable* set_identifiable(Writable* self, int value) {
self->is_identifiable = value;
return self;
}
int is_identifiable(Writable* self) {
return self->is_identifiable;
}
int get_identifiable(Writable* self) {
return self->is_identifiable;
}
const char * get_tag(Writable* self) {
int idx = ((Identifiable*)self)->_index;
return tag[idx];
}
char * get_xml_id(Writable* self) {
char xml_id[10];
int idx = ((Identifiable*)self)->_index;
int end_idx = strlen(tag[idx]) - 1;
char start = tag[idx][0];
char end = tag[idx][end_idx];
sprintf(xml_id,"%c%c%d",start,end,((Identifiable*)self)->id);
self->xml_id = savepv(xml_id);
return self->xml_id;
}
Writable* set_base_uri(Writable* self, char * uri) {
hv_store(self->attributes, "xml:base", 8, newSVpv(uri,0), 0);
return self;
}
void destroy_writable(Writable* self) {
destroy_identifiable((Identifiable*)self);
// SvREFCNT_dec(self->attributes);
// SvREFCNT_dec(self->meta);
if ( self->url != NULL ) {
Safefree(self->url);
}
}
MODULE = Bio::PhyloXS::NeXML::Writable PACKAGE = Bio::PhyloXS::NeXML::Writable
PROTOTYPES: DISABLE
void
initialize_writable (self)
Writable * self
PREINIT:
I32* temp;
PPCODE:
temp = PL_markstack_ptr++;
initialize_writable(self);
if (PL_markstack_ptr != temp) {
/* truly void, because dXSARGS not invoked */
PL_markstack_ptr = temp;
XSRETURN_EMPTY; /* return empty stack */
}
/* must have used dXSARGS; list context implied */
return; /* assume stack size is correct */
Writable *
set_attributes (self, ...)
Writable * self
PREINIT:
I32* temp;
CODE:
temp = PL_markstack_ptr++;
RETVAL = set_attributes(self);
PL_markstack_ptr = temp;
OUTPUT:
RETVAL
HV *
get_attributes (self)
Writable * self
Writable *
set_link (self, url)
Writable * self
char * url
char *
get_link (self)
Writable * self
Writable *
set_name (self, name)
Writable * self
char * name
char *
get_name (self)
Writable * self
Writable *
set_suppress_ns (self)
Writable * self
Writable *
clear_suppress_ns (self)
Writable * self
int
is_ns_suppressed (self)
Writable * self
int
get_suppress_ns (self)
Writable * self
Writable *
set_identifiable (self, value)
Writable * self
int value
int
is_identifiable (self)
Writable * self
int
get_identifiable (self)
Writable * self
const char *
get_tag (self)
Writable * self
char *
get_xml_id (self)
Writable * self
Writable *
set_base_uri (self, uri)
Writable * self
char * uri
void
destroy_writable (self)
Writable * self
PREINIT:
I32* temp;
PPCODE:
temp = PL_markstack_ptr++;
destroy_writable(self);
if (PL_markstack_ptr != temp) {
/* truly void, because dXSARGS not invoked */
PL_markstack_ptr = temp;
XSRETURN_EMPTY; /* return empty stack */
}
/* must have used dXSARGS; list context implied */
return; /* assume stack size is correct */