1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * rasqal_feature.c - Query system features
4 *
5 * Copyright (C) 2006-2009, David Beckett http://www.dajobe.org/
6 *
7 * This package is Free Software and part of Redland http://librdf.org/
8 *
9 * It is licensed under the following three licenses as alternatives:
10 * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
11 * 2. GNU General Public License (GPL) V2 or any newer version
12 * 3. Apache License, V2.0 or any newer version
13 *
14 * You may not use this file except in compliance with at least one of
15 * the above three licenses.
16 *
17 * See LICENSE.html or LICENSE.txt at the top of this package for the
18 * complete terms and further detail along with the license texts for
19 * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
20 *
21 *
22 */
23
24
25 #ifdef HAVE_CONFIG_H
26 #include <rasqal_config.h>
27 #endif
28
29 #ifdef WIN32
30 #include <win32_rasqal_config.h>
31 #endif
32
33
34 #include <stdio.h>
35 #include <string.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39 #include <ctype.h>
40 #include <stdarg.h>
41
42 /* Rasqal includes */
43 #include "rasqal.h"
44 #include "rasqal_internal.h"
45
46
47 static const struct
48 {
49 rasqal_feature feature;
50 /* flag bits
51 * 1=query feature
52 * 2=unused
53 * 4=string value (else int)
54 */
55 int flags;
56 const char *name;
57 const char *label;
58 } rasqal_features_list [RASQAL_FEATURE_LAST + 1]= {
59 { RASQAL_FEATURE_NO_NET, 1, "noNet", "Deny network requests." } ,
60 { RASQAL_FEATURE_RAND_SEED, 1, "randSeed", "Set rand() seed." }
61 };
62
63
64 static const char * const rasqal_feature_uri_prefix="http://feature.librdf.org/rasqal-";
65 /* NOTE: this is strlen(rasqal_feature_uri_prefix) */
66 #define RASQAL_FEATURE_URI_PREFIX_LEN 33
67
68
69 /*
70 * rasqal_features_enumerate_common:
71 * @world: rasqal_world object
72 * @feature: feature enumeration (0+)
73 * @name: pointer to store feature short name (or NULL)
74 * @uri: pointer to store feature URI (or NULL)
75 * @label: pointer to feature label (or NULL)
76 * @flags: flags to match
77 *
78 * Internal: Get list of rasqal features.
79 *
80 * If @uri is not NULL, a pointer to a new raptor_uri is returned
81 * that must be freed by the caller with raptor_free_uri().
82 *
83 * Return value: 0 on success, <0 on failure, >0 if feature is unknown
84 **/
85 static int
rasqal_features_enumerate_common(rasqal_world * world,const rasqal_feature feature,const char ** name,raptor_uri ** uri,const char ** label,int flags)86 rasqal_features_enumerate_common(rasqal_world* world,
87 const rasqal_feature feature,
88 const char **name,
89 raptor_uri **uri, const char **label,
90 int flags)
91 {
92 int i;
93
94 /* for compatibility with older binaries that do not call it */
95 rasqal_world_open(world);
96
97 for(i=0; i <= RASQAL_FEATURE_LAST; i++)
98 if(rasqal_features_list[i].feature == feature &&
99 (rasqal_features_list[i].flags & flags)) {
100 if(name)
101 *name=rasqal_features_list[i].name;
102
103 if(uri) {
104 raptor_uri *base_uri;
105 base_uri = raptor_new_uri(world->raptor_world_ptr,
106 RASQAL_GOOD_CAST(const unsigned char*, rasqal_feature_uri_prefix));
107 if(!base_uri)
108 return -1;
109 *uri = raptor_new_uri_from_uri_local_name(world->raptor_world_ptr, base_uri,
110 RASQAL_GOOD_CAST(const unsigned char*, rasqal_features_list[i].name));
111 raptor_free_uri(base_uri);
112 }
113 if(label)
114 *label=rasqal_features_list[i].label;
115 return 0;
116 }
117
118 return 1;
119 }
120
121
122 /**
123 * rasqal_features_enumerate:
124 * @world: rasqal_world object
125 * @feature: feature enumeration (0+)
126 * @name: pointer to store feature short name (or NULL)
127 * @uri: pointer to store feature URI (or NULL)
128 * @label: pointer to feature label (or NULL)
129 *
130 * Get list of rasqal features.
131 *
132 * If uri is not NULL, a pointer to a new raptor_uri is returned
133 * that must be freed by the caller with raptor_free_uri().
134 *
135 * Return value: 0 on success, <0 on failure, >0 if feature is unknown
136 **/
137 int
rasqal_features_enumerate(rasqal_world * world,const rasqal_feature feature,const char ** name,raptor_uri ** uri,const char ** label)138 rasqal_features_enumerate(rasqal_world* world,
139 const rasqal_feature feature,
140 const char **name,
141 raptor_uri **uri, const char **label)
142 {
143 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, -1);
144
145 return rasqal_features_enumerate_common(world, feature, name, uri, label, 1);
146 }
147
148
149 /**
150 * rasqal_feature_value_type
151 * @feature: rasqal query feature
152 *
153 * Get the type of a features.
154 *
155 * The type of the @feature is 0=integer , 1=string. Other values are
156 * undefined. Most features are integer values and use
157 * rasqal_query_set_feature rasqal_query_get_feature()
158 *
159 * Return value: the type of the feature or <0 if @feature is unknown
160 */
161 int
rasqal_feature_value_type(const rasqal_feature feature)162 rasqal_feature_value_type(const rasqal_feature feature) {
163 if(feature > RASQAL_FEATURE_LAST)
164 return -1;
165 return (rasqal_features_list[feature].flags & 4) ? 1 : 0;
166 }
167
168
169 /**
170 * rasqal_feature_from_uri:
171 * @world: rasqal_world object
172 * @uri: feature URI
173 *
174 * Turn a feature URI into an feature enum.
175 *
176 * The allowed feature URIs are available via rasqal_features_enumerate().
177 *
178 * Return value: < 0 if the feature is unknown
179 **/
180 rasqal_feature
rasqal_feature_from_uri(rasqal_world * world,raptor_uri * uri)181 rasqal_feature_from_uri(rasqal_world* world, raptor_uri *uri)
182 {
183 unsigned char *uri_string;
184 int i;
185 rasqal_feature feature = (rasqal_feature)-1;
186
187 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, feature);
188 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(uri, rasqal_world, feature);
189
190 /* for compatibility with older binaries that do not call it */
191 rasqal_world_open(world);
192
193 uri_string = raptor_uri_as_string(uri);
194 if(strncmp(RASQAL_GOOD_CAST(const char*, uri_string),
195 rasqal_feature_uri_prefix,
196 RASQAL_FEATURE_URI_PREFIX_LEN))
197 return feature;
198
199 uri_string += RASQAL_FEATURE_URI_PREFIX_LEN;
200
201 for(i = 0; i <= RASQAL_FEATURE_LAST; i++)
202 if(!strcmp(rasqal_features_list[i].name,
203 RASQAL_GOOD_CAST(const char*, uri_string))) {
204 feature = (rasqal_feature)i;
205 break;
206 }
207
208 return feature;
209 }
210
211
212 /**
213 * rasqal_get_feature_count:
214 *
215 * Get the count of features defined.
216 *
217 * This is prefered to the compile time-only symbol #RASQAL_FEATURE_LAST
218 * and returns a count of the number of features which is
219 * #RASQAL_FEATURE_LAST+1.
220 *
221 * Return value: count of features in the #rasqal_feature enumeration
222 **/
223 unsigned int
rasqal_get_feature_count(void)224 rasqal_get_feature_count(void) {
225 return RASQAL_FEATURE_LAST+1;
226 }
227