270 lines
5.2 KiB
C
270 lines
5.2 KiB
C
#include <errno.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "utils.h"
|
|
#include "xvec.h"
|
|
|
|
int xvec_init(xvec_t* v, int count, int elsize)
|
|
{
|
|
if ((v == NULL) || (count <= 0) || (elsize <= 0)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
v->data = (void*)calloc(count, elsize);
|
|
if (v->data == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
v->count = count;
|
|
v->elsize = elsize;
|
|
|
|
return v->count;
|
|
}
|
|
|
|
void xvec_fini(xvec_t* v)
|
|
{
|
|
if (v == NULL) {
|
|
return;
|
|
}
|
|
|
|
FREEUP(v->data);
|
|
memset(v, 0x0, sizeof(*v));
|
|
}
|
|
|
|
int xvec_zero(xvec_t* v)
|
|
{
|
|
if (v == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (v->data == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
memset(v->data, 0x0, v->count * v->elsize);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int xvec_resize(xvec_t* v, int new_size)
|
|
{
|
|
void* p = NULL;
|
|
|
|
if (v == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (new_size <= v->count) {
|
|
/* do thing for shrink now */
|
|
return 0;
|
|
}
|
|
|
|
p = (void*)realloc(v->data, new_size * v->elsize);
|
|
if (p == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
v->data = p;
|
|
/* zero fill the extended space */
|
|
memset(((char*)p) + v->count * v->elsize, 0x0,
|
|
(new_size - v->count) * v->elsize);
|
|
v->count = new_size;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define X_OP(op) X_OP_##op
|
|
#define X_OP_add +=
|
|
#define X_OP_sub -=
|
|
|
|
#define DEFINE_VEC_OP(op, typ) \
|
|
static inline int vec_##typ##_##op(typ* v1, typ* v2, int count) \
|
|
{ \
|
|
int i; \
|
|
for (i = 0; i < count; i++) { \
|
|
v1[i] X_OP(op) v2[i]; \
|
|
} \
|
|
return 0; \
|
|
}
|
|
|
|
DEFINE_VEC_OP(add, int)
|
|
DEFINE_VEC_OP(sub, int)
|
|
DEFINE_VEC_OP(add, float)
|
|
DEFINE_VEC_OP(sub, float)
|
|
|
|
int xvec_op(xvec_t* v1, xvec_t* v2, xvec_op_t op)
|
|
{
|
|
int rc = 0;
|
|
|
|
if ((v1 == NULL) || (v2 == NULL)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (v1->elsize != v2->elsize) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
switch (op) {
|
|
case XVEC_ADD_INT:
|
|
case XVEC_SUB_INT:
|
|
if (v1->elsize != sizeof(int)) {
|
|
return -EINVAL;
|
|
}
|
|
break;
|
|
case XVEC_ADD_FLOAT:
|
|
case XVEC_SUB_FLOAT:
|
|
if (v1->elsize != sizeof(float)) {
|
|
return -EINVAL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (v1->count < v2->count) {
|
|
rc = xvec_resize(v1, v2->count);
|
|
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
switch (op) {
|
|
case XVEC_ADD_INT:
|
|
rc = vec_int_add((int*)v1->data, (int*)v2->data, v2->count);
|
|
break;
|
|
case XVEC_SUB_INT:
|
|
rc = vec_int_sub((int*)v1->data, (int*)v2->data, v2->count);
|
|
break;
|
|
case XVEC_ADD_FLOAT:
|
|
rc = vec_float_add((float*)v1->data, (float*)v2->data, v2->count);
|
|
break;
|
|
case XVEC_SUB_FLOAT:
|
|
rc = vec_float_sub((float*)v1->data, (float*)v2->data, v2->count);
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int xvec_dup(xvec_t** dst, xvec_t* src)
|
|
{
|
|
xvec_t* v = NULL;
|
|
|
|
v = (xvec_t*)calloc(1, sizeof(*v));
|
|
*dst = v;
|
|
|
|
if (v == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
v->data = (void*)calloc(src->count, src->elsize);
|
|
if (v->data == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
memcpy(v->data, src->data, src->elsize * src->count);
|
|
v->elsize = src->elsize;
|
|
v->count = src->count;
|
|
|
|
return v->count;
|
|
}
|
|
|
|
int xvec_put(xvec_t* v, int idx, void* data)
|
|
{
|
|
int rc;
|
|
char* p;
|
|
|
|
if ((v == NULL) || (idx < 0) || (data == NULL)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
rc = xvec_resize(v, idx + 1);
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
|
|
p = (char*)v->data;
|
|
memcpy(p + v->elsize * idx, data, v->elsize);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int xvec_get(xvec_t* v, int idx, void* data)
|
|
{
|
|
char* p = NULL;
|
|
|
|
if ((v == NULL) || (idx < 0) || (data == NULL)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (idx >= v->count) {
|
|
memset(data, 0x0, v->elsize);
|
|
return 0;
|
|
}
|
|
|
|
p = (char*)v->data;
|
|
memcpy(data, p + v->elsize * idx, v->elsize);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int xvec_idval_init(xvec_idval_t* v, int initsize)
|
|
{
|
|
int rc;
|
|
|
|
if ((v == NULL) || (initsize <= 0)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
memset(v, 0x0, sizeof(*v));
|
|
rc = xvec_init(&(v->idxs), initsize, sizeof(int));
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
|
|
rc = xvec_init(&(v->vals), initsize, sizeof(float));
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
|
|
v->count = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void xvec_idval_fini(xvec_idval_t* v)
|
|
{
|
|
if (v == NULL) {
|
|
return;
|
|
}
|
|
|
|
xvec_fini(&(v->idxs));
|
|
xvec_fini(&(v->vals));
|
|
|
|
memset(v, 0x0, sizeof(*v));
|
|
return;
|
|
}
|
|
|
|
int xvec_idval_store(xvec_idval_t* v, int idx, float val)
|
|
{
|
|
int rc;
|
|
int pos;
|
|
|
|
if ((v == NULL) || (idx < 0)) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
pos = v->count;
|
|
rc = xvec_put(&(v->idxs), pos, &idx);
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
|
|
rc = xvec_put(&(v->vals), pos, &val);
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
|
|
v->count = pos + 1;
|
|
|
|
return v->count;
|
|
}
|