1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * raptor_statement.c - Raptor statements
4 *
5 * Copyright (C) 2008, 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 #ifdef HAVE_CONFIG_H
24 #include <raptor_config.h>
25 #endif
26
27 #ifdef WIN32
28 #include <win32_raptor_config.h>
29 #endif
30
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <stdarg.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39
40 /* Raptor includes */
41 #include "raptor.h"
42 #include "raptor_internal.h"
43
44
45 /* prototypes for helper functions */
46 static void raptor_print_statement_part_as_ntriples(raptor_world* world, FILE* stream, const void *term, raptor_identifier_type type, raptor_uri* literal_datatype, const unsigned char *literal_language);
47 static void raptor_print_statement_as_ntriples_common(raptor_world* world, const raptor_statement *statement, FILE *stream);
48 static int raptor_statement_compare_common(raptor_world* world, const raptor_statement *s1, const raptor_statement *s2);
49
50
51 /**
52 * raptor_statement_copy_v2:
53 * @statement: statement to copy
54 *
55 * Copy a #raptor_statement.
56 *
57 * Return value: a new #raptor_statement_v2 or NULL on error
58 */
59 raptor_statement_v2*
raptor_statement_copy_v2(const raptor_statement_v2 * statement)60 raptor_statement_copy_v2(const raptor_statement_v2 *statement)
61 {
62 return raptor_statement_copy_v2_from_v1(statement->world, statement->s);
63 }
64
65
66 /**
67 * raptor_statement_copy_v2_from_v1:
68 * @world: raptor_world object
69 * @statement: statement to copy
70 *
71 * Copy a #raptor_statement and wrap it in #raptor_statement_v2.
72 *
73 * Return value: a new #raptor_statement_v2 or NULL on error
74 */
75 raptor_statement_v2*
raptor_statement_copy_v2_from_v1(raptor_world * world,const raptor_statement * statement)76 raptor_statement_copy_v2_from_v1(raptor_world* world, const raptor_statement *statement)
77 {
78 raptor_statement_v2 *s;
79
80 s=(raptor_statement_v2*)RAPTOR_CALLOC(raptor_statement_v2, 1, sizeof(raptor_statement_v2));
81 if(!s)
82 return NULL;
83
84 s->world=world;
85 s->s=raptor_statement_copy(world, statement);
86 if(!s->s) {
87 raptor_free_statement_v2(s);
88 s=NULL;
89 }
90
91 return s;
92 }
93
94
95 /**
96 * raptor_statement_copy:
97 * @world: raptor_world object
98 * @statement: statement to copy
99 *
100 * Copy a #raptor_statement.
101 *
102 * Return value: a new #raptor_statement or NULL on error
103 */
104 raptor_statement*
raptor_statement_copy(raptor_world * world,const raptor_statement * statement)105 raptor_statement_copy(raptor_world* world, const raptor_statement *statement)
106 {
107 raptor_statement *s;
108
109 s=(raptor_statement*)RAPTOR_CALLOC(raptor_statement, 1, sizeof(raptor_statement));
110 if(!s)
111 return NULL;
112
113 s->subject_type=statement->subject_type;
114 if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) {
115 unsigned char *new_blank=(unsigned char*)RAPTOR_MALLOC(cstring, strlen((char*)statement->subject)+1);
116 if(!new_blank)
117 goto oom;
118 strcpy((char*)new_blank, (const char*)statement->subject);
119 s->subject=new_blank;
120 } else if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) {
121 s->subject=raptor_new_uri_from_rdf_ordinal(world, *((int*)statement->subject));
122 s->subject_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE;
123 } else
124 s->subject=raptor_uri_copy_v2(world, (raptor_uri*)statement->subject);
125
126 s->predicate_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE;
127 if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL)
128 s->predicate=raptor_new_uri_from_rdf_ordinal(world, *((int*)statement->predicate));
129 else
130 s->predicate=raptor_uri_copy_v2(world, (raptor_uri*)statement->predicate);
131
132
133 s->object_type=statement->object_type;
134 if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL ||
135 statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) {
136 unsigned char *string;
137 char *language=NULL;
138 raptor_uri *uri=NULL;
139
140 string=(unsigned char*)RAPTOR_MALLOC(cstring, strlen((char*)statement->object)+1);
141 if(!string)
142 goto oom;
143 strcpy((char*)string, (const char*)statement->object);
144 s->object=string;
145
146 if(statement->object_literal_language) {
147 language=(char*)RAPTOR_MALLOC(cstring, strlen((const char*)statement->object_literal_language)+1);
148 if(!language)
149 goto oom;
150 strcpy(language, (const char*)statement->object_literal_language);
151 s->object_literal_language=(const unsigned char*)language;
152 }
153
154 if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) {
155 /* nop */
156 } else if(statement->object_literal_datatype) {
157 uri=raptor_uri_copy_v2(world, (raptor_uri*)statement->object_literal_datatype);
158 s->object_literal_datatype=uri;
159 }
160 } else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) {
161 char *blank=(char*)statement->object;
162 unsigned char *new_blank=(unsigned char*)RAPTOR_MALLOC(cstring, strlen(blank)+1);
163 if(!new_blank)
164 goto oom;
165 strcpy((char*)new_blank, (const char*)blank);
166 s->object=new_blank;
167 } else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) {
168 s->object=raptor_new_uri_from_rdf_ordinal(world, *((int*)statement->object));
169 s->object_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE;
170 } else {
171 raptor_uri *uri=raptor_uri_copy_v2(world, (raptor_uri*)statement->object);
172 s->object=uri;
173 }
174
175 return s;
176
177 oom:
178 raptor_free_statement(world, s);
179 return NULL;
180 }
181
182
183 /**
184 * raptor_free_statement_v2:
185 * @statement: statement
186 *
187 * Destructor
188 *
189 */
190 void
raptor_free_statement_v2(raptor_statement_v2 * statement)191 raptor_free_statement_v2(raptor_statement_v2 *statement)
192 {
193 RAPTOR_ASSERT_OBJECT_POINTER_RETURN(statement, raptor_statement);
194 raptor_free_statement(statement->world, statement->s);
195 RAPTOR_FREE(raptor_statement_v2, statement);
196 }
197
198
199 /**
200 * raptor_free_statement:
201 * @statement: statement
202 *
203 * Destructor
204 *
205 */
206 void
raptor_free_statement(raptor_world * world,raptor_statement * statement)207 raptor_free_statement(raptor_world *world, raptor_statement *statement)
208 {
209 if(statement->subject) {
210 if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE)
211 raptor_free_uri_v2(world, (raptor_uri*)statement->subject);
212 else
213 RAPTOR_FREE(cstring, (void*)statement->subject);
214 }
215
216 if(statement->predicate) {
217 if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_PREDICATE ||
218 statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE)
219 raptor_free_uri_v2(world, (raptor_uri*)statement->predicate);
220 else
221 RAPTOR_FREE(cstring, (void*)statement->predicate);
222 }
223
224 if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE) {
225 if(statement->object)
226 raptor_free_uri_v2(world, (raptor_uri*)statement->object);
227 } else {
228 if(statement->object)
229 RAPTOR_FREE(cstring, (void*)statement->object);
230
231 if(statement->object_literal_language)
232 RAPTOR_FREE(cstring, (void*)statement->object_literal_language);
233 if(statement->object_literal_datatype)
234 raptor_free_uri_v2(world, (raptor_uri*)statement->object_literal_datatype);
235 }
236
237 RAPTOR_FREE(raptor_statement, statement);
238 }
239
240
241 #ifndef RAPTOR_DISABLE_V1
242 /**
243 * raptor_print_statement:
244 * @statement: #raptor_statement object to print
245 * @stream: #FILE* stream
246 *
247 * Print a raptor_statement to a stream.
248 *
249 * raptor_init() MUST have been called before calling this function.
250 * Use raptor_print_statement_v2() if using raptor_world APIs.
251 **/
252 void
raptor_print_statement(const raptor_statement * statement,FILE * stream)253 raptor_print_statement(const raptor_statement * statement, FILE *stream)
254 {
255 raptor_print_statement_v1(raptor_world_instance(), statement, stream);
256 }
257 #endif
258
259
260 /**
261 * raptor_print_statement_v2:
262 * @statement: #raptor_statement_v2 object to print
263 * @stream: #FILE* stream
264 *
265 * Print a raptor_statement to a stream.
266 **/
267 void
raptor_print_statement_v2(const raptor_statement_v2 * statement,FILE * stream)268 raptor_print_statement_v2(const raptor_statement_v2 * statement, FILE *stream)
269 {
270 raptor_print_statement_v1(statement->world, statement->s, stream);
271 }
272
273
274 /**
275 * raptor_print_statement_v1:
276 * @world: raptor_world object
277 * @statement: #raptor_statement object to print
278 * @stream: #FILE* stream
279 *
280 * Print a raptor_statement to a stream.
281 **/
282 void
raptor_print_statement_v1(raptor_world * world,const raptor_statement * statement,FILE * stream)283 raptor_print_statement_v1(raptor_world* world, const raptor_statement * statement, FILE *stream)
284 {
285 fputc('[', stream);
286
287 if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) {
288 fputs((const char*)statement->subject, stream);
289 } else {
290 #ifdef RAPTOR_DEBUG
291 if(!statement->subject)
292 RAPTOR_FATAL1("Statement has NULL subject URI\n");
293 #endif
294 fputs((const char*)raptor_uri_as_string_v2(world, (raptor_uri*)statement->subject), stream);
295 }
296
297 fputs(", ", stream);
298
299 if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL)
300 fprintf(stream, "[rdf:_%d]", *((int*)statement->predicate));
301 else {
302 #ifdef RAPTOR_DEBUG
303 if(!statement->predicate)
304 RAPTOR_FATAL1("Statement has NULL predicate URI\n");
305 #endif
306 fputs((const char*)raptor_uri_as_string_v2(world, (raptor_uri*)statement->predicate), stream);
307 }
308
309 fputs(", ", stream);
310
311 if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL ||
312 statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) {
313 if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) {
314 fputc('<', stream);
315 fputs((const char*)raptor_xml_literal_datatype_uri_string, stream);
316 fputc('>', stream);
317 } else if(statement->object_literal_datatype) {
318 fputc('<', stream);
319 fputs((const char*)raptor_uri_as_string_v2(world, (raptor_uri*)statement->object_literal_datatype), stream);
320 fputc('>', stream);
321 }
322 fputc('"', stream);
323 fputs((const char*)statement->object, stream);
324 fputc('"', stream);
325 } else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS)
326 fputs((const char*)statement->object, stream);
327 else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL)
328 fprintf(stream, "[rdf:_%d]", *((int*)statement->object));
329 else {
330 #ifdef RAPTOR_DEBUG
331 if(!statement->object)
332 RAPTOR_FATAL1("Statement has NULL object URI\n");
333 #endif
334 fputs((const char*)raptor_uri_as_string_v2(world, (raptor_uri*)statement->object), stream);
335 }
336
337 fputc(']', stream);
338 }
339
340
341 #if !defined(RAPTOR_DISABLE_DEPRECATED) && !defined(RAPTOR_DISABLE_V1)
342 /**
343 * raptor_print_statement_detailed:
344 * @statement: #raptor_statement object to print
345 * @detailed: unused
346 * @stream: #FILE* stream
347 *
348 * Print a raptor_statement to a stream in a detailed fashion.
349 *
350 * raptor_init() MUST have been called before calling this function.
351 *
352 * @deprecated: an internal function, do not use.
353 *
354 * No current difference from calling raptor_print_statement().
355 *
356 **/
357 void
raptor_print_statement_detailed(const raptor_statement * statement,int detailed,FILE * stream)358 raptor_print_statement_detailed(const raptor_statement * statement,
359 int detailed, FILE *stream)
360 {
361 raptor_print_statement(statement, stream);
362 }
363 #endif
364
365
366 #ifndef RAPTOR_DISABLE_V1
367 /**
368 * raptor_statement_part_as_counted_string:
369 * @term: #raptor_statement part (subject, predicate, object)
370 * @type: #raptor_statement part type
371 * @literal_datatype: #raptor_statement part datatype
372 * @literal_language: #raptor_statement part language
373 * @len_p: Pointer to location to store length of new string (if not NULL)
374 *
375 * Turns part of raptor statement into a N-Triples format counted string.
376 *
377 * Turns the given @term into an N-Triples escaped string using all the
378 * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples
379 *
380 * The part (subject, predicate, object) of the raptor_statement is
381 * typically passed in as @term, the part type (subject_type,
382 * predicate_type, object_type) is passed in as @type. When the part
383 * is a literal, the @literal_datatype and @literal_language fields
384 * are set, otherwise NULL (usually object_datatype,
385 * object_literal_language).
386 *
387 * raptor_init() MUST have been called before calling this function.
388 * Use raptor_statement_part_as_counted_string_v2() if using raptor_world APIs.
389 *
390 * Return value: the new string or NULL on failure. The length of
391 * the new string is returned in *@len_p if len_p is not NULL.
392 **/
393 unsigned char*
raptor_statement_part_as_counted_string(const void * term,raptor_identifier_type type,raptor_uri * literal_datatype,const unsigned char * literal_language,size_t * len_p)394 raptor_statement_part_as_counted_string(const void *term,
395 raptor_identifier_type type,
396 raptor_uri* literal_datatype,
397 const unsigned char *literal_language,
398 size_t* len_p)
399 {
400 return raptor_statement_part_as_counted_string_v2(raptor_world_instance(),
401 term,
402 type,
403 literal_datatype,
404 literal_language,
405 len_p);
406 }
407 #endif
408
409
410 /**
411 * raptor_statement_part_as_counted_string_v2:
412 * @world: raptor_world object
413 * @term: #raptor_statement part (subject, predicate, object)
414 * @type: #raptor_statement part type
415 * @literal_datatype: #raptor_statement part datatype
416 * @literal_language: #raptor_statement part language
417 * @len_p: Pointer to location to store length of new string (if not NULL)
418 *
419 * Turns part of raptor statement into a N-Triples format counted string.
420 *
421 * Turns the given @term into an N-Triples escaped string using all the
422 * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples
423 *
424 * The part (subject, predicate, object) of the raptor_statement is
425 * typically passed in as @term, the part type (subject_type,
426 * predicate_type, object_type) is passed in as @type. When the part
427 * is a literal, the @literal_datatype and @literal_language fields
428 * are set, otherwise NULL (usually object_datatype,
429 * object_literal_language).
430 *
431 * Return value: the new string or NULL on failure. The length of
432 * the new string is returned in *@len_p if len_p is not NULL.
433 **/
434 unsigned char*
raptor_statement_part_as_counted_string_v2(raptor_world * world,const void * term,raptor_identifier_type type,raptor_uri * literal_datatype,const unsigned char * literal_language,size_t * len_p)435 raptor_statement_part_as_counted_string_v2(raptor_world* world,
436 const void *term,
437 raptor_identifier_type type,
438 raptor_uri* literal_datatype,
439 const unsigned char *literal_language,
440 size_t* len_p)
441 {
442 size_t len=0, term_len, uri_len;
443 size_t language_len=0;
444 unsigned char *s, *buffer=NULL;
445 unsigned char *uri_string=NULL;
446
447 switch(type) {
448 case RAPTOR_IDENTIFIER_TYPE_LITERAL:
449 case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL:
450 term_len=strlen((const char*)term);
451 len=2+term_len;
452 if(literal_language && type == RAPTOR_IDENTIFIER_TYPE_LITERAL) {
453 language_len=strlen((const char*)literal_language);
454 len+= language_len+1;
455 }
456 if(type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL)
457 len += 4+raptor_xml_literal_datatype_uri_string_len;
458 else if(literal_datatype) {
459 uri_string=raptor_uri_as_counted_string_v2(world, (raptor_uri*)literal_datatype, &uri_len);
460 len += 4+uri_len;
461 }
462
463 buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1);
464 if(!buffer)
465 return NULL;
466
467 s=buffer;
468 *s++ ='"';
469 /* raptor_print_ntriples_string(stream, (const char*)term, '"'); */
470 strcpy((char*)s, (const char*)term);
471 s+= term_len;
472 *s++ ='"';
473 if(literal_language && type == RAPTOR_IDENTIFIER_TYPE_LITERAL) {
474 *s++ ='@';
475 strcpy((char*)s, (const char*)literal_language);
476 s+= language_len;
477 }
478
479 if(type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) {
480 *s++ ='^';
481 *s++ ='^';
482 *s++ ='<';
483 strcpy((char*)s, (const char*)raptor_xml_literal_datatype_uri_string);
484 s+= raptor_xml_literal_datatype_uri_string_len;
485 *s++ ='>';
486 } else if(literal_datatype) {
487 *s++ ='^';
488 *s++ ='^';
489 *s++ ='<';
490 strcpy((char*)s, (const char*)uri_string);
491 s+= uri_len;
492 *s++ ='>';
493 }
494 *s++ ='\0';
495
496 break;
497
498 case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS:
499 len=2+strlen((const char*)term);
500 buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1);
501 if(!buffer)
502 return NULL;
503 s=buffer;
504 *s++ ='_';
505 *s++ =':';
506 strcpy((char*)s, (const char*)term);
507 break;
508
509 case RAPTOR_IDENTIFIER_TYPE_ORDINAL:
510 len=raptor_rdf_namespace_uri_len + 13;
511 buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1);
512 if(!buffer)
513 return NULL;
514
515 sprintf((char*)buffer, "<%s_%d>",
516 raptor_rdf_namespace_uri, *((int*)term));
517 break;
518
519 case RAPTOR_IDENTIFIER_TYPE_RESOURCE:
520 case RAPTOR_IDENTIFIER_TYPE_PREDICATE:
521 uri_string=raptor_uri_as_counted_string_v2(world, (raptor_uri*)term, &uri_len);
522 len=2+uri_len;
523 buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1);
524 if(!buffer)
525 return NULL;
526
527 s=buffer;
528 *s++ ='<';
529 /* raptor_print_ntriples_string(stream, raptor_uri_as_string((raptor_uri*)term), '\0'); */
530 strcpy((char*)s, (const char*)uri_string);
531 s+= uri_len;
532 *s++ ='>';
533 *s++ ='\0';
534 break;
535
536 case RAPTOR_IDENTIFIER_TYPE_UNKNOWN:
537 default:
538 RAPTOR_FATAL2("Unknown type %d", type);
539 }
540
541 if(len_p)
542 *len_p=len;
543
544 return buffer;
545 }
546
547
548 #ifndef RAPTOR_DISABLE_V1
549 /**
550 * raptor_statement_part_as_string:
551 * @term: #raptor_statement part (subject, predicate, object)
552 * @type: #raptor_statement part type
553 * @literal_datatype: #raptor_statement part datatype
554 * @literal_language: #raptor_statement part language
555 *
556 * Turns part of raptor statement into a N-Triples format string.
557 *
558 * Turns the given @term into an N-Triples escaped string using all the
559 * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples
560 *
561 * The part (subject, predicate, object) of the raptor_statement is
562 * typically passed in as @term, the part type (subject_type,
563 * predicate_type, object_type) is passed in as @type. When the part
564 * is a literal, the @literal_datatype and @literal_language fields
565 * are set, otherwise NULL (usually object_datatype,
566 * object_literal_language).
567 *
568 * raptor_init() MUST have been called before calling this function.
569 * Use raptor_statement_part_as_string_v2() if using raptor_world APIs.
570 *
571 * Return value: the new string or NULL on failure.
572 **/
573 unsigned char*
raptor_statement_part_as_string(const void * term,raptor_identifier_type type,raptor_uri * literal_datatype,const unsigned char * literal_language)574 raptor_statement_part_as_string(const void *term,
575 raptor_identifier_type type,
576 raptor_uri* literal_datatype,
577 const unsigned char *literal_language)
578 {
579 return raptor_statement_part_as_string_v2(raptor_world_instance(),
580 term,
581 type,
582 literal_datatype,
583 literal_language);
584 }
585 #endif
586
587
588 /**
589 * raptor_statement_part_as_string_v2:
590 * @world: raptor_world object
591 * @term: #raptor_statement part (subject, predicate, object)
592 * @type: #raptor_statement part type
593 * @literal_datatype: #raptor_statement part datatype
594 * @literal_language: #raptor_statement part language
595 *
596 * Turns part of raptor statement into a N-Triples format string.
597 *
598 * Turns the given @term into an N-Triples escaped string using all the
599 * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples
600 *
601 * The part (subject, predicate, object) of the raptor_statement is
602 * typically passed in as @term, the part type (subject_type,
603 * predicate_type, object_type) is passed in as @type. When the part
604 * is a literal, the @literal_datatype and @literal_language fields
605 * are set, otherwise NULL (usually object_datatype,
606 * object_literal_language).
607 *
608 * Return value: the new string or NULL on failure.
609 **/
610 unsigned char*
raptor_statement_part_as_string_v2(raptor_world * world,const void * term,raptor_identifier_type type,raptor_uri * literal_datatype,const unsigned char * literal_language)611 raptor_statement_part_as_string_v2(raptor_world* world,
612 const void *term,
613 raptor_identifier_type type,
614 raptor_uri* literal_datatype,
615 const unsigned char *literal_language)
616 {
617 return raptor_statement_part_as_counted_string_v2(world, term, type,
618 literal_datatype,
619 literal_language,
620 NULL);
621 }
622
623
624 static void
raptor_print_statement_part_as_ntriples(raptor_world * world,FILE * stream,const void * term,raptor_identifier_type type,raptor_uri * literal_datatype,const unsigned char * literal_language)625 raptor_print_statement_part_as_ntriples(raptor_world* world,
626 FILE* stream,
627 const void *term,
628 raptor_identifier_type type,
629 raptor_uri* literal_datatype,
630 const unsigned char *literal_language)
631 {
632 switch(type) {
633 case RAPTOR_IDENTIFIER_TYPE_LITERAL:
634 case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL:
635 fputc('"', stream);
636 raptor_print_ntriples_string(stream, (const unsigned char*)term, '"');
637 fputc('"', stream);
638 if(literal_language && type == RAPTOR_IDENTIFIER_TYPE_LITERAL) {
639 fputc('@', stream);
640 fputs((const char*)literal_language, stream);
641 }
642 if(type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) {
643 fputs("^^<", stream);
644 fputs((const char*)raptor_xml_literal_datatype_uri_string, stream);
645 fputc('>', stream);
646 } else if(literal_datatype) {
647 fputs("^^<", stream);
648 fputs((const char*)raptor_uri_as_string_v2(world, (raptor_uri*)literal_datatype), stream);
649 fputc('>', stream);
650 }
651
652 break;
653
654 case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS:
655 fputs("_:", stream);
656 fputs((const char*)term, stream);
657 break;
658
659 case RAPTOR_IDENTIFIER_TYPE_ORDINAL:
660 fprintf(stream, "<%s_%d>",
661 raptor_rdf_namespace_uri, *((int*)term));
662 break;
663
664 case RAPTOR_IDENTIFIER_TYPE_RESOURCE:
665 case RAPTOR_IDENTIFIER_TYPE_PREDICATE:
666 fputc('<', stream);
667 raptor_print_ntriples_string(stream, raptor_uri_as_string_v2(world, (raptor_uri*)term), '\0');
668 fputc('>', stream);
669 break;
670
671 case RAPTOR_IDENTIFIER_TYPE_UNKNOWN:
672 default:
673 RAPTOR_FATAL2("Unknown type %d", type);
674 }
675 }
676
677
678 #ifndef RAPTOR_DISABLE_V1
679 /**
680 * raptor_print_statement_as_ntriples:
681 * @statement: #raptor_statement to print
682 * @stream: #FILE* stream
683 *
684 * Print a raptor_statement in N-Triples form.
685 *
686 * raptor_init() MUST have been called before calling this function.
687 * Use raptor_print_statement_as_ntriples_v2() if using raptor_world APIs.
688 *
689 **/
690 void
raptor_print_statement_as_ntriples(const raptor_statement * statement,FILE * stream)691 raptor_print_statement_as_ntriples(const raptor_statement * statement,
692 FILE *stream)
693 {
694 raptor_print_statement_as_ntriples_common(raptor_world_instance(),
695 statement,
696 stream);
697 }
698 #endif
699
700
701 /**
702 * raptor_print_statement_as_ntriples_v2:
703 * @statement: #raptor_statement_v2 to print
704 * @stream: #FILE* stream
705 *
706 * Print a raptor_statement in N-Triples form.
707 *
708 **/
709 void
raptor_print_statement_as_ntriples_v2(const raptor_statement_v2 * statement,FILE * stream)710 raptor_print_statement_as_ntriples_v2(const raptor_statement_v2 * statement,
711 FILE *stream)
712 {
713 raptor_print_statement_as_ntriples_common(statement->world,
714 statement->s,
715 stream);
716 }
717
718
719 static void
raptor_print_statement_as_ntriples_common(raptor_world * world,const raptor_statement * statement,FILE * stream)720 raptor_print_statement_as_ntriples_common(raptor_world* world,
721 const raptor_statement *statement,
722 FILE *stream)
723 {
724 raptor_print_statement_part_as_ntriples(world,
725 stream,
726 statement->subject,
727 statement->subject_type,
728 NULL, NULL);
729 fputc(' ', stream);
730 raptor_print_statement_part_as_ntriples(world,
731 stream,
732 statement->predicate,
733 statement->predicate_type,
734 NULL, NULL);
735 fputc(' ', stream);
736 raptor_print_statement_part_as_ntriples(world,
737 stream,
738 statement->object,
739 statement->object_type,
740 statement->object_literal_datatype,
741 statement->object_literal_language);
742 fputs(" .", stream);
743 }
744
745
746 #ifndef RAPTOR_DISABLE_V1
747 /**
748 * raptor_statement_compare:
749 * @s1: first statement
750 * @s2: second statement
751 *
752 * Compare a pair of #raptor_statement
753 *
754 * If types are different, the #raptor_identifier_type order is used.
755 * Resource and datatype URIs are compared with raptor_uri_compare(),
756 * blank nodes and literals with strcmp(). If one literal has no
757 * language, it is earlier than one with a language. If one literal
758 * has no datatype, it is earlier than one with a datatype.
759 *
760 * raptor_init() MUST have been called before calling this function.
761 * Use raptor_statement_compare_v2() if using raptor_world APIs.
762 *
763 * Return value: <0 if s1 is before s2, 0 if equal, >0 if s1 is after s2
764 */
765 int
raptor_statement_compare(const raptor_statement * s1,const raptor_statement * s2)766 raptor_statement_compare(const raptor_statement *s1,
767 const raptor_statement *s2)
768 {
769 return raptor_statement_compare_common(raptor_world_instance(), s1, s2);
770 }
771 #endif
772
773
774 /**
775 * raptor_statement_compare_v2:
776 * @s1: first statement
777 * @s2: second statement
778 *
779 * Compare a pair of #raptor_statement_v2
780 *
781 * If types are different, the #raptor_identifier_type order is used.
782 * Resource and datatype URIs are compared with raptor_uri_compare(),
783 * blank nodes and literals with strcmp(). If one literal has no
784 * language, it is earlier than one with a language. If one literal
785 * has no datatype, it is earlier than one with a datatype.
786 *
787 * Return value: <0 if s1 is before s2, 0 if equal, >0 if s1 is after s2
788 */
789 int
raptor_statement_compare_v2(const raptor_statement_v2 * s1,const raptor_statement_v2 * s2)790 raptor_statement_compare_v2(const raptor_statement_v2 *s1,
791 const raptor_statement_v2 *s2)
792 {
793 return raptor_statement_compare_common(s1->world, s1->s, s2->s);
794 }
795
796
797 static int
raptor_statement_compare_common(raptor_world * world,const raptor_statement * s1,const raptor_statement * s2)798 raptor_statement_compare_common(raptor_world* world,
799 const raptor_statement *s1,
800 const raptor_statement *s2)
801 {
802 int d=0;
803
804 if(s1->subject && s2->subject) {
805 d=s1->subject_type != s2->subject_type;
806 if(d)
807 return d;
808
809 /* subjects are URIs or blank nodes */
810 if(s1->subject_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS)
811 d=strcmp((char*)s1->subject, (char*)s2->subject);
812 else
813 d=raptor_uri_compare_v2(world,
814 (raptor_uri*)s1->subject,
815 (raptor_uri*)s2->subject);
816 } else if(s1->subject || s2->subject)
817 d=(!s1->subject ? -1 : 1);
818 if(d)
819 return d;
820
821
822 /* predicates are URIs */
823 if(s1->predicate && s2->predicate) {
824 d=raptor_uri_compare_v2(world,
825 (raptor_uri*)s1->predicate,
826 (raptor_uri*)s2->predicate);
827 } else if(s1->predicate || s2->predicate)
828 d=(!s1->predicate ? -1 : 1);
829 if(d)
830 return d;
831
832
833 /* objects are URIs or blank nodes or literals */
834 if(s1->object && s2->object) {
835 if(s1->object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL ||
836 s1->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) {
837 d=strcmp((char*)s1->object, (char*)s2->object);
838 if(d)
839 return d;
840
841 if(s1->object_literal_language && s2->object_literal_language) {
842 /* both have a language */
843 d=strcmp((char*)s1->object_literal_language,
844 (char*)s2->object_literal_language);
845 } else if(s1->object_literal_language || s2->object_literal_language)
846 /* only one has a language; the language-less one is earlier */
847 d=(!s1->object_literal_language ? -1 : 1);
848 if(d)
849 return d;
850
851 if(s1->object_literal_datatype && s2->object_literal_datatype) {
852 /* both have a datatype */
853 d=raptor_uri_compare_v2(world,
854 (raptor_uri*)s1->object_literal_datatype,
855 (raptor_uri*)s2->object_literal_datatype);
856 } else if(s1->object_literal_datatype || s2->object_literal_datatype)
857 /* only one has a datatype; the datatype-less one is earlier */
858 d=(!s1->object_literal_datatype ? -1 : 1);
859 if(d)
860 return d;
861
862 } else if(s1->object_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS)
863 d=strcmp((char*)s1->object, (char*)s2->object);
864 else
865 d=raptor_uri_compare_v2(world, (raptor_uri*)s1->object, (raptor_uri*)s2->object);
866 } else if(s1->object || s2->object)
867 d=(!s1->object ? -1 : 1);
868
869 return d;
870 }
871