GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
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/gstypes.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 int 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 int free_data_buffs(dataset * ds, int typ)
394 {
395  int nsiz = 1, i, siz, freed = 0;
396 
397  for (i = 0; i < ds->ndims; i++) {
398  nsiz *= ds->dims[i];
399  }
400 
401  if (typ & ATTY_NULL) {
402  if (ds->databuff.nm) {
403  siz = BM_get_map_size(ds->databuff.nm);
404  BM_destroy(ds->databuff.nm);
405  ds->databuff.nm = NULL;
406  freed += siz;
407  }
408  }
409 
410  if (typ & ATTY_MASK) {
411  if (ds->databuff.bm) {
412  siz = BM_get_map_size(ds->databuff.bm);
413  BM_destroy(ds->databuff.bm);
414  ds->databuff.bm = NULL;
415  freed += siz;
416  }
417  }
418 
419  if (typ & ATTY_CHAR) {
420  if (ds->databuff.cb) {
421  siz = nsiz * sizeof(char);
422  free(ds->databuff.cb);
423  ds->databuff.cb = NULL;
424  freed += siz;
425  }
426  }
427 
428  if (typ & ATTY_SHORT) {
429  if (ds->databuff.sb) {
430  siz = nsiz * sizeof(short);
431  free(ds->databuff.sb);
432  ds->databuff.sb = NULL;
433  freed += siz;
434  }
435  }
436 
437  if (typ & ATTY_INT) {
438  if (ds->databuff.ib) {
439  siz = nsiz * sizeof(int);
440  free(ds->databuff.ib);
441  ds->databuff.ib = NULL;
442  freed += siz;
443  }
444  }
445 
446  if (typ & ATTY_FLOAT) {
447  if (ds->databuff.fb) {
448  siz = nsiz * sizeof(float);
449  free(ds->databuff.fb);
450  ds->databuff.fb = NULL;
451  freed += siz;
452  }
453  }
454 
455  Tot_mem -= freed;
456  ds->numbytes -= freed;
457 
458  if (freed) {
459  G_debug(5, "free_data_buffs(): freed data from id no. %d",
460  ds->data_id);
461  G_debug(5,
462  "free_data_buffs(): %.3f Kbytes freed, current total = %.3f",
463  freed / 1000., Tot_mem / 1000.);
464  }
465 
466  return (freed);
467 }
468 
481 int gsds_alloc_typbuff(int id, int *dims, int ndims, int type)
482 {
483  dataset *ds;
484  int i, siz = 1;
485 
486  if ((ds = get_dataset(id))) {
487  /*
488  free_data_buffs(ds);
489  careful here - allowing > 1 type to coexist (for float -> color conv.)
490  now also use this to allocate a null mask
491  (then if not used, use gsds_free_data_buff(id, ATTY_NULL))
492  */
493 
494  for (i = 0; i < ndims; i++) {
495  ds->dims[i] = dims[i];
496  siz *= dims[i];
497  }
498 
499  switch (type) {
500  case ATTY_NULL:
501  if (ndims != 2) {
502  /* higher dimension bitmaps not supported */
503  return (-1);
504  }
505 
506  if (NULL == (ds->databuff.nm = BM_create(dims[1], dims[0]))) {
507  return (-1);
508  }
509 
510  siz = BM_get_map_size(ds->databuff.nm);
511 
512  break;
513 
514  case ATTY_MASK:
515  if (ndims != 2) {
516  /* higher dimension bitmaps not supported */
517  return (-1);
518  }
519 
520  if (NULL == (ds->databuff.bm = BM_create(dims[1], dims[0]))) {
521  return (-1);
522  }
523 
524  siz = BM_get_map_size(ds->databuff.bm);
525 
526  break;
527 
528  case ATTY_CHAR:
529  siz *= sizeof(char);
530 
531  if (siz) {
532  if (NULL ==
533  (ds->databuff.cb = (unsigned char *)G_malloc(siz))) {
534  return (-1);
535  }
536  }
537  else {
538  return (-1);
539  }
540 
541  break;
542 
543  case ATTY_SHORT:
544  siz *= sizeof(short);
545 
546  if (siz) {
547  if (NULL == (ds->databuff.sb = (short *)G_malloc(siz))) {
548  return (-1);
549  }
550  }
551  else {
552  return (-1);
553  }
554 
555  break;
556 
557  case ATTY_INT:
558  siz *= sizeof(int);
559 
560  if (siz) {
561  if (NULL == (ds->databuff.ib = (int *)G_malloc(siz))) {
562  return (-1);
563  }
564  }
565  else {
566  return (-1);
567  }
568 
569  break;
570 
571  case ATTY_FLOAT:
572  siz *= sizeof(float);
573 
574  if (siz) {
575  if (NULL == (ds->databuff.fb = (float *)G_malloc(siz))) {
576  return (-1);
577  }
578  }
579  else {
580  return (-1);
581  }
582 
583  break;
584 
585  default:
586  return (-1);
587  }
588 
589  ds->changed = 0; /* starting with clean slate */
590  ds->need_reload = 1;
591  ds->numbytes += siz;
592  ds->ndims = ndims;
593  Tot_mem += siz;
594 
595  G_debug(5,
596  "gsds_alloc_typbuff(): %f Kbytes allocated, current total = %f",
597  siz / 1000., Tot_mem / 1000.);
598 
599  return (siz);
600  }
601 
602  return (-1);
603 }
604 
613 int gsds_get_changed(int id)
614 {
615  dataset *ds;
616 
617  if ((ds = get_dataset(id))) {
618  return ((int)ds->changed);
619  }
620 
621  return (-1);
622 }
623 
633 int gsds_set_changed(int id, IFLAG reason)
634 {
635  dataset *ds;
636 
637  if ((ds = get_dataset(id))) {
638  ds->changed = reason;
639  }
640 
641  return (-1);
642 }
643 
651 int gsds_get_type(int id)
652 {
653  dataset *ds;
654 
655  ds = get_dataset(id);
656 
657  return (get_type(ds));
658 }
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
int gsds_findh(const char *name, IFLAG *changes, IFLAG *types, int begin)
Get handle to gsds.
Definition: gsds.c:188
int
Definition: y.tab.c:1344
string name
Definition: render.py:1305
int free_data_buffs(dataset *ds, int typ)
Free data buffer.
Definition: gsds.c:393
typbuff * gsds_get_typbuff(int id, IFLAG change_flag)
Get data buffer.
Definition: gsds.c:281
int BM_destroy(struct BM *map)
Destroy bitmap and free all associated memory.
Definition: bitmap.c:90
int 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:481
int gsds_get_type(int id)
ADD.
Definition: gsds.c:651
#define LUCKY
Definition: gsds.c:63
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:613
int first
Definition: form/open.c:25
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
return NULL
Definition: dbfopen.c:1394
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
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:633
int BM_get_map_size(struct BM *map)
Returns size in bytes that bitmap is taking up.
Definition: bitmap.c:245
int gsds_free_datah(int id)
Free allocated dataset.
Definition: gsds.c:329