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