1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: MIT
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Stupid implementation of pointer -> pointer map.
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci * Copyright (c) 2017 Luc Van Oostenryck.
6f08c3bdfSopenharmony_ci *
7f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
8f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal
9f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights
10f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is
12f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions:
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in
15f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software.
16f08c3bdfSopenharmony_ci *
17f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23f08c3bdfSopenharmony_ci * THE SOFTWARE.
24f08c3bdfSopenharmony_ci */
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_ci#include "ptrmap.h"
27f08c3bdfSopenharmony_ci#include "allocate.h"
28f08c3bdfSopenharmony_ci#include <stddef.h>
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci#define	MAP_NR	7
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_cistruct ptrpair {
33f08c3bdfSopenharmony_ci	void *key;
34f08c3bdfSopenharmony_ci	void *val;
35f08c3bdfSopenharmony_ci};
36f08c3bdfSopenharmony_cistruct ptrmap {
37f08c3bdfSopenharmony_ci	struct ptrmap *next;
38f08c3bdfSopenharmony_ci	int nr;
39f08c3bdfSopenharmony_ci	struct ptrpair pairs[MAP_NR];
40f08c3bdfSopenharmony_ci};
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_ciDECLARE_ALLOCATOR(ptrmap);
43f08c3bdfSopenharmony_ciALLOCATOR(ptrmap, "ptrmap");
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_civoid __ptrmap_add(struct ptrmap **mapp, void *key, void *val)
46f08c3bdfSopenharmony_ci{
47f08c3bdfSopenharmony_ci	struct ptrmap *head = *mapp;
48f08c3bdfSopenharmony_ci	struct ptrmap *newmap;
49f08c3bdfSopenharmony_ci	struct ptrmap *map;
50f08c3bdfSopenharmony_ci	struct ptrpair *pair;
51f08c3bdfSopenharmony_ci	int nr;
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	if ((map = head)) {
54f08c3bdfSopenharmony_ci		struct ptrmap *next = map->next;
55f08c3bdfSopenharmony_ci		if (next)		// head is full
56f08c3bdfSopenharmony_ci			map = next;
57f08c3bdfSopenharmony_ci		if ((nr = map->nr) < MAP_NR)
58f08c3bdfSopenharmony_ci			goto oldmap;
59f08c3bdfSopenharmony_ci	}
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	// need a new block
62f08c3bdfSopenharmony_ci	newmap = __alloc_ptrmap(0);
63f08c3bdfSopenharmony_ci	if (!head) {
64f08c3bdfSopenharmony_ci		*mapp = newmap;
65f08c3bdfSopenharmony_ci	} else {
66f08c3bdfSopenharmony_ci		newmap->next = head->next;
67f08c3bdfSopenharmony_ci		head->next = newmap;
68f08c3bdfSopenharmony_ci	}
69f08c3bdfSopenharmony_ci	map = newmap;
70f08c3bdfSopenharmony_ci	nr = 0;
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_cioldmap:
73f08c3bdfSopenharmony_ci	pair = &map->pairs[nr];
74f08c3bdfSopenharmony_ci	pair->key = key;
75f08c3bdfSopenharmony_ci	pair->val = val;
76f08c3bdfSopenharmony_ci	map->nr = ++nr;
77f08c3bdfSopenharmony_ci}
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_civoid *__ptrmap_lookup(struct ptrmap *map, void *key)
80f08c3bdfSopenharmony_ci{
81f08c3bdfSopenharmony_ci	for (; map; map = map->next) {
82f08c3bdfSopenharmony_ci		int i, n = map->nr;
83f08c3bdfSopenharmony_ci		for (i = 0; i < n; i++) {
84f08c3bdfSopenharmony_ci			struct ptrpair *pair = &map->pairs[i];
85f08c3bdfSopenharmony_ci			if (pair->key == key)
86f08c3bdfSopenharmony_ci				return pair->val;
87f08c3bdfSopenharmony_ci		}
88f08c3bdfSopenharmony_ci	}
89f08c3bdfSopenharmony_ci	return NULL;
90f08c3bdfSopenharmony_ci}
91f08c3bdfSopenharmony_ci
92f08c3bdfSopenharmony_civoid __ptrmap_update(struct ptrmap **mapp, void *key, void *val)
93f08c3bdfSopenharmony_ci{
94f08c3bdfSopenharmony_ci	struct ptrmap *map = *mapp;
95f08c3bdfSopenharmony_ci
96f08c3bdfSopenharmony_ci	for (; map; map = map->next) {
97f08c3bdfSopenharmony_ci		int i, n = map->nr;
98f08c3bdfSopenharmony_ci		for (i = 0; i < n; i++) {
99f08c3bdfSopenharmony_ci			struct ptrpair *pair = &map->pairs[i];
100f08c3bdfSopenharmony_ci			if (pair->key == key) {
101f08c3bdfSopenharmony_ci				if (pair->val != val)
102f08c3bdfSopenharmony_ci					pair->val = val;
103f08c3bdfSopenharmony_ci				return;
104f08c3bdfSopenharmony_ci			}
105f08c3bdfSopenharmony_ci		}
106f08c3bdfSopenharmony_ci	}
107f08c3bdfSopenharmony_ci
108f08c3bdfSopenharmony_ci	__ptrmap_add(mapp, key, val);
109f08c3bdfSopenharmony_ci}
110