/src/PROJ/src/initcache.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * Project: PROJ.4 |
3 | | * Purpose: init file definition cache. |
4 | | * Author: Frank Warmerdam, warmerdam@pobox.com |
5 | | * |
6 | | ****************************************************************************** |
7 | | * Copyright (c) 2009, Frank Warmerdam |
8 | | * |
9 | | * Permission is hereby granted, free of charge, to any person obtaining a |
10 | | * copy of this software and associated documentation files (the "Software"), |
11 | | * to deal in the Software without restriction, including without limitation |
12 | | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
13 | | * and/or sell copies of the Software, and to permit persons to whom the |
14 | | * Software is furnished to do so, subject to the following conditions: |
15 | | * |
16 | | * The above copyright notice and this permission notice shall be included |
17 | | * in all copies or substantial portions of the Software. |
18 | | * |
19 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
20 | | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
22 | | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
24 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
25 | | * DEALINGS IN THE SOFTWARE. |
26 | | *****************************************************************************/ |
27 | | |
28 | | #include <assert.h> |
29 | | #include <string.h> |
30 | | |
31 | | #include "proj.h" |
32 | | #include "proj_internal.h" |
33 | | |
34 | | static int cache_count = 0; |
35 | | static int cache_alloc = 0; |
36 | | static char **cache_key = nullptr; |
37 | | static paralist **cache_paralist = nullptr; |
38 | | |
39 | | /************************************************************************/ |
40 | | /* pj_clone_paralist() */ |
41 | | /* */ |
42 | | /* Allocate a copy of a parameter list. */ |
43 | | /************************************************************************/ |
44 | | |
45 | 982 | paralist *pj_clone_paralist(const paralist *list) { |
46 | 982 | paralist *list_copy = nullptr, *next_copy = nullptr; |
47 | | |
48 | 5.80k | for (; list != nullptr; list = list->next) { |
49 | 4.82k | paralist *newitem = |
50 | 4.82k | (paralist *)malloc(sizeof(paralist) + strlen(list->param)); |
51 | 4.82k | assert(newitem); |
52 | | |
53 | 4.82k | newitem->used = 0; |
54 | 4.82k | newitem->next = nullptr; |
55 | 4.82k | strcpy(newitem->param, list->param); |
56 | | |
57 | 4.82k | if (next_copy) |
58 | 3.84k | next_copy->next = newitem; |
59 | 982 | else |
60 | 982 | list_copy = newitem; |
61 | | |
62 | 4.82k | next_copy = newitem; |
63 | 4.82k | } |
64 | | |
65 | 982 | return list_copy; |
66 | 982 | } |
67 | | |
68 | | /************************************************************************/ |
69 | | /* pj_clear_initcache() */ |
70 | | /* */ |
71 | | /* Clear out all memory held in the init file cache. */ |
72 | | /************************************************************************/ |
73 | | |
74 | 11.3k | void pj_clear_initcache() { |
75 | 11.3k | if (cache_alloc > 0) { |
76 | 227 | int i; |
77 | | |
78 | 227 | pj_acquire_lock(); |
79 | | |
80 | 521 | for (i = 0; i < cache_count; i++) { |
81 | 294 | paralist *n, *t = cache_paralist[i]; |
82 | | |
83 | 294 | free(cache_key[i]); |
84 | | |
85 | | /* free parameter list elements */ |
86 | 1.93k | for (; t != nullptr; t = n) { |
87 | 1.63k | n = t->next; |
88 | 1.63k | free(t); |
89 | 1.63k | } |
90 | 294 | } |
91 | | |
92 | 227 | free(cache_key); |
93 | 227 | free(cache_paralist); |
94 | 227 | cache_count = 0; |
95 | 227 | cache_alloc = 0; |
96 | 227 | cache_key = nullptr; |
97 | 227 | cache_paralist = nullptr; |
98 | | |
99 | 227 | pj_release_lock(); |
100 | 227 | } |
101 | 11.3k | } |
102 | | |
103 | | /************************************************************************/ |
104 | | /* pj_search_initcache() */ |
105 | | /* */ |
106 | | /* Search for a matching definition in the init cache. */ |
107 | | /************************************************************************/ |
108 | | |
109 | | paralist *pj_search_initcache(const char *filekey) |
110 | | |
111 | 1.37k | { |
112 | 1.37k | int i; |
113 | 1.37k | paralist *result = nullptr; |
114 | | |
115 | 1.37k | pj_acquire_lock(); |
116 | | |
117 | 2.53k | for (i = 0; result == nullptr && i < cache_count; i++) { |
118 | 1.16k | if (strcmp(filekey, cache_key[i]) == 0) { |
119 | 688 | result = pj_clone_paralist(cache_paralist[i]); |
120 | 688 | } |
121 | 1.16k | } |
122 | | |
123 | 1.37k | pj_release_lock(); |
124 | | |
125 | 1.37k | return result; |
126 | 1.37k | } |
127 | | |
128 | | /************************************************************************/ |
129 | | /* pj_insert_initcache() */ |
130 | | /* */ |
131 | | /* Insert a paralist definition in the init file cache. */ |
132 | | /************************************************************************/ |
133 | | |
134 | | void pj_insert_initcache(const char *filekey, const paralist *list) |
135 | | |
136 | 294 | { |
137 | 294 | pj_acquire_lock(); |
138 | | |
139 | | /* |
140 | | ** Grow list if required. |
141 | | */ |
142 | 294 | if (cache_count == cache_alloc) { |
143 | 227 | char **cache_key_new; |
144 | 227 | paralist **cache_paralist_new; |
145 | | |
146 | 227 | cache_alloc = cache_alloc * 2 + 15; |
147 | | |
148 | 227 | cache_key_new = (char **)malloc(sizeof(char *) * cache_alloc); |
149 | 227 | assert(cache_key_new); |
150 | 227 | if (cache_key && cache_count) { |
151 | 0 | memcpy(cache_key_new, cache_key, sizeof(char *) * cache_count); |
152 | 0 | } |
153 | 227 | free(cache_key); |
154 | 227 | cache_key = cache_key_new; |
155 | | |
156 | 227 | cache_paralist_new = |
157 | 227 | (paralist **)malloc(sizeof(paralist *) * cache_alloc); |
158 | 227 | assert(cache_paralist_new); |
159 | 227 | if (cache_paralist && cache_count) { |
160 | 0 | memcpy(cache_paralist_new, cache_paralist, |
161 | 0 | sizeof(paralist *) * cache_count); |
162 | 0 | } |
163 | 227 | free(cache_paralist); |
164 | 227 | cache_paralist = cache_paralist_new; |
165 | 227 | } |
166 | | |
167 | | /* |
168 | | ** Duplicate the filekey and paralist, and insert in cache. |
169 | | */ |
170 | 294 | cache_key[cache_count] = (char *)malloc(strlen(filekey) + 1); |
171 | 294 | assert(cache_key[cache_count]); |
172 | 294 | strcpy(cache_key[cache_count], filekey); |
173 | | |
174 | 294 | cache_paralist[cache_count] = pj_clone_paralist(list); |
175 | | |
176 | 294 | cache_count++; |
177 | | |
178 | 294 | pj_release_lock(); |
179 | 294 | } |