123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- #include "pointergrid.h"
- /** Allocates a new, uninitialized PointerGrid. */
- PointerGrid * pointergrid_alloc(void) {
- return mem_alloc(sizeof(PointerGrid));
- }
- /** Nulls out all the data in pointergrid. If memdestructor is not NULL,
- * it will be called with the old value in the cell before NULL is set.
- */
- int pointergrid_nullall(PointerGrid * self, MemDestructor * destroy) {
- int w, h, x, y;
- if (!self) return -1;
- if (!self->data) return -1;
- w = pointergrid_w(self);
- h = pointergrid_h(self);
- for(y = 0; y < h ; y++) {
- for(x = 0; x < w ; x++) {
- void * cell = pointergrid_getraw(self, x, y);
- if (destroy && cell) {
- destroy(cell);
- }
- pointergrid_putraw(self, x, y, NULL);
- }
- }
- return 0;
- }
- /** Cleans up and deinitializes the PointerGrid self,
- using the destructor if needed */
- PointerGrid * pointergrid_done(PointerGrid * self, MemDestructor * destroy) {
- int index;
- if(!self) return NULL;
- if(!self->data) return self;
- for (index = 0; index < self->h; index ++) {
- if(self->data[index]) {
- /* Clean up elements if needed. */
- if(destroy) {
- pointergrid_nullall(self, destroy);
- }
- mem_free(self->data[index]);
- }
- self->data[index] = NULL;
- }
-
- self->w = -1;
- self->h = -1;
- mem_free(self->data);
- return self;
- }
- /** Calls PointerGrid_done, and then frees the PointerGrid self. Returns NULL. */
- PointerGrid * pointergrid_free(PointerGrid * self) {
- pointergrid_done(self, NULL);
- mem_free(self);
- return NULL;
- }
- /** Returns the width of the PointerGrid. Returns -1 is self isn't propery
- * initialized.
- */
- int pointergrid_w(PointerGrid * self) {
- if(!self) return -1;
- return self->w;
- }
- /** Returns the height of the PointerGrid.
- * Returns -1 is self isn't propery initialized. */
- int pointergrid_h(PointerGrid * self) {
- if(!self) return -1;
- return self->h;
- }
- /** Initializes a PointerGrid to be of the given width and height.
- * Returns NULL on error, or if h or w are less than 1.
- * Returns self on sucess.
- */
- PointerGrid * pointergrid_init(PointerGrid * self, int w, int h) {
- int index;
- if(!self) return NULL;
- self->w = w;
- self->h = h;
- self->data = NULL;
- if ((self->h <= 0) || (self->w <= 0)) { return NULL; }
- // Allocate y dimension
- self->data = (intptr_t **) mem_alloc(sizeof(intptr_t *) * self->h);
- if(!self->data) return NULL;
- // Now allocate the x dimensions.
- for (index = 0; index < self->h; index ++) {
- self->data[index] = (intptr_t *) mem_alloc(sizeof(intptr_t) * self->w);
- if(!self->data[index]) return pointergrid_free(self);
- }
- return self;
- }
- /** Allocates a new grid and initializes it. */
- PointerGrid * pointergrid_new(int w, int h) {
- PointerGrid * self = pointergrid_alloc();
- return pointergrid_init(self, w, h);
- }
-
- /**
- * Return true if the arguments x and or y are out of range, or
- * if self itself isn't properly initialized. Return false if OK.
- */
- int pointergrid_outofrange(PointerGrid * self, int x, int y) {
- if(!self) return TRUE;
- if(!self->data) return TRUE;
- if ((x < 0) || (y < 0)) { return TRUE; }
- if ((y >= self->h) || (x >= self->w)) { return TRUE; }
- return FALSE;
- }
- /** Gets an element from the grid. Does no checking whatsoever.
- * Use only where the inputs are guaranteed to be valid, where speed is
- * of the essence.
- */
- void * pointergrid_getraw(PointerGrid * self, int x, int y) {
- return (void *)self->data[y][x];
- }
- /** Gets a row of elements from the grid. Does no checking whatsoever.
- * Use only where the inputs are guaranteed to be valid, where speed is
- * of the essence.
- */
- void * * pointergrid_rowraw(PointerGrid * self, int y) {
- return (void **) self->data[y];
- }
- /** Gets an element from the grid self.
- * If all goes well, this function returns 0, and sets the value to
- * (*result).
- * If w and h are out of range, or the grid isn't correctly initialized,
- * does nothing and returns -1 in stead.
- */
- int pointergrid_get(PointerGrid * self, int x, int y, void * * result) {
- void * * aid;
- if(pointergrid_outofrange(self,x,y)) { return -1; }
- (*result) = pointergrid_getraw(self,x,y);
- return 0;
- }
- /** Puts an element in the grid self. Does no checking whatsoever.
- * Use only where the inputs are guaranteed to be valid, where speed is
- * of the essence.
- */
- void pointergrid_putraw(PointerGrid * self, int x, int y, void * el) {
- self->data[y][x] = (intptr_t)el;
- }
- /** Puts and element into the grid self.
- * If all goes well, this function returns 0.
- * If w and h are out of range, or the grid isn't correctly initialized,
- * does nothing and returns -1 in stead.
- */
- int pointergrid_put(PointerGrid * self, int x, int y, void * el) {
- if(pointergrid_outofrange(self,x,y)) { return -1; }
- pointergrid_putraw(self,x,y,el);
- return 0;
- }
- /** Sets and element into the grid self.
- * If all goes well, this function returns el.
- * If w and h are out of range, or the grid isn't correctly initialized,
- * does nothing and returns NULL in stead.
- */
- void * pointergrid_store(PointerGrid * self, int x, int y, void * el) {
- if(pointergrid_outofrange(self,x,y)) { return NULL; }
- pointergrid_putraw(self,x,y,el);
- return el;
- }
- /** Fetched an element from the grid self.
- * If all goes well, this returns the result.
- * If w and h are out of range, or the grid isn't correctly initialized,
- * returns NULL.
- */
- void * pointergrid_fetch(PointerGrid * self, int x, int y) {
- if (pointergrid_outofrange(self,x,y)) { return NULL; }
- return pointergrid_getraw(self,x,y);
- }
- /** Copies the data from one grid to the other.
- * If the grides are of unequal size, copies the smallest of both
- * heights and widths.
- * Returns 0 on succes, -1 on error.
- */
- int pointergrid_copy(PointerGrid * self, PointerGrid * other) {
- int ws, hs, wo, ho, w, h, x, y;
- if ((!self) || (!other)) return -1;
- if ((!self->data) || (!other->data)) return -1;
- ws = pointergrid_w(self);
- hs = pointergrid_h(self);
-
- wo = pointergrid_w(other);
- ho = pointergrid_h(other);
- // Copy only smallest of width and height.
- w = (ws < wo ? ws : wo);
- h = (hs < ho ? hs : ho);
- for(y = 0; y < h ; y++) {
- for(x = 0; x < w ; x++) {
- self->data[y][x] = other->data[y][x];
- }
- }
- return 0;
- }
- /** Gets an element from the grid. Does no checking whatsoever.
- * Use only where the inputs are guaranteed to be valid, where speed is
- * of the essence.
- */
- intptr_t pointergrid_get_raw_int(PointerGrid * self, int x, int y) {
- return self->data[y][x];
- }
- /** Gets a row of elements from the grid. Does no checking whatsoever.
- * Use only where the inputs are guaranteed to be valid, where speed is
- * of the essence.
- */
- intptr_t * pointergrid_row_raw_int(PointerGrid * self, int y) {
- return self->data[y];
- }
- /** Gets an integer value from the grid self.
- * If all goes well, this function returns 0, and sets the value to
- * (*result).
- * If w and h are out of range, or the grid isn't correctly initialized,
- * does nothing and returns -1 in stead.
- */
- int pointergrid_get_int(PointerGrid * self, int x, int y, int * result) {
- if(pointergrid_outofrange(self,x,y)) { return -1; }
- (*result) = (int) pointergrid_get_raw_int(self, x, y);
- return 0;
- }
- /** Puts an integer in the grid self. Does no checking whatsoever.
- * Use only where the inputs are guaranteed to be valid, where speed is
- * of the essence.
- */
- void pointergrid_put_raw_int(PointerGrid * self, int x, int y, int el) {
- self->data[y][x] = (intptr_t)el;
- }
- /** Puts an integer into the grid self.
- * If all goes well, this function returns 0.
- * If w and h are out of range, or the grid isn't correctly initialized,
- * does nothing and returns -1 in stead.
- */
- int pointergrid_put_int(PointerGrid * self, int x, int y, int el) {
- if(pointergrid_outofrange(self,x,y)) { return -1; }
- pointergrid_put_raw_int(self,x,y,el);
- return 0;
- }
- /** Sets and element into the grid self.
- * If all goes well, this function returns el.
- * If w and h are out of range, or the grid isn't correctly initialized,
- * does nothing and returns 0 in stead.
- */
- int pointergrid_store_int(PointerGrid * self, int x, int y, int el) {
- if(pointergrid_outofrange(self, x, y)) { return 0; }
- pointergrid_put_raw_int(self, x, y, el);
- return el;
- }
- /** Fetched an element from the grid self.
- * If all goes well, this returns the result.
- * If w and h are out of range, or the grid isn't correctly initialized,
- * returns 0.
- */
- int pointergrid_fetch_int(PointerGrid * self, int x, int y) {
- if (pointergrid_outofrange(self,x,y)) { return 0; }
- return (int) pointergrid_get_raw_int(self,x,y);
- }
- /** Sets all the pointer grid to a 0 integer. Do NOT do this
- * if the pointergrid is intent to store pointer, only if it stores integers.
- */
- int pointergrid_zero_all(PointerGrid * self) {
- int w, h, x, y;
- if (!self) return -1;
- if (!self->data) return -1;
- w = pointergrid_w(self);
- h = pointergrid_h(self);
- for(y = 0; y < h ; y++) {
- for(x = 0; x < w ; x++) {
- pointergrid_put_raw_int(self, x, y, 0);
- }
- }
- return 0;
- }
|