1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * rasqal_data_graph.c - Rasqal data graph class
4  *
5  * Copyright (C) 2010, 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 #ifdef HAVE_CONFIG_H
25 #include <rasqal_config.h>
26 #endif
27 
28 #ifdef WIN32
29 #include <win32_rasqal_config.h>
30 #endif
31 
32 #include <stdio.h>
33 #include <string.h>
34 #include <ctype.h>
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38 #include <stdarg.h>
39 
40 #include "rasqal.h"
41 #include "rasqal_internal.h"
42 
43 
44 static rasqal_data_graph*
rasqal_new_data_graph_common(rasqal_world * world,raptor_uri * uri,raptor_iostream * iostr,raptor_uri * base_uri,raptor_uri * name_uri,unsigned int flags,const char * format_type,const char * format_name,raptor_uri * format_uri)45 rasqal_new_data_graph_common(rasqal_world* world,
46                              raptor_uri* uri,
47                              raptor_iostream* iostr, raptor_uri* base_uri,
48                              raptor_uri* name_uri,
49                              unsigned int flags,
50                              const char* format_type,
51                              const char* format_name,
52                              raptor_uri* format_uri)
53 {
54   rasqal_data_graph* dg;
55 
56   dg = RASQAL_CALLOC(rasqal_data_graph*, 1, sizeof(*dg));
57   if(dg) {
58     dg->world = world;
59 
60     dg->usage = 1;
61 
62     if(iostr)
63       dg->iostr = iostr;
64     else if(uri)
65       dg->uri = raptor_uri_copy(uri);
66 
67     if(name_uri)
68       dg->name_uri = raptor_uri_copy(name_uri);
69 
70     dg->flags = flags;
71 
72     if(format_type) {
73       size_t len = strlen(format_type);
74       dg->format_type = RASQAL_MALLOC(char*, len + 1);
75       if(!dg->format_type)
76         goto error;
77 
78       memcpy(dg->format_type, format_type, len + 1);
79     }
80 
81     if(format_name) {
82       size_t len = strlen(format_name);
83       dg->format_name = RASQAL_MALLOC(char*, len + 1);
84       if(!dg->format_name)
85         goto error;
86 
87       memcpy(dg->format_name, format_name, len + 1);
88     }
89 
90     if(format_uri)
91       dg->format_uri = raptor_uri_copy(format_uri);
92 
93     if(base_uri)
94       dg->base_uri = raptor_uri_copy(base_uri);
95   }
96 
97   return dg;
98 
99   error:
100   rasqal_free_data_graph(dg);
101   return NULL;
102 }
103 
104 
105 /**
106  * rasqal_new_data_graph_from_uri:
107  * @world: rasqal_world object
108  * @uri: source URI
109  * @name_uri: name of graph (or NULL)
110  * @flags: %RASQAL_DATA_GRAPH_NAMED or %RASQAL_DATA_GRAPH_BACKGROUND
111  * @format_type: MIME Type of data format at @uri (or NULL)
112  * @format_name: Raptor parser Name of data format at @uri (or NULL)
113  * @format_uri: URI of data format at @uri (or NULL)
114  *
115  * Constructor - create a new #rasqal_data_graph.
116  *
117  * The name_uri is only used when the flags are %RASQAL_DATA_GRAPH_NAMED.
118  *
119  * Return value: a new #rasqal_data_graph or NULL on failure.
120  **/
121 rasqal_data_graph*
rasqal_new_data_graph_from_uri(rasqal_world * world,raptor_uri * uri,raptor_uri * name_uri,unsigned int flags,const char * format_type,const char * format_name,raptor_uri * format_uri)122 rasqal_new_data_graph_from_uri(rasqal_world* world, raptor_uri* uri,
123                                raptor_uri* name_uri, unsigned int flags,
124                                const char* format_type,
125                                const char* format_name,
126                                raptor_uri* format_uri)
127 {
128   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
129   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(uri, raptor_uri, NULL);
130 
131   return rasqal_new_data_graph_common(world,
132                                       uri,
133                                       /* iostr */ NULL, /* base URI */ NULL,
134                                       name_uri, flags,
135                                       format_type, format_name, format_uri);
136 }
137 
138 
139 /**
140  * rasqal_new_data_graph_from_iostream:
141  * @world: rasqal_world object
142  * @iostr: source graph format iostream
143  * @base_uri: base URI for iostream content
144  * @name_uri: name of graph (or NULL)
145  * @flags: %RASQAL_DATA_GRAPH_NAMED or %RASQAL_DATA_GRAPH_BACKGROUND
146  * @format_type: MIME Type of data format at @uri (or NULL)
147  * @format_name: Raptor parser Name of data format at @uri (or NULL)
148  * @format_uri: URI of data format at @uri (or NULL)
149  *
150  * Constructor - create a new #rasqal_data_graph from iostream content
151  *
152  * The @name_uri is used when the flags are %RASQAL_DATA_GRAPH_NAMED.
153  *
154  * The @base_uri is used to provide the Raptor parser a base URI.  If
155  * a base URI is required but none is given, the parsing will fail
156  * and the query that uses this data source will fail.
157  *
158  * Return value: a new #rasqal_data_graph or NULL on failure.
159  **/
160 rasqal_data_graph*
rasqal_new_data_graph_from_iostream(rasqal_world * world,raptor_iostream * iostr,raptor_uri * base_uri,raptor_uri * name_uri,unsigned int flags,const char * format_type,const char * format_name,raptor_uri * format_uri)161 rasqal_new_data_graph_from_iostream(rasqal_world* world,
162                                     raptor_iostream* iostr,
163                                     raptor_uri* base_uri,
164                                     raptor_uri* name_uri,
165                                     unsigned int flags,
166                                     const char* format_type,
167                                     const char* format_name,
168                                     raptor_uri* format_uri)
169 {
170   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
171 
172   return rasqal_new_data_graph_common(world,
173                                       /* uri */ NULL,
174                                       iostr, base_uri,
175                                       name_uri, flags,
176                                       format_type, format_name, format_uri);
177 }
178 
179 
180 /**
181  * rasqal_new_data_graph_from_data_graph:
182  * @dg: #rasqal_data_graph object to copy or NULL
183  *
184  * Copy Constructor - create a new #rasqal_data_graph object from an existing #rasqal_data_graph object.
185  *
186  * Return value: a new #rasqal_data_graph object or NULL if @dg was NULL.
187  **/
188 rasqal_data_graph*
rasqal_new_data_graph_from_data_graph(rasqal_data_graph * dg)189 rasqal_new_data_graph_from_data_graph(rasqal_data_graph* dg)
190 {
191   dg->usage++;
192 
193   return dg;
194 }
195 
196 
197 /**
198  * rasqal_free_data_graph:
199  * @dg: #rasqal_data_graph object
200  *
201  * Destructor - destroy a #rasqal_data_graph object.
202  *
203  **/
204 void
rasqal_free_data_graph(rasqal_data_graph * dg)205 rasqal_free_data_graph(rasqal_data_graph* dg)
206 {
207   if(!dg)
208     return;
209 
210   if(--dg->usage)
211     return;
212 
213   if(dg->uri)
214     raptor_free_uri(dg->uri);
215   if(dg->name_uri)
216     raptor_free_uri(dg->name_uri);
217   if(dg->format_type)
218     RASQAL_FREE(char*, dg->format_type);
219   if(dg->format_name)
220     RASQAL_FREE(char*, dg->format_name);
221   if(dg->format_uri)
222     raptor_free_uri(dg->format_uri);
223   if(dg->base_uri)
224     raptor_free_uri(dg->base_uri);
225 
226   RASQAL_FREE(rasqal_data_graph, dg);
227 }
228 
229 
230 /**
231  * rasqal_data_graph_print:
232  * @dg: #rasqal_data_graph object
233  * @fh: the FILE* handle to print to
234  *
235  * Print a Rasqal data graph in a debug format.
236  *
237  * The print debug format may change in any release.
238  *
239  * Return value: non-0 on failure
240  **/
241 int
rasqal_data_graph_print(rasqal_data_graph * dg,FILE * fh)242 rasqal_data_graph_print(rasqal_data_graph* dg, FILE* fh)
243 {
244   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(dg, rasqal_data_graph, 1);
245   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(fh, FILE*, 1);
246 
247   if(dg->iostr) {
248     if(dg->name_uri)
249       fprintf(fh, "data graph(from iostream, named as %s, flags %u",
250               raptor_uri_as_string(dg->name_uri), dg->flags);
251     else
252       fprintf(fh, "data graph(from iostream, %u", dg->flags);
253   } else {
254     /* dg->uri must exist */
255     if(dg->name_uri)
256       fprintf(fh, "data graph(from uri %s, named as %s, flags %u",
257               raptor_uri_as_string(dg->uri),
258               raptor_uri_as_string(dg->name_uri),
259               dg->flags);
260     else
261       fprintf(fh, "data graph(from uri %s, flags %u",
262               raptor_uri_as_string(dg->uri), dg->flags);
263   }
264 
265   if(dg->format_type || dg->format_name || dg->format_uri) {
266     fputs(" with format ", fh);
267     if(dg->format_type)
268       fprintf(fh, "type %s", dg->format_type);
269     if(dg->format_name)
270       fprintf(fh, "name %s", dg->format_name);
271     if(dg->format_uri)
272       fprintf(fh, "uri %s", raptor_uri_as_string(dg->format_uri));
273     if(dg->base_uri)
274       fprintf(fh, "base uri %s", raptor_uri_as_string(dg->base_uri));
275   }
276   fputc(')', fh);
277 
278   return 0;
279 }
280