/src/gdal/frmts/pcraster/libcsf/kernlcsf.c
Line | Count | Source |
1 | | #include "csf.h" |
2 | | #include "csfimpl.h" |
3 | | |
4 | | #include <stdlib.h> |
5 | | |
6 | | /***************/ |
7 | | /* EXTERNALS */ |
8 | | /***************/ |
9 | | |
10 | | static MAP **mapList = NULL; |
11 | | static size_t mapListLen = 4; |
12 | | |
13 | | /*********************/ |
14 | | /* LOCAL DEFINITIONS */ |
15 | | /*********************/ |
16 | | |
17 | | /**********************/ |
18 | | /* LOCAL DECLARATIONS */ |
19 | | /**********************/ |
20 | | |
21 | | /******************/ |
22 | | /* IMPLEMENTATION */ |
23 | | /******************/ |
24 | | |
25 | | |
26 | | /* close all open maps at exit (LIBRARY_INTERNAL) |
27 | | * passed through atexit to c-library |
28 | | * exit code |
29 | | */ |
30 | | static void CsfCloseCsfKernel(void) |
31 | 2 | { |
32 | 2 | size_t i; |
33 | | |
34 | 10 | for(i = 0; i < mapListLen; i++) |
35 | 8 | if(mapList[i] != NULL) |
36 | 0 | if(Mclose(mapList[i])) |
37 | 0 | (void)fprintf(stderr,"CSF_INTERNAL_ERROR: unable to close %s at exit\n", |
38 | 0 | mapList[i]->fileName); |
39 | 2 | CSF_FREE(mapList); |
40 | 2 | mapList = NULL; |
41 | 2 | } |
42 | | |
43 | | /* boot the CSF runtime library (LIBRARY_INTERNAL) |
44 | | * CsfBootCsfKernel creates the mapList and adds the function to |
45 | | * close all files at a system exit |
46 | | * |
47 | | * NOTE |
48 | | * Note that CsfBootCsfKernel never returns if there isn't enough |
49 | | * memory to allocate an array of mapListLen pointers, or if |
50 | | * the atexit() call fails |
51 | | */ |
52 | | void CsfBootCsfKernel(void) |
53 | 2 | { |
54 | 2 | POSTCOND(mapList == NULL); |
55 | | |
56 | 2 | mapList = (MAP **)calloc(mapListLen,sizeof(MAP *)); |
57 | 2 | if (mapList == NULL) { |
58 | 0 | (void)fprintf(stderr,"CSF_INTERNAL_ERROR: Not enough memory to use CSF-files\n"); |
59 | 0 | exit(1); |
60 | 0 | } |
61 | | |
62 | 2 | if (atexit(CsfCloseCsfKernel)) { |
63 | 0 | (void)fprintf(stderr,"CSF_INTERNAL_ERROR: Impossible to close CSF-files automatically at exit\n"); |
64 | 0 | exit(1); |
65 | 0 | } |
66 | 2 | } |
67 | | |
68 | | /* check if the kernel is booted (LIBRARY_INTERNAL) |
69 | | * returns 0 if not, nonzero if already booted |
70 | | */ |
71 | | int CsfIsBootedCsfKernel(void) |
72 | 26 | { |
73 | 26 | return(mapList != NULL); |
74 | 26 | } |
75 | | |
76 | | /* put map in run time structure (LIBRARY_INTERNAL) |
77 | | * Every map opened or created is |
78 | | * registered in a list for verification |
79 | | * if functions get a valid map handle |
80 | | * passed and for automatic closing |
81 | | * at exit if the application forgets it. |
82 | | */ |
83 | | void CsfRegisterMap( |
84 | | MAP *m) /* map handle to be registered, the field m->mapListId is |
85 | | * initialized |
86 | | */ |
87 | 0 | { |
88 | 0 | size_t i=0; |
89 | |
|
90 | 0 | while (i < mapListLen && mapList[i] != NULL) |
91 | 0 | i++; |
92 | |
|
93 | 0 | if(i == mapListLen) |
94 | 0 | { |
95 | 0 | size_t j; |
96 | 0 | MAP** mapListNew; |
97 | | /* double size */ |
98 | | /* +1 to make clang static analyzer not warn about realloc(0) */ |
99 | 0 | mapListLen = 2 * mapListLen + 1; |
100 | 0 | mapListNew=realloc(mapList,sizeof(MAP *)*mapListLen); |
101 | 0 | if (mapListNew == NULL) { |
102 | 0 | (void)fprintf(stderr,"CSF_INTERNAL_ERROR: Not enough memory to use CSF-files\n"); |
103 | 0 | exit(1); |
104 | 0 | } |
105 | 0 | mapList = mapListNew; |
106 | | /* initialize new part, i at begin */ |
107 | 0 | for(j=i; j < mapListLen; ++j) |
108 | 0 | mapList[j]=0; |
109 | 0 | } |
110 | | |
111 | 0 | mapList[i] = m; |
112 | 0 | m->mapListId = (int)i; |
113 | 0 | } |
114 | | |
115 | | /* remove map from run time structure (LIBRARY_INTERNAL) |
116 | | * The map handle will become invalid. |
117 | | */ |
118 | | void CsfUnloadMap( |
119 | | MAP *m) /* map handle */ |
120 | 0 | { |
121 | 0 | POSTCOND(CsfIsValidMap(m)); |
122 | |
|
123 | 0 | mapList[m->mapListId] = NULL; |
124 | 0 | m->mapListId = -1; |
125 | 0 | } |
126 | | |
127 | | /* check if the map handle is created via the csf kernel (LIBRARY_INTERNAL) |
128 | | */ |
129 | | int CsfIsValidMap( |
130 | | const MAP *m) /* map handle */ |
131 | 0 | { |
132 | 0 | return(CsfIsBootedCsfKernel() && m != NULL |
133 | 0 | && m->mapListId >= 0 && ((size_t)m->mapListId) < mapListLen |
134 | 0 | && mapList[m->mapListId] == m); |
135 | 0 | } |