pbc4hs-0.1.0.0: cbits/array.c
#include "pbc.h"
#include "array.h"
#include "alloc.h"
#include <stdlib.h>
#include <string.h>
struct array {
int number;
struct heap *heap;
union _pbc_var * a;
};
#define INNER_FIELD ((PBC_ARRAY_CAP - sizeof(struct array)) / sizeof(pbc_var))
void
_pbcA_open(pbc_array _array) {
struct array * a = (struct array *)_array;
a->number = 0;
a->heap = NULL;
a->a = (union _pbc_var *)(a+1);
}
void
_pbcA_open_heap(pbc_array _array, struct heap *h) {
struct array * a = (struct array *)_array;
a->number = 0;
a->heap = h;
a->a = (union _pbc_var *)(a+1);
}
void
_pbcA_close(pbc_array _array) {
struct array * a = (struct array *)_array;
if (a->heap == NULL && a->a != NULL && (union _pbc_var *)(a+1) != a->a) {
_pbcM_free(a->a);
a->a = NULL;
}
}
void
_pbcA_push(pbc_array _array, pbc_var var) {
struct array * a = (struct array *)_array;
if (a->number == 0) {
a->a = (union _pbc_var *)(a+1);
} else if (a->number >= INNER_FIELD) {
if (a->number == INNER_FIELD) {
int cap = 1;
while (cap <= a->number + 1)
cap *= 2;
struct heap * h = a->heap;
union _pbc_var * outer = (union _pbc_var *)HMALLOC(cap * sizeof(union _pbc_var));
memcpy(outer , a->a , INNER_FIELD * sizeof(pbc_var));
a->a = outer;
} else {
int size=a->number;
if (((size + 1) ^ size) > size) {
struct heap * h = a->heap;
if (h) {
void * old = a->a;
a->a = (union _pbc_var *)_pbcH_alloc(h, sizeof(union _pbc_var) * (size+1) * 2);
memcpy(a->a, old, sizeof(union _pbc_var) * size);
} else {
a->a = (union _pbc_var *)_pbcM_realloc(a->a,sizeof(union _pbc_var) * (size+1) * 2);
}
}
}
}
a->a[a->number] = *var;
++ a->number;
}
void
_pbcA_index(pbc_array _array, int idx, pbc_var var)
{
struct array * a = (struct array *)_array;
var[0] = a->a[idx];
}
void *
_pbcA_index_p(pbc_array _array, int idx)
{
struct array * a = (struct array *)_array;
return &(a->a[idx]);
}
int
pbc_array_size(pbc_array _array) {
struct array * a = (struct array *)_array;
return a->number;
}
uint32_t
pbc_array_integer(pbc_array array, int index, uint32_t *hi) {
pbc_var var;
_pbcA_index(array , index , var);
if (hi) {
*hi = var->integer.hi;
}
return var->integer.low;
}
double
pbc_array_real(pbc_array array, int index) {
pbc_var var;
_pbcA_index(array , index , var);
return var->real;
}
struct pbc_slice *
pbc_array_slice(pbc_array _array, int index) {
struct array * a = (struct array *)_array;
if (index <0 || index > a->number) {
return NULL;
}
return (struct pbc_slice *) &(a->a[index]);
}
void
pbc_array_push_integer(pbc_array array, uint32_t low, uint32_t hi) {
pbc_var var;
var->integer.low = low;
var->integer.hi = hi;
_pbcA_push(array,var);
}
void
pbc_array_push_slice(pbc_array array, struct pbc_slice *s) {
pbc_var var;
var->m = *s;
_pbcA_push(array,var);
}
void
pbc_array_push_real(pbc_array array, double v) {
pbc_var var;
var->real = v;
_pbcA_push(array,var);
}