Coverage Report

Created: 2026-04-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/proj/src/initcache.cpp
Line
Count
Source
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
20.4k
paralist *pj_clone_paralist(const paralist *list) {
46
20.4k
    paralist *list_copy = nullptr, *next_copy = nullptr;
47
48
69.8k
    for (; list != nullptr; list = list->next) {
49
49.4k
        paralist *newitem =
50
49.4k
            (paralist *)malloc(sizeof(paralist) + strlen(list->param));
51
49.4k
        assert(newitem);
52
53
49.4k
        newitem->used = 0;
54
49.4k
        newitem->next = nullptr;
55
49.4k
        strcpy(newitem->param, list->param);
56
57
49.4k
        if (next_copy)
58
29.0k
            next_copy->next = newitem;
59
20.4k
        else
60
20.4k
            list_copy = newitem;
61
62
49.4k
        next_copy = newitem;
63
49.4k
    }
64
65
20.4k
    return list_copy;
66
20.4k
}
67
68
/************************************************************************/
69
/*                            pj_clear_initcache()                      */
70
/*                                                                      */
71
/*      Clear out all memory held in the init file cache.               */
72
/************************************************************************/
73
74
0
void pj_clear_initcache() {
75
0
    if (cache_alloc > 0) {
76
0
        int i;
77
78
0
        pj_acquire_lock();
79
80
0
        for (i = 0; i < cache_count; i++) {
81
0
            paralist *n, *t = cache_paralist[i];
82
83
0
            free(cache_key[i]);
84
85
            /* free parameter list elements */
86
0
            for (; t != nullptr; t = n) {
87
0
                n = t->next;
88
0
                free(t);
89
0
            }
90
0
        }
91
92
0
        free(cache_key);
93
0
        free(cache_paralist);
94
0
        cache_count = 0;
95
0
        cache_alloc = 0;
96
0
        cache_key = nullptr;
97
0
        cache_paralist = nullptr;
98
99
0
        pj_release_lock();
100
0
    }
101
0
}
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
21.9k
{
112
21.9k
    int i;
113
21.9k
    paralist *result = nullptr;
114
115
21.9k
    pj_acquire_lock();
116
117
2.26M
    for (i = 0; result == nullptr && i < cache_count; i++) {
118
2.24M
        if (strcmp(filekey, cache_key[i]) == 0) {
119
20.2k
            result = pj_clone_paralist(cache_paralist[i]);
120
20.2k
        }
121
2.24M
    }
122
123
21.9k
    pj_release_lock();
124
125
21.9k
    return result;
126
21.9k
}
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
223
{
137
223
    pj_acquire_lock();
138
139
    /*
140
    ** Grow list if required.
141
    */
142
223
    if (cache_count == cache_alloc) {
143
4
        char **cache_key_new;
144
4
        paralist **cache_paralist_new;
145
146
4
        cache_alloc = cache_alloc * 2 + 15;
147
148
4
        cache_key_new = (char **)malloc(sizeof(char *) * cache_alloc);
149
4
        assert(cache_key_new);
150
4
        if (cache_key && cache_count) {
151
3
            memcpy(cache_key_new, cache_key, sizeof(char *) * cache_count);
152
3
        }
153
4
        free(cache_key);
154
4
        cache_key = cache_key_new;
155
156
4
        cache_paralist_new =
157
4
            (paralist **)malloc(sizeof(paralist *) * cache_alloc);
158
4
        assert(cache_paralist_new);
159
4
        if (cache_paralist && cache_count) {
160
3
            memcpy(cache_paralist_new, cache_paralist,
161
3
                   sizeof(paralist *) * cache_count);
162
3
        }
163
4
        free(cache_paralist);
164
4
        cache_paralist = cache_paralist_new;
165
4
    }
166
167
    /*
168
    ** Duplicate the filekey and paralist, and insert in cache.
169
    */
170
223
    cache_key[cache_count] = (char *)malloc(strlen(filekey) + 1);
171
223
    assert(cache_key[cache_count]);
172
223
    strcpy(cache_key[cache_count], filekey);
173
174
223
    cache_paralist[cache_count] = pj_clone_paralist(list);
175
176
223
    cache_count++;
177
178
223
    pj_release_lock();
179
223
}