#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dynP.h"
int DynAppend(obj, els, num)
DynObjectP obj;
DynPtr els;
int num;
{
return DynInsert(obj, DynSize(obj), els, num);
}
#ifndef DEFAULT_INC
#define DEFAULT_INC 100
#endif
static int default_increment = DEFAULT_INC;
DynObjectP DynCreate(el_size, inc)
int el_size, inc;
{
DynObjectP obj;
obj = (DynObjectP) malloc(sizeof(DynObjectRecP));
if (obj == NULL)
return NULL;
obj->array = (DynPtr) malloc(1);
if (obj->array == NULL) {
free(obj);
return NULL;
}
obj->array[0] = '\0';
obj->el_size = el_size;
obj->num_el = obj->size = 0;
obj->debug = obj->paranoid = 0;
obj->inc = (inc) ? inc : default_increment;
obj->initzero = 0;
return obj;
}
DynObjectP DynCopy(obj)
DynObjectP obj;
{
DynObjectP obj1;
obj1 = (DynObjectP) malloc(sizeof(DynObjectRecP));
if (obj1 == NULL)
return NULL;
obj1->el_size = obj->el_size;
obj1->num_el = obj->num_el;
obj1->size = obj->size;
obj1->inc = obj->inc;
obj1->debug = obj->debug;
obj1->paranoid = obj->paranoid;
obj1->initzero = obj->initzero;
obj1->array = (char *) malloc((size_t) (obj1->el_size * obj1->size));
if (obj1->array == NULL) {
free(obj1);
return NULL;
}
memcpy(obj1->array, obj->array,
(size_t) (obj1->el_size * obj1->size));
return obj1;
}
int DynDestroy(obj)
DynObjectP obj;
{
if (obj->paranoid) {
if (obj->debug)
fprintf(stderr, "dyn: destroy: zeroing %d bytes from %p.\n",
obj->el_size * obj->size, obj->array);
memset(obj->array, 0, (size_t) (obj->el_size * obj->size));
}
free(obj->array);
free(obj);
return DYN_OK;
}
int DynRelease(obj)
DynObjectP obj;
{
if (obj->debug)
fprintf(stderr, "dyn: release: freeing object structure.\n");
free(obj);
return DYN_OK;
}
int DynDebug(obj, state)
DynObjectP obj;
int state;
{
obj->debug = state;
fprintf(stderr, "dyn: debug: Debug state set to %d.\n", state);
return DYN_OK;
}
int DynDelete(obj, idx)
DynObjectP obj;
int idx;
{
if (idx < 0) {
if (obj->debug)
fprintf(stderr, "dyn: delete: bad index %d\n", idx);
return DYN_BADINDEX;
}
if (idx >= obj->num_el) {
if (obj->debug)
fprintf(stderr, "dyn: delete: Highest index is %d.\n",
obj->num_el);
return DYN_BADINDEX;
}
if (idx == obj->num_el-1) {
if (obj->paranoid) {
if (obj->debug)
fprintf(stderr, "dyn: delete: last element, zeroing.\n");
memset(obj->array + idx*obj->el_size, 0, (size_t) obj->el_size);
}
else {
if (obj->debug)
fprintf(stderr, "dyn: delete: last element, punting.\n");
}
}
else {
if (obj->debug)
fprintf(stderr,
"dyn: delete: copying %d bytes from %p + %d to + %d.\n",
obj->el_size*(obj->num_el - idx), obj->array,
(idx+1)*obj->el_size, idx*obj->el_size);
memmove(obj->array + idx*obj->el_size,
obj->array + (idx+1)*obj->el_size,
(size_t) obj->el_size*(obj->num_el - idx));
if (obj->paranoid) {
if (obj->debug)
fprintf(stderr,
"dyn: delete: zeroing %d bytes from %p + %d\n",
obj->el_size, obj->array,
obj->el_size*(obj->num_el - 1));
memset(obj->array + obj->el_size*(obj->num_el - 1), 0,
(size_t) obj->el_size);
}
}
--obj->num_el;
if (obj->debug)
fprintf(stderr, "dyn: delete: done.\n");
return DYN_OK;
}
int DynInitzero(obj, state)
DynObjectP obj;
int state;
{
obj->initzero = state;
if (obj->debug)
fprintf(stderr, "dyn: initzero: initzero set to %d.\n", state);
return DYN_OK;
}
int DynInsert(obj, idx, els_in, num)
DynObjectP obj;
void *els_in;
int idx, num;
{
DynPtr els = (DynPtr) els_in;
int ret;
if (idx < 0 || idx > obj->num_el) {
if (obj->debug)
fprintf(stderr, "dyn: insert: index %d is not in [0,%d]\n",
idx, obj->num_el);
return DYN_BADINDEX;
}
if (num < 1) {
if (obj->debug)
fprintf(stderr, "dyn: insert: cannot insert %d elements\n",
num);
return DYN_BADVALUE;
}
if (obj->debug)
fprintf(stderr,"dyn: insert: Moving %d bytes from %p + %d to + %d\n",
(obj->num_el-idx)*obj->el_size, obj->array,
obj->el_size*idx, obj->el_size*(idx+num));
if ((ret = _DynResize(obj, obj->num_el + num)) != DYN_OK)
return ret;
memmove(obj->array + obj->el_size*(idx + num),
obj->array + obj->el_size*idx,
(size_t) ((obj->num_el-idx)*obj->el_size));
if (obj->debug)
fprintf(stderr, "dyn: insert: Copying %d bytes from %p to %p + %d\n",
obj->el_size*num, els, obj->array, obj->el_size*idx);
memmove(obj->array + obj->el_size*idx, els, (size_t) (obj->el_size*num));
obj->num_el += num;
if (obj->debug)
fprintf(stderr, "dyn: insert: done.\n");
return DYN_OK;
}
int DynParanoid(obj, state)
DynObjectP obj;
int state;
{
obj->paranoid = state;
if (obj->debug)
fprintf(stderr, "dyn: paranoid: Paranoia set to %d.\n", state);
return DYN_OK;
}
DynPtr DynArray(obj)
DynObjectP obj;
{
if (obj->debug)
fprintf(stderr, "dyn: array: returning array pointer %p.\n",
obj->array);
return obj->array;
}
DynPtr DynGet(obj, num)
DynObjectP obj;
int num;
{
if (num < 0) {
if (obj->debug)
fprintf(stderr, "dyn: get: bad index %d\n", num);
return NULL;
}
if (num >= obj->num_el) {
if (obj->debug)
fprintf(stderr, "dyn: get: highest element is %d.\n",
obj->num_el);
return NULL;
}
if (obj->debug)
fprintf(stderr, "dyn: get: Returning address %p + %d.\n",
obj->array, obj->el_size*num);
return (DynPtr) obj->array + obj->el_size*num;
}
int DynAdd(obj, el)
DynObjectP obj;
void *el;
{
int ret;
ret = DynPut(obj, el, obj->num_el);
if (ret != DYN_OK)
return ret;
++obj->num_el;
return ret;
}
int DynPut(obj, el_in, idx)
DynObjectP obj;
void *el_in;
int idx;
{
DynPtr el = (DynPtr) el_in;
int ret;
if (obj->debug)
fprintf(stderr, "dyn: put: Writing %d bytes from %p to %p + %d\n",
obj->el_size, el, obj->array, idx*obj->el_size);
if ((ret = _DynResize(obj, idx)) != DYN_OK)
return ret;
memmove(obj->array + idx*obj->el_size, el, (size_t) obj->el_size);
if (obj->debug)
fprintf(stderr, "dyn: put: done.\n");
return DYN_OK;
}
int _DynResize(obj, req)
DynObjectP obj;
int req;
{
int size;
if (obj->size > req)
return DYN_OK;
else if (obj->inc > 0)
return _DynRealloc(obj, (req - obj->size) / obj->inc + 1);
else {
if (obj->size == 0)
size = -obj->inc;
else
size = obj->size;
while (size <= req)
size <<= 1;
return _DynRealloc(obj, size);
}
}
int _DynRealloc(obj, num_incs)
DynObjectP obj;
int num_incs;
{
DynPtr temp;
int new_size_in_bytes;
if (obj->inc > 0)
new_size_in_bytes = obj->el_size*(obj->size + obj->inc*num_incs);
else
new_size_in_bytes = obj->el_size*num_incs;
if (obj->debug)
fprintf(stderr,
"dyn: alloc: Increasing object by %d bytes (%d incs).\n",
new_size_in_bytes - obj->el_size*obj->size,
num_incs);
temp = (DynPtr) realloc(obj->array, (size_t) new_size_in_bytes);
if (temp == NULL) {
if (obj->debug)
fprintf(stderr, "dyn: alloc: Out of memory.\n");
return DYN_NOMEM;
}
else {
obj->array = temp;
if (obj->inc > 0)
obj->size += obj->inc*num_incs;
else
obj->size = num_incs;
}
if (obj->debug)
fprintf(stderr, "dyn: alloc: done.\n");
return DYN_OK;
}
int DynSize(obj)
DynObjectP obj;
{
if (obj->debug)
fprintf(stderr, "dyn: size: returning size %d.\n", obj->num_el);
return obj->num_el;
}
int DynCapacity(obj)
DynObjectP obj;
{
if (obj->debug)
fprintf(stderr, "dyn: capacity: returning cap of %d.\n", obj->size);
return obj->size;
}