GRASS Programmer's Manual  6.4.2(2012)
gsds.c
Go to the documentation of this file.
00001 
00056 #include <stdlib.h>
00057 #include <string.h>
00058 
00059 #include <grass/gis.h>
00060 #include <grass/glocale.h>
00061 #include <grass/gstypes.h>
00062 
00063 #define LUCKY 33
00064 #define BLOC 20
00065 #define MAX_DS 100
00066 
00067 static int init_gsds(void);
00068 static int check_numsets(void);
00069 static dataset *get_dataset(int);
00070 static int get_type(dataset *);
00071 
00072 static dataset *Data[MAX_DS];
00073 static dataset Ds[MAX_DS];      /* trying to avoid allocation */
00074 
00075 static int Numsets = 0;
00076 
00077 static int Cur_id = LUCKY;
00078 static int Cur_max;
00079 static int Tot_mem = 0;
00080 
00084 static int init_gsds(void)
00085 {
00086     int i;
00087 
00088     for (i = 0; i < MAX_DS; i++) {
00089         /* avoiding dynamic allocation */
00090         Data[i] = &(Ds[i]);
00091     }
00092 
00093     Cur_max = MAX_DS;
00094 
00095     return (1);
00096 }
00097 
00103 static int check_numsets(void)
00104 {
00105     if (Numsets < Cur_max) {
00106         return (0);
00107     }
00108 
00109     G_fatal_error(_("Maximum number of datasets exceeded"));
00110 
00111     /* This return statement keeps compilers happy, it is never executed */
00112     return (0);
00113 }
00114 
00123 static dataset *get_dataset(int id)
00124 {
00125     int i;
00126 
00127     for (i = 0; i < Numsets; i++) {
00128         if (Data[i]->data_id == id) {
00129             return (Data[i]);
00130         }
00131     }
00132 
00133     return (NULL);
00134 }
00135 
00144 static int get_type(dataset * ds)
00145 {
00146     if (ds) {
00147         if (ds->databuff.bm) {
00148             return (ATTY_MASK);
00149         }
00150 
00151         if (ds->databuff.cb) {
00152             return (ATTY_CHAR);
00153         }
00154 
00155         if (ds->databuff.sb) {
00156             return (ATTY_SHORT);
00157         }
00158 
00159         if (ds->databuff.ib) {
00160             return (ATTY_INT);
00161         }
00162 
00163         if (ds->databuff.fb) {
00164             return (ATTY_FLOAT);
00165         }
00166     }
00167 
00168     return (-1);
00169 }
00170 
00188 int gsds_findh(const char *name, IFLAG * changes, IFLAG * types, int begin)
00189 {
00190     static int i;
00191     int start;
00192 
00193     start = begin ? 0 : i + 1;
00194 
00195     for (i = start; i < Numsets; i++) {
00196         if (!strcmp(Data[i]->unique_name, name)) {
00197             if ((Data[i]->changed & *changes) || !(Data[i]->changed)) {
00198                 if (get_type(Data[i]) & *types) {
00199                     *changes = Data[i]->changed;
00200                     *types = get_type(Data[i]);
00201 
00202                     return (Data[i]->data_id);
00203                 }
00204             }
00205         }
00206     }
00207 
00208     return (-1);
00209 }
00210 
00219 int gsds_newh(const char *name)
00220 {
00221     dataset *new;
00222     static int first = 1;
00223     int i;
00224 
00225     if (first) {
00226         if (0 > init_gsds()) {
00227             return (-1);
00228         }
00229 
00230         first = 0;
00231     }
00232     else if (0 > check_numsets()) {
00233         return (-1);
00234     }
00235 
00236     if (!name) {
00237         return (-1);
00238     }
00239 
00240     new = Data[Numsets];
00241 
00242     if (new) {
00243         Numsets++;
00244         new->data_id = Cur_id++;
00245 
00246         for (i = 0; i < MAXDIMS; i++) {
00247             new->dims[i] = 0;
00248         }
00249 
00250         new->unique_name = G_store(name);
00251         new->databuff.fb = NULL;
00252         new->databuff.ib = NULL;
00253         new->databuff.sb = NULL;
00254         new->databuff.cb = NULL;
00255         new->databuff.bm = NULL;
00256         new->databuff.nm = NULL;
00257         new->databuff.k = 0.0;
00258         new->changed = 0;
00259         new->ndims = 0;
00260         new->need_reload = 1;
00261 
00262         return (new->data_id);
00263     }
00264 
00265     return (-1);
00266 }
00267 
00281 typbuff *gsds_get_typbuff(int id, IFLAG change_flag)
00282 {
00283     dataset *ds;
00284 
00285     if ((ds = get_dataset(id))) {
00286         ds->changed = ds->changed | change_flag;
00287         ds->need_reload = 0;
00288 
00289         return (&(ds->databuff));
00290     }
00291 
00292     return (NULL);
00293 }
00294 
00303 char *gsds_get_name(int id)
00304 {
00305     int i;
00306     dataset *fds;
00307     static char retstr[GPATH_MAX];
00308 
00309     for (i = 0; i < Numsets; i++) {
00310         if (Data[i]->data_id == id) {
00311             fds = Data[i];
00312             strcpy(retstr, fds->unique_name);
00313 
00314             return (retstr);
00315         }
00316     }
00317 
00318     return (NULL);
00319 }
00320 
00329 int gsds_free_datah(int id)
00330 {
00331     int i, j, found = 0;
00332     dataset *fds;
00333 
00334     G_debug(3, "gsds_free_datah");
00335 
00336     for (i = 0; i < Numsets; i++) {
00337         if (Data[i]->data_id == id) {
00338             found = 1;
00339             fds = Data[i];
00340             free_data_buffs(fds, ATTY_ANY);
00341             G_free((void *)fds->unique_name);
00342             fds->unique_name = NULL;
00343             fds->data_id = 0;
00344 
00345             for (j = i; j < (Numsets - 1); j++) {
00346                 Data[j] = Data[j + 1];
00347             }
00348 
00349             Data[j] = fds;
00350         }
00351     }
00352 
00353     if (found) {
00354         --Numsets;
00355     }
00356 
00357     return (found);
00358 }
00359 
00369 int gsds_free_data_buff(int id, int typ)
00370 {
00371     int i, found = 0;
00372     dataset *fds;
00373 
00374     for (i = 0; i < Numsets; i++) {
00375         if (Data[i]->data_id == id) {
00376             found = 1;
00377             fds = Data[i];
00378             free_data_buffs(fds, typ);
00379         }
00380     }
00381 
00382     return (found);
00383 }
00384 
00393 int free_data_buffs(dataset * ds, int typ)
00394 {
00395     int nsiz = 1, i, siz, freed = 0;
00396 
00397     for (i = 0; i < ds->ndims; i++) {
00398         nsiz *= ds->dims[i];
00399     }
00400 
00401     if (typ & ATTY_NULL) {
00402         if (ds->databuff.nm) {
00403             siz = BM_get_map_size(ds->databuff.nm);
00404             BM_destroy(ds->databuff.nm);
00405             ds->databuff.nm = NULL;
00406             freed += siz;
00407         }
00408     }
00409 
00410     if (typ & ATTY_MASK) {
00411         if (ds->databuff.bm) {
00412             siz = BM_get_map_size(ds->databuff.bm);
00413             BM_destroy(ds->databuff.bm);
00414             ds->databuff.bm = NULL;
00415             freed += siz;
00416         }
00417     }
00418 
00419     if (typ & ATTY_CHAR) {
00420         if (ds->databuff.cb) {
00421             siz = nsiz * sizeof(char);
00422             free(ds->databuff.cb);
00423             ds->databuff.cb = NULL;
00424             freed += siz;
00425         }
00426     }
00427 
00428     if (typ & ATTY_SHORT) {
00429         if (ds->databuff.sb) {
00430             siz = nsiz * sizeof(short);
00431             free(ds->databuff.sb);
00432             ds->databuff.sb = NULL;
00433             freed += siz;
00434         }
00435     }
00436 
00437     if (typ & ATTY_INT) {
00438         if (ds->databuff.ib) {
00439             siz = nsiz * sizeof(int);
00440             free(ds->databuff.ib);
00441             ds->databuff.ib = NULL;
00442             freed += siz;
00443         }
00444     }
00445 
00446     if (typ & ATTY_FLOAT) {
00447         if (ds->databuff.fb) {
00448             siz = nsiz * sizeof(float);
00449             free(ds->databuff.fb);
00450             ds->databuff.fb = NULL;
00451             freed += siz;
00452         }
00453     }
00454 
00455     Tot_mem -= freed;
00456     ds->numbytes -= freed;
00457 
00458     if (freed) {
00459         G_debug(5, "free_data_buffs(): freed data from id no. %d",
00460                 ds->data_id);
00461         G_debug(5,
00462                 "free_data_buffs(): %.3f Kbytes freed, current total = %.3f",
00463                 freed / 1000., Tot_mem / 1000.);
00464     }
00465 
00466     return (freed);
00467 }
00468 
00481 int gsds_alloc_typbuff(int id, int *dims, int ndims, int type)
00482 {
00483     dataset *ds;
00484     int i, siz = 1;
00485 
00486     if ((ds = get_dataset(id))) {
00487         /*
00488            free_data_buffs(ds); 
00489            careful here - allowing > 1 type to coexist (for float -> color conv.)
00490            now also use this to allocate a null mask
00491            (then if not used, use gsds_free_data_buff(id, ATTY_NULL))
00492          */
00493 
00494         for (i = 0; i < ndims; i++) {
00495             ds->dims[i] = dims[i];
00496             siz *= dims[i];
00497         }
00498 
00499         switch (type) {
00500         case ATTY_NULL:
00501             if (ndims != 2) {
00502                 /* higher dimension bitmaps not supported */
00503                 return (-1);
00504             }
00505 
00506             if (NULL == (ds->databuff.nm = BM_create(dims[1], dims[0]))) {
00507                 return (-1);
00508             }
00509 
00510             siz = BM_get_map_size(ds->databuff.nm);
00511 
00512             break;
00513 
00514         case ATTY_MASK:
00515             if (ndims != 2) {
00516                 /* higher dimension bitmaps not supported */
00517                 return (-1);
00518             }
00519 
00520             if (NULL == (ds->databuff.bm = BM_create(dims[1], dims[0]))) {
00521                 return (-1);
00522             }
00523 
00524             siz = BM_get_map_size(ds->databuff.bm);
00525 
00526             break;
00527 
00528         case ATTY_CHAR:
00529             siz *= sizeof(char);
00530 
00531             if (siz) {
00532                 if (NULL ==
00533                     (ds->databuff.cb = (unsigned char *)G_malloc(siz))) {
00534                     return (-1);
00535                 }
00536             }
00537             else {
00538                 return (-1);
00539             }
00540 
00541             break;
00542 
00543         case ATTY_SHORT:
00544             siz *= sizeof(short);
00545 
00546             if (siz) {
00547                 if (NULL == (ds->databuff.sb = (short *)G_malloc(siz))) {
00548                     return (-1);
00549                 }
00550             }
00551             else {
00552                 return (-1);
00553             }
00554 
00555             break;
00556 
00557         case ATTY_INT:
00558             siz *= sizeof(int);
00559 
00560             if (siz) {
00561                 if (NULL == (ds->databuff.ib = (int *)G_malloc(siz))) {
00562                     return (-1);
00563                 }
00564             }
00565             else {
00566                 return (-1);
00567             }
00568 
00569             break;
00570 
00571         case ATTY_FLOAT:
00572             siz *= sizeof(float);
00573 
00574             if (siz) {
00575                 if (NULL == (ds->databuff.fb = (float *)G_malloc(siz))) {
00576                     return (-1);
00577                 }
00578             }
00579             else {
00580                 return (-1);
00581             }
00582 
00583             break;
00584 
00585         default:
00586             return (-1);
00587         }
00588 
00589         ds->changed = 0;        /* starting with clean slate */
00590         ds->need_reload = 1;
00591         ds->numbytes += siz;
00592         ds->ndims = ndims;
00593         Tot_mem += siz;
00594 
00595         G_debug(5,
00596                 "gsds_alloc_typbuff(): %f Kbytes allocated, current total = %f",
00597                 siz / 1000., Tot_mem / 1000.);
00598 
00599         return (siz);
00600     }
00601 
00602     return (-1);
00603 }
00604 
00613 int gsds_get_changed(int id)
00614 {
00615     dataset *ds;
00616 
00617     if ((ds = get_dataset(id))) {
00618         return ((int)ds->changed);
00619     }
00620 
00621     return (-1);
00622 }
00623 
00633 int gsds_set_changed(int id, IFLAG reason)
00634 {
00635     dataset *ds;
00636 
00637     if ((ds = get_dataset(id))) {
00638         ds->changed = reason;
00639     }
00640 
00641     return (-1);
00642 }
00643 
00651 int gsds_get_type(int id)
00652 {
00653     dataset *ds;
00654 
00655     ds = get_dataset(id);
00656 
00657     return (get_type(ds));
00658 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines