1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * raptor_feature.c - Parser and Serializer features
4  *
5  * Copyright (C) 2004-2008, David Beckett http://www.dajobe.org/
6  * Copyright (C) 2004-2005, University of Bristol, UK http://www.bristol.ac.uk/
7  *
8  * This package is Free Software and part of Redland http://librdf.org/
9  *
10  * It is licensed under the following three licenses as alternatives:
11  *   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12  *   2. GNU General Public License (GPL) V2 or any newer version
13  *   3. Apache License, V2.0 or any newer version
14  *
15  * You may not use this file except in compliance with at least one of
16  * the above three licenses.
17  *
18  * See LICENSE.html or LICENSE.txt at the top of this package for the
19  * complete terms and further detail along with the license texts for
20  * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
21  *
22  *
23  */
24 
25 
26 #ifdef HAVE_CONFIG_H
27 #include <raptor_config.h>
28 #endif
29 
30 #ifdef WIN32
31 #include <win32_raptor_config.h>
32 #endif
33 
34 
35 #include <stdio.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include <stdarg.h>
39 
40 /* Raptor includes */
41 #include "raptor.h"
42 #include "raptor_internal.h"
43 
44 
45 static const struct
46 {
47   raptor_feature feature;
48   /* flag bits
49    *  0: default is bool/int value
50    *
51    *  1=parser feature
52    *  2=serializer feature
53    *  4=string value (else bool/int)
54    *  8=xml writer feature
55    * 16=bool/int value is an integer
56    */
57   int flags;
58   const char *name;
59   const char *label;
60 } raptor_features_list[RAPTOR_FEATURE_LAST+1]= {
61   { RAPTOR_FEATURE_SCANNING                , 1, "scanForRDF", "Scan for rdf:RDF in XML content" },
62   { RAPTOR_FEATURE_ASSUME_IS_RDF           , 1, "assumeIsRDF", "Assume content is RDF/XML, don't require rdf:RDF" },
63   { RAPTOR_FEATURE_ALLOW_NON_NS_ATTRIBUTES , 1, "allowNonNsAttributes", "Allow bare 'name' rather than namespaced 'rdf:name'" },
64   { RAPTOR_FEATURE_ALLOW_OTHER_PARSETYPES  , 1, "allowOtherParsetypes", "Allow user-defined rdf:parseType values" },
65   { RAPTOR_FEATURE_ALLOW_BAGID             , 1, "allowBagID", "Allow rdf:bagID" },
66   { RAPTOR_FEATURE_ALLOW_RDF_TYPE_RDF_LIST , 1, "allowRDFtypeRDFlist", "Generate the collection rdf:type rdf:List triple" },
67   { RAPTOR_FEATURE_NORMALIZE_LANGUAGE      , 1, "normalizeLanguage", "Normalize xml:lang values to lowercase" },
68   { RAPTOR_FEATURE_NON_NFC_FATAL           , 1, "nonNFCfatal", "Make non-NFC literals cause a fatal error" },
69   { RAPTOR_FEATURE_WARN_OTHER_PARSETYPES   , 1, "warnOtherParseTypes", "Warn about unknown rdf:parseType values" },
70   { RAPTOR_FEATURE_CHECK_RDF_ID            , 1, "checkRdfID", "Check rdf:ID values for duplicates" },
71   { RAPTOR_FEATURE_RELATIVE_URIS           , 2, "relativeURIs", "Write relative URIs wherever possible in serializing." },
72   { RAPTOR_FEATURE_START_URI               , 6, "startURI", "Start URI for serializing to use." },
73   { RAPTOR_FEATURE_WRITER_AUTO_INDENT      , 8, "autoIndent", "Automatically indent elements." },
74   { RAPTOR_FEATURE_WRITER_AUTO_EMPTY       , 8, "autoEmpty", "Automatically detect and abbreviate empty elements." },
75   { RAPTOR_FEATURE_WRITER_INDENT_WIDTH     , 8, "indentWidth", "Number of spaces to indent." },
76   { RAPTOR_FEATURE_WRITER_XML_VERSION      , 10, "xmlVersion", "XML version to write." },
77   { RAPTOR_FEATURE_WRITER_XML_DECLARATION  , 10, "xmlDeclaration", "Write XML declaration." },
78   { RAPTOR_FEATURE_NO_NET                  , 1,  "noNet", "Deny network requests." },
79   { RAPTOR_FEATURE_RESOURCE_BORDER   , 6,  "resourceBorder", "DOT serializer resource border color" },
80   { RAPTOR_FEATURE_LITERAL_BORDER    , 6,  "literalBorder", "DOT serializer literal border color" },
81   { RAPTOR_FEATURE_BNODE_BORDER      , 6,  "bnodeBorder", "DOT serializer blank node border color" },
82   { RAPTOR_FEATURE_RESOURCE_FILL     , 6,  "resourceFill", "DOT serializer resource fill color" },
83   { RAPTOR_FEATURE_LITERAL_FILL      , 6,  "literalFill", "DOT serializer literal fill color" },
84   { RAPTOR_FEATURE_BNODE_FILL        , 6,  "bnodeFill", "DOT serializer blank node fill color" },
85   { RAPTOR_FEATURE_HTML_TAG_SOUP     , 1,  "htmlTagSoup", "HTML parsing uses a lax HTML parser" },
86   { RAPTOR_FEATURE_MICROFORMATS      , 1,  "microformats", "GRDDL parsing looks for microformats" },
87   { RAPTOR_FEATURE_HTML_LINK         , 1,  "htmlLink", "GRDDL parsing looks for <link type=\"application/rdf+xml\">" },
88   { RAPTOR_FEATURE_WWW_TIMEOUT       , 1+16,  "wwwTimeout", "Set internal WWW URI retrieval timeout" },
89   { RAPTOR_FEATURE_WRITE_BASE_URI    , 2,  "writeBaseURI", "Write @base / xml:base directive in serializer output" },
90   { RAPTOR_FEATURE_WWW_HTTP_CACHE_CONTROL, 5, "wwwHttpCacheControl", "Set HTTP Cache-Control: header value" },
91   { RAPTOR_FEATURE_WWW_HTTP_USER_AGENT , 5,  "wwwHttpUserAgent", "Set HTTP User-Agent: header value" },
92   { RAPTOR_FEATURE_JSON_CALLBACK     , 6,  "jsonCallback", "JSON serializer callback" },
93   { RAPTOR_FEATURE_JSON_EXTRA_DATA   , 6,  "jsonExtraData", "JSON serializer extra data" },
94   { RAPTOR_FEATURE_RSS_TRIPLES       , 6,  "rssTriples", "Atom/RSS serializer writes extra RDF triples" },
95   { RAPTOR_FEATURE_ATOM_ENTRY_URI    , 6,  "atomEntryUri", "Atom serializer Entry URI" },
96   { RAPTOR_FEATURE_PREFIX_ELEMENTS   , 2,  "prefixElements", "Atom/RSS serializers write namespace-prefixed elements" },
97   { RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES, 1, "loadExternalEntities", "Load external XML entities." }
98 };
99 
100 
101 static const char * const raptor_feature_uri_prefix="http://feature.librdf.org/raptor-";
102 /* NOTE: this is strlen(raptor_feature_uri_prefix) */
103 #define RAPTOR_FEATURE_URI_PREFIX_LEN 33
104 
105 
106 /*
107  * raptor_features_enumerate_common:
108  * @world: raptor_world object
109  * @feature: feature enumeration (0+)
110  * @name: pointer to store feature short name (or NULL)
111  * @uri: pointer to store feature URI (or NULL)
112  * @label: pointer to feature label (or NULL)
113  * @flags: flags to match
114  *
115  * Internal: Get list of syntax features.
116  *
117  * If @uri is not NULL, a pointer toa new raptor_uri is returned
118  * that must be freed by the caller with raptor_free_uri().
119  *
120  * Return value: 0 on success, <0 on failure, >0 if feature is unknown
121  **/
122 int
raptor_features_enumerate_common(raptor_world * world,const raptor_feature feature,const char ** name,raptor_uri ** uri,const char ** label,int flags)123 raptor_features_enumerate_common(raptor_world* world,
124                                  const raptor_feature feature,
125                                  const char **name,
126                                  raptor_uri **uri, const char **label,
127                                  int flags)
128 {
129   int i;
130 
131   for(i=0; i <= RAPTOR_FEATURE_LAST; i++)
132     if(raptor_features_list[i].feature == feature &&
133        (raptor_features_list[i].flags & flags)) {
134       if(name)
135         *name=raptor_features_list[i].name;
136 
137       if(uri) {
138         raptor_uri *base_uri=raptor_new_uri_v2(world, (const unsigned char*)raptor_feature_uri_prefix);
139         if(!base_uri)
140           return -1;
141 
142         *uri=raptor_new_uri_from_uri_local_name_v2(world,
143                                                    base_uri,
144                                                    (const unsigned char*)raptor_features_list[i].name);
145         raptor_free_uri_v2(world, base_uri);
146       }
147       if(label)
148         *label=raptor_features_list[i].label;
149       return 0;
150     }
151 
152   return 1;
153 }
154 
155 
156 
157 /**
158  * raptor_feature_value_type
159  * @feature: raptor serializer or parser feature
160  *
161  * Get the type of a features.
162  *
163  * The type of the @feature is 0=integer , 1=string.  Other values are
164  * undefined.  Most features are integer values and use
165  * raptor_set_feature and raptor_get_feature()
166  * ( raptor_serializer_set_feature raptor_serializer_get_feature() )
167  *
168  * String value features use raptor_parser_set_feature_string() and
169  * raptor_parser_get_feature_string()
170  * ( raptor_serializer_set_feature_string()
171  * and raptor_serializer_get_feature_string() )
172  *
173  * Return value: the type of the feature or <0 if @feature is unknown
174  */
175 int
raptor_feature_value_type(const raptor_feature feature)176 raptor_feature_value_type(const raptor_feature feature) {
177   if(feature > RAPTOR_FEATURE_LAST)
178     return -1;
179   return (raptor_features_list[feature].flags & 4) ? 1 : 0;
180 }
181 
182 
183 #ifndef RAPTOR_DISABLE_V1
184 /**
185  * raptor_feature_from_uri:
186  * @uri: feature URI
187  *
188  * Turn a feature URI into an feature enum.
189  *
190  * The allowed feature URIs are available via raptor_features_enumerate().
191  *
192  * raptor_init() MUST have been called before calling this function.
193  * Use raptor_feature_from_uri_v2() if using raptor_world APIs.
194  *
195  * Return value: < 0 if the feature is unknown
196  **/
197 raptor_feature
raptor_feature_from_uri(raptor_uri * uri)198 raptor_feature_from_uri(raptor_uri *uri)
199 {
200   return raptor_feature_from_uri_v2(raptor_world_instance(), uri);
201 }
202 #endif
203 
204 
205 /**
206  * raptor_feature_from_uri_v2:
207  * @world: raptor_world instance
208  * @uri: feature URI
209  *
210  * Turn a feature URI into an feature enum.
211  *
212  * The allowed feature URIs are available via raptor_features_enumerate().
213  *
214  * Return value: < 0 if the feature is unknown
215  **/
216 raptor_feature
raptor_feature_from_uri_v2(raptor_world * world,raptor_uri * uri)217 raptor_feature_from_uri_v2(raptor_world* world, raptor_uri *uri)
218 {
219   unsigned char *uri_string;
220   int i;
221   raptor_feature feature= (raptor_feature)-1;
222 
223   if(!uri)
224     return feature;
225 
226   uri_string=raptor_uri_as_string_v2(world, uri);
227   if(strncmp((const char*)uri_string, raptor_feature_uri_prefix,
228              RAPTOR_FEATURE_URI_PREFIX_LEN))
229     return feature;
230 
231   uri_string += RAPTOR_FEATURE_URI_PREFIX_LEN;
232 
233   for(i=0; i <= RAPTOR_FEATURE_LAST; i++)
234     if(!strcmp(raptor_features_list[i].name, (const char*)uri_string)) {
235       feature=(raptor_feature)i;
236       break;
237     }
238 
239   return feature;
240 }
241 
242 
243 /**
244  * raptor_get_feature_count:
245  *
246  * Get the count of features defined.
247  *
248  * This is prefered to the compile time-only symbol #RAPTOR_FEATURE_LAST
249  * and returns a count of the number of features which is
250  * #RAPTOR_FEATURE_LAST+1.
251  *
252  * Return value: count of features in the #raptor_feature enumeration
253  **/
254 unsigned int
raptor_get_feature_count(void)255 raptor_get_feature_count(void) {
256   return RAPTOR_FEATURE_LAST+1;
257 }
258 
259