GRASS GIS 7 Programmer's Manual  7.0.5(2016)-r00000
gsds.c
Go to the documentation of this file.
1 
56 #include <stdlib.h>
57 #include <string.h>
58 
59 #include <grass/gis.h>
60 #include <grass/glocale.h>
61 #include <grass/ogsf.h>
62 
63 #define LUCKY 33
64 #define BLOC 20
65 #define MAX_DS 100
66 
67 static int init_gsds(void);
68 static int check_numsets(void);
69 static dataset *get_dataset(int);
70 static int get_type(dataset *);
71 
72 static dataset *Data[MAX_DS];
73 static dataset Ds[MAX_DS]; /* trying to avoid allocation */
74 
75 static int Numsets = 0;
76 
77 static int Cur_id = LUCKY;
78 static int Cur_max;
79 static size_t Tot_mem = 0;
80 
84 static int init_gsds(void)
85 {
86  int i;
87 
88  for (i = 0; i < MAX_DS; i++) {
89  /* avoiding dynamic allocation */
90  Data[i] = &(Ds[i]);
91  }
92 
93  Cur_max = MAX_DS;
94 
95  return (1);
96 }
97 
103 static int check_numsets(void)
104 {
105  if (Numsets < Cur_max) {
106  return (0);
107  }
108 
109  G_fatal_error(_("Maximum number of datasets exceeded"));
110 
111  /* This return statement keeps compilers happy, it is never executed */
112  return (0);
113 }
114 
123 static dataset *get_dataset(int id)
124 {
125  int i;
126 
127  for (i = 0; i < Numsets; i++) {
128  if (Data[i]->data_id == id) {
129  return (Data[i]);
130  }
131  }
132 
133  return (NULL);
134 }
135 
144 static int get_type(dataset * ds)
145 {
146  if (ds) {
147  if (ds->databuff.bm) {
148  return (ATTY_MASK);
149  }
150 
151  if (ds->databuff.cb) {
152  return (ATTY_CHAR);
153  }
154 
155  if (ds->databuff.sb) {
156  return (ATTY_SHORT);
157  }
158 
159  if (ds->databuff.ib) {
160  return (ATTY_INT);
161  }
162 
163  if (ds->databuff.fb) {
164  return (ATTY_FLOAT);
165  }
166  }
167 
168  return (-1);
169 }
170 
188 int gsds_findh(const char *name, IFLAG * changes, IFLAG * types, int begin)
189 {
190  static int i;
191  int start;
192 
193  start = begin ? 0 : i + 1;
194 
195  for (i = start; i < Numsets; i++) {
196  if (!strcmp(Data[i]->unique_name, name)) {
197  if ((Data[i]->changed & *changes) || !(Data[i]->changed)) {
198  if (get_type(Data[i]) & *types) {
199  *changes = Data[i]->changed;
200  *types = get_type(Data[i]);
201 
202  return (Data[i]->data_id);
203  }
204  }
205  }
206  }
207 
208  return (-1);
209 }
210 
219 int gsds_newh(const char *name)
220 {
221  dataset *new;
222  static int first = 1;
223  int i;
224 
225  if (first) {
226  if (0 > init_gsds()) {
227  return (-1);
228  }
229 
230  first = 0;
231  }
232  else if (0 > check_numsets()) {
233  return (-1);
234  }
235 
236  if (!name) {
237  return (-1);
238  }
239 
240  new = Data[Numsets];
241 
242  if (new) {
243  Numsets++;
244  new->data_id = Cur_id++;
245 
246  for (i = 0; i < MAXDIMS; i++) {
247  new->dims[i] = 0;
248  }
249 
250  new->unique_name = G_store(name);
251  new->databuff.fb = NULL;
252  new->databuff.ib = NULL;
253  new->databuff.sb = NULL;
254  new->databuff.cb = NULL;
255  new->databuff.bm = NULL;
256  new->databuff.nm = NULL;
257  new->databuff.k = 0.0;
258  new->changed = 0;
259  new->ndims = 0;
260  new->need_reload = 1;
261 
262  return (new->data_id);
263  }
264 
265  return (-1);
266 }
267 
281 typbuff *gsds_get_typbuff(int id, IFLAG change_flag)
282 {
283  dataset *ds;
284 
285  if ((ds = get_dataset(id))) {
286  ds->changed = ds->changed | change_flag;
287  ds->need_reload = 0;
288 
289  return (&(ds->databuff));
290  }
291 
292  return (NULL);
293 }
294 
303 char *gsds_get_name(int id)
304 {
305  int i;
306  dataset *fds;
307  static char retstr[GPATH_MAX];
308 
309  for (i = 0; i < Numsets; i++) {
310  if (Data[i]->data_id == id) {
311  fds = Data[i];
312  strcpy(retstr, fds->unique_name);
313 
314  return (retstr);
315  }
316  }
317 
318  return (NULL);
319 }
320 
329 int gsds_free_datah(int id)
330 {
331  int i, j, found = 0;
332  dataset *fds;
333 
334  G_debug(3, "gsds_free_datah");
335 
336  for (i = 0; i < Numsets; i++) {
337  if (Data[i]->data_id == id) {
338  found = 1;
339  fds = Data[i];
340  free_data_buffs(fds, ATTY_ANY);
341  G_free((void *)fds->unique_name);
342  fds->unique_name = NULL;
343  fds->data_id = 0;
344 
345  for (j = i; j < (Numsets - 1); j++) {
346  Data[j] = Data[j + 1];
347  }
348 
349  Data[j] = fds;
350  }
351  }
352 
353  if (found) {
354  --Numsets;
355  }
356 
357  return (found);
358 }
359 
369 int gsds_free_data_buff(int id, int typ)
370 {
371  int i, found = 0;
372  dataset *fds;
373 
374  for (i = 0; i < Numsets; i++) {
375  if (Data[i]->data_id == id) {
376  found = 1;
377  fds = Data[i];
378  free_data_buffs(fds, typ);
379  }
380  }
381 
382  return (found);
383 }
384 
393 size_t free_data_buffs(dataset * ds, int typ)
394 {
395  int i;
396  size_t siz, nsiz = 1, freed = 0;
397 
398  for (i = 0; i < ds->ndims; i++) {
399  nsiz *= ds->dims[i];
400  }
401 
402  if (typ & ATTY_NULL) {
403  if (ds->databuff.nm) {
404  siz = BM_get_map_size(ds->databuff.nm);
405  BM_destroy(ds->databuff.nm);
406  ds->databuff.nm = NULL;
407  freed += siz;
408  }
409  }
410 
411  if (typ & ATTY_MASK) {
412  if (ds->databuff.bm) {
413  siz = BM_get_map_size(ds->databuff.bm);
414  BM_destroy(ds->databuff.bm);
415  ds->databuff.bm = NULL;
416  freed += siz;
417  }
418  }
419 
420  if (typ & ATTY_CHAR) {
421  if (ds->databuff.cb) {
422  siz = nsiz * sizeof(char);
423  free(ds->databuff.cb);
424  ds->databuff.cb = NULL;
425  freed += siz;
426  }
427  }
428 
429  if (typ & ATTY_SHORT) {
430  if (ds->databuff.sb) {
431  siz = nsiz * sizeof(short);
432  free(ds->databuff.sb);
433  ds->databuff.sb = NULL;
434  freed += siz;
435  }
436  }
437 
438  if (typ & ATTY_INT) {
439  if (ds->databuff.ib) {
440  siz = nsiz * sizeof(int);
441  free(ds->databuff.ib);
442  ds->databuff.ib = NULL;
443  freed += siz;
444  }
445  }
446 
447  if (typ & ATTY_FLOAT) {
448  if (ds->databuff.fb) {
449  siz = nsiz * sizeof(float);
450  free(ds->databuff.fb);
451  ds->databuff.fb = NULL;
452  freed += siz;
453  }
454  }
455 
456  Tot_mem -= freed;
457  ds->numbytes -= freed;
458 
459  if (freed) {
460  G_debug(5, "free_data_buffs(): freed data from id no. %d",
461  ds->data_id);
462  G_debug(5,
463  "free_data_buffs(): %.3f Kbytes freed, current total = %.3f",
464  freed / 1000., Tot_mem / 1000.);
465  }
466 
467  return (freed);
468 }
469 
482 size_t gsds_alloc_typbuff(int id, int *dims, int ndims, int type)
483 {
484  dataset *ds;
485  int i;
486  size_t siz = 1;
487 
488  if ((ds = get_dataset(id))) {
489  /*
490  free_data_buffs(ds);
491  careful here - allowing > 1 type to coexist (for float -> color conv.)
492  now also use this to allocate a null mask
493  (then if not used, use gsds_free_data_buff(id, ATTY_NULL))
494  */
495 
496  for (i = 0; i < ndims; i++) {
497  ds->dims[i] = dims[i];
498  siz *= dims[i];
499  }
500 
501  switch (type) {
502  case ATTY_NULL:
503  if (ndims != 2) {
504  /* higher dimension bitmaps not supported */
505  return 0;
506  }
507 
508  if (NULL == (ds->databuff.nm = BM_create(dims[1], dims[0]))) {
509  return 0;
510  }
511 
512  siz = BM_get_map_size(ds->databuff.nm);
513 
514  break;
515 
516  case ATTY_MASK:
517  if (ndims != 2) {
518  /* higher dimension bitmaps not supported */
519  return (-1);
520  }
521 
522  if (NULL == (ds->databuff.bm = BM_create(dims[1], dims[0]))) {
523  return 0;
524  }
525 
526  siz = BM_get_map_size(ds->databuff.bm);
527 
528  break;
529 
530  case ATTY_CHAR:
531  siz *= sizeof(char);
532 
533  if (siz) {
534  if (NULL ==
535  (ds->databuff.cb = (unsigned char *)G_malloc(siz))) {
536  return 0;
537  }
538  }
539  else {
540  return 0;
541  }
542 
543  break;
544 
545  case ATTY_SHORT:
546  siz *= sizeof(short);
547 
548  if (siz) {
549  if (NULL == (ds->databuff.sb = (short *)G_malloc(siz))) {
550  return 0;
551  }
552  }
553  else {
554  return 0;
555  }
556 
557  break;
558 
559  case ATTY_INT:
560  siz *= sizeof(int);
561 
562  if (siz) {
563  if (NULL == (ds->databuff.ib = (int *)G_malloc(siz))) {
564  return 0;
565  }
566  }
567  else {
568  return 0;
569  }
570 
571  break;
572 
573  case ATTY_FLOAT:
574  siz *= sizeof(float);
575 
576  if (siz) {
577  if (NULL == (ds->databuff.fb = (float *)G_malloc(siz))) {
578  return 0;
579  }
580  }
581  else {
582  return 0;
583  }
584 
585  break;
586 
587  default:
588  return 0;
589  }
590 
591  ds->changed = 0; /* starting with clean slate */
592  ds->need_reload = 1;
593  ds->numbytes += siz;
594  ds->ndims = ndims;
595  Tot_mem += siz;
596 
597  G_debug(5,
598  "gsds_alloc_typbuff(): %f Kbytes allocated, current total = %f",
599  siz / 1000., Tot_mem / 1000.);
600 
601  return (siz);
602  }
603 
604  return 0;
605 }
606 
615 int gsds_get_changed(int id)
616 {
617  dataset *ds;
618 
619  if ((ds = get_dataset(id))) {
620  return ((int)ds->changed);
621  }
622 
623  return (-1);
624 }
625 
635 int gsds_set_changed(int id, IFLAG reason)
636 {
637  dataset *ds;
638 
639  if ((ds = get_dataset(id))) {
640  ds->changed = reason;
641  }
642 
643  return (-1);
644 }
645 
653 int gsds_get_type(int id)
654 {
655  dataset *ds;
656 
657  ds = get_dataset(id);
658 
659  return (get_type(ds));
660 }
int gsds_findh(const char *name, IFLAG *changes, IFLAG *types, int begin)
Get handle to gsds.
Definition: gsds.c:188
size_t gsds_alloc_typbuff(int id, int *dims, int ndims, int type)
Allocates correct buffer according to type, keeps track of total mem.
Definition: gsds.c:482
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:86
typbuff * gsds_get_typbuff(int id, IFLAG change_flag)
Get data buffer.
Definition: gsds.c:281
#define NULL
Definition: ccmath.h:32
int BM_destroy(struct BM *map)
Destroy bitmap and free all associated memory.
Definition: bitmap.c:90
int gsds_get_type(int id)
ADD.
Definition: gsds.c:653
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
#define LUCKY
Definition: gsds.c:63
size_t free_data_buffs(dataset *ds, int typ)
Free data buffer.
Definition: gsds.c:393
char * gsds_get_name(int id)
Get name.
Definition: gsds.c:303
int gsds_free_data_buff(int id, int typ)
Free allocated buffer.
Definition: gsds.c:369
int gsds_get_changed(int id)
ADD.
Definition: gsds.c:615
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
struct BM * BM_create(int x, int y)
Create bitmap of dimension x/y and return structure token.
Definition: bitmap.c:60
#define MAX_DS
Definition: gsds.c:65
size_t BM_get_map_size(struct BM *map)
Returns size in bytes that bitmap is taking up.
Definition: bitmap.c:245
const char * name
Definition: named_colr.c:7
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
int gsds_newh(const char *name)
Get handle to gsds.
Definition: gsds.c:219
int gsds_set_changed(int id, IFLAG reason)
ADD.
Definition: gsds.c:635
int gsds_free_datah(int id)
Free allocated dataset.
Definition: gsds.c:329