Volksdata 1.0b7
RDF library
Loading...
Searching...
No Matches
namespace.c
Go to the documentation of this file.
2
3
6struct dump_iter_t {
7 size_t i; // Iterator counter.
8 const char *** data; // Stored data.
9};
10
11
12// TODO expose in API as first-class iterator function.
13static bool nsmap_dump_ns_iter_fn (const void *item, void *udata)
14{
15 const NSEntry *entry = item;
16 struct dump_iter_t *cur = udata;
17 //LOG_TRACE ("Dumping NS to string: %s %s", entry->pfx, entry->ns);
18
19 cur->data[cur->i][0] = (const char *)entry->pfx;
20 cur->data[cur->i++][1] = (const char *)entry->ns;
21
22 return true;
23}
24
25
29
30/*
31 * @note The internal functions to create and tear down this structure
32 * are in the environment module, while all functions for regular operations
33 * are in this module. This is because environment requires term, and term
34 * requires some namespace functions. This split is a bit awkward but it
35 * avoids circular dependencies; and anyways, nsm-related functions in the
36 * environment module are not exposed.
37 */
38struct hashmap *VOLK_default_nsm = NULL;
39
40
42VOLK_nsmap_add (const char *pfx, const char *nsstr)
43{
44 NSEntry entry_s = {};
45
46 if (strlen(pfx) >= PFX_LEN)
47 log_warn(
48 "Prefix `%s` is longer than the maximum allowed size "
49 "(%d characters). Truncating.", pfx, PFX_LEN - 1);
50 strncpy (entry_s.pfx, pfx, PFX_LEN -1);
51 entry_s.ns = strdup (nsstr);
52
53 const NSEntry *ret = hashmap_delete (VOLK_default_nsm, &entry_s);
54 if (!ret) LOG_DEBUG("Adding prefix '%s' to NS map.", entry_s.pfx);
55 else {
57 "Replacing NS '%s' with '%s' for prefix '%s'.",
58 ret->ns, entry_s.ns, entry_s.pfx);
59 // Free replaced NS string.
60 free (ret->ns);
61 }
62 hashmap_set (VOLK_default_nsm, &entry_s);
63 if (hashmap_oom (VOLK_default_nsm)) return VOLK_MEM_ERR;
64
65 return VOLK_OK;
66}
67
68
70VOLK_nsmap_remove (const char *pfx)
71{
72 NSEntry entry_s = {};
73 strncpy (entry_s.pfx, pfx, PFX_LEN - 1);
74 const NSEntry *entry = hashmap_delete (VOLK_default_nsm, &entry_s);
75
76 if (!entry) return VOLK_NOACTION;
77
78 free (entry->ns);
79
80 return VOLK_OK;
81}
82
83
84const char *
85VOLK_nsmap_get_ns (const char *pfx)
86{
87 NSEntry entry_s = {};
88 strncpy (entry_s.pfx, pfx, PFX_LEN - 1);
89 const NSEntry *entry = hashmap_get (VOLK_default_nsm, &entry_s);
90
91 return (entry) ? entry->ns : NULL;
92}
93
94
95const char *
96VOLK_nsmap_get_pfx (const char *ns)
97{
98 const NSEntry *entry;
99 size_t i = 0;
100 while (hashmap_iter (VOLK_default_nsm, &i, (void **) &entry)) {
101 if (strncmp (entry->ns, ns, strlen (ns)) == 0)
102 return entry->pfx;
103 }
104
105 return NULL;
106}
107
108
110VOLK_nsmap_normalize_uri (const char *pfx_uri, char **fq_uri_p)
111{
112 if (!pfx_uri) {
113 log_error ("Prefixed URI cannot be NULL.");
114 return VOLK_VALUE_ERR;
115 }
117 char *fq_uri = NULL;
118
119 size_t pfx_len = strcspn (pfx_uri, ":");
120 if (pfx_len >= PFX_LEN || pfx_len == strlen (pfx_uri)) {
121 log_warn (
122 "No prefix separator detected in URI `%s` within maximum "
123 "prefix length (%d characters).", pfx_uri, PFX_LEN - 1);
124 goto finally;
125 }
126
127 VOLK_ns_pfx pfx;
128 strncpy (pfx, pfx_uri, pfx_len);
129 pfx[pfx_len] = '\0';
130
131 const char *ns = VOLK_nsmap_get_ns (pfx);
132
133 if (ns) {
134 // -1 for :, +1 for terminator.
135 size_t fq_size = strlen (ns) + strlen (pfx_uri) - pfx_len;
136 fq_uri = malloc (fq_size);
137 if (UNLIKELY (! (fq_uri))) return VOLK_MEM_ERR;
138
139 strcpy (fq_uri, ns);
140 strcat (fq_uri, pfx_uri + pfx_len + 1);
141
142 rc = VOLK_OK;
143 } else log_warn ("No NS prefix found in map to normalize %s", pfx_uri);
144
145finally:
146 *fq_uri_p = fq_uri;
147
148 return rc;
149}
150
151
153VOLK_nsmap_denormalize_uri (const char *fq_uri, char **pfx_uri_p)
154{
155 /*
156 * This is different from VOLK_nsmap_get_ns, in that the URI being looked
157 * at will unlikely match exactly the full namespace stored in the map.
158 * This function has to count the characters left over from the match in
159 * order to add the URI suffix.
160 */
162 const NSEntry *entry;
163 const char *pfx = NULL;
164 char *pfx_uri = NULL;
165
166 size_t i = 0, offset;
167 while (hashmap_iter (VOLK_default_nsm, &i, (void **) &entry)) {
168 offset = strlen (entry->ns);
169 if (strncmp (entry->ns, fq_uri, offset) == 0) {
170 pfx = entry->pfx;
171 break;
172 }
173 }
174 if (pfx) {
175 // +2: one for terminating \x00, one for the colon.
176 pfx_uri = malloc (strlen (pfx) + strlen (fq_uri) - offset + 2);
177 if (UNLIKELY (! (pfx_uri))) return VOLK_MEM_ERR;
178
179 sprintf (pfx_uri, "%s:%s", pfx, fq_uri + offset);
180
181 rc = VOLK_OK;
182 } else log_warn ("No NS prefix found in map to denormalize %s", fq_uri);
183
184 *pfx_uri_p = pfx_uri;
185
186 return rc;
187}
188
189
190const char ***
192{
193 size_t i = hashmap_count (VOLK_default_nsm);
194
195 const char ***data = malloc (2 * (i + 1) * sizeof (char *));
196 if (UNLIKELY (!data)) return NULL;
197
198 for (size_t j = 0; j < i; j++) {
199 data[j] = malloc (2 * sizeof (char *));
200 if (UNLIKELY (!data[j])) return NULL;
201 }
202
203 struct dump_iter_t cur = {.i = 0, .data = data};
204 hashmap_scan (VOLK_default_nsm, nsmap_dump_ns_iter_fn, &cur);
205 data[i] = NULL; // Sentinel
206
207 return data;
208}
#define UNLIKELY(x)
Definition core.h:39
VOLK_rc VOLK_nsmap_remove(const char *pfx)
Remove a prefix -> namespace pair from a map.
Definition namespace.c:70
const char * VOLK_nsmap_get_pfx(const char *ns)
Get the prefix for a namespace.
Definition namespace.c:96
struct hashmap * VOLK_default_nsm
Default namespace prefix map.
Definition namespace.c:38
VOLK_rc VOLK_nsmap_normalize_uri(const char *pfx_uri, char **fq_uri_p)
Convert a namespace-prefixed string to a FQ URI sring if mapped.
Definition namespace.c:110
const char * VOLK_nsmap_get_ns(const char *pfx)
Get the namespace for a prefix.
Definition namespace.c:85
const char *** VOLK_nsmap_dump(void)
Dump all entries of the namespace map.
Definition namespace.c:191
VOLK_rc VOLK_nsmap_denormalize_uri(const char *fq_uri, char **pfx_uri_p)
Convert a FQ URI string to a prefixed string if the prefix is found.
Definition namespace.c:153
VOLK_rc VOLK_nsmap_add(const char *pfx, const char *nsstr)
Add a prefix -> namespace pair to the map or update it.
Definition namespace.c:42
char VOLK_ns_pfx[PFX_LEN]
Namespace prefix type.
Definition namespace.h:21
#define PFX_LEN
Namespace prefix length, including terminator.
Definition namespace.h:16
char * strdup(const char *src)
Replacement for GNU strdup.
Definition core.c:109
#define LOG_DEBUG(...)
Definition core.h:275
#define VOLK_VALUE_ERR
An invalid input value was provided.
Definition core.h:129
#define VOLK_MEM_ERR
Memory allocation error.
Definition core.h:144
#define VOLK_NORESULT
No result yielded.
Definition core.h:100
#define VOLK_OK
Generic success return code.
Definition core.h:83
#define VOLK_NOACTION
No action taken.
Definition core.h:93
int VOLK_rc
Definition core.h:79
Prefix / Namespace pair.
Definition namespace.h:26
char * ns
Definition namespace.h:28
VOLK_ns_pfx pfx
Definition namespace.h:27
Iterator for dumping NS map.
Definition namespace.c:6
const char *** data
Definition namespace.c:8
size_t i
Definition namespace.c:7