#include #include #include "util/util.h" #include "xml/xml.h" #include "geometry.h" /* macro to ensure tag type matches what we expect */ #define CHECK_TAG_TYPE(expected) \ if (strcmp(src->type, expected) != 0) { \ return -1; \ } int kai_read_float_array(struct ka_float_array_t *dest, struct kai_tag_t *src) { CHECK_TAG_TYPE("float_array"); long count = kai_tag_attr_to_long(src, "count", -1); if (count == -1) { /* count not present */ return -1; } dest->count = count; dest->id = kai_tag_attr_to_dup(src, "id"); dest->digits = kai_tag_attr_to_long(src, "digits", 6); dest->magnitude = kai_tag_attr_to_long(src, "magnitude", 38); /* allocate & fill buffer */ dest->buf = kai_alloc( dest->count * sizeof(ka_real_t), "float_array buffer" ); if (dest->buf == NULL) { free(dest->id); return -1; } kai_text_to_reals(dest->buf, src->content, dest->count); return 0; } void kai_release_float_array(struct ka_float_array_t fa) { free(fa.id); free(fa.buf); } int kai_read_param(struct ka_param_t *dest, struct kai_tag_t *src) { CHECK_TAG_TYPE("param"); char *type = kai_tag_attr_to_dup(src, "type"); if (type == NULL) { return -1; } dest->name = kai_tag_attr_to_dup(src, "name"); dest->sid = kai_tag_attr_to_dup(src, "sid"); dest->type = type; dest->semantic = kai_tag_attr_to_dup(src, "semantic"); return 0; } void kai_release_param(struct ka_param_t p) { free(p.name); free(p.sid); free(p.type); free(p.semantic); } int kai_read_accessor(struct ka_accessor_t *dest, struct kai_tag_t *src) { CHECK_TAG_TYPE("accessor"); long count = kai_tag_attr_to_long(src, "count", -1); if (count == -1) { return -1; } char *source = kai_tag_attr_to_dup(src, "source"); if (source == NULL) { return -1; } dest->count = count; dest->offset = kai_tag_attr_to_long(src, "offset", 0); dest->source = source; dest->stride = kai_tag_attr_to_long(src, "stride", 1); dest->param_count = kai_tag_num_children(src); dest->param = kai_alloc( dest->param_count * sizeof(struct ka_param_t), "accessor tag param array" ); if (dest->param == NULL) { free(source); return -1; } struct kai_tag_t *t = src->children; int i; for (i=0; iparam_count; i++) { int result = kai_read_param(dest->param + i, t); if (result != 0) { free(dest->param); free(dest->source); return -1; } t = t->next; } return 0; } void kai_release_accessor(struct ka_accessor_t a) { free(a.source); int i; for (i=0; iid = id; dest->name = kai_tag_attr_to_dup(src, "name"); struct kai_tag_t *child; for (child = src->children; child != NULL; child = child->next) { if (strcmp(child->type, "float_array") == 0) { kai_read_float_array(&(dest->float_array), child); } else if (strcmp(child->type, "technique_common") == 0) { kai_read_accessor(&(dest->accessor), child->children); } /* ignore others */ } return 0; } void kai_release_source(struct ka_source_t s) { free(s.id); free(s.name); kai_release_float_array(s.float_array); kai_release_accessor(s.accessor); }