1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * rdf_serializer.c - RDF Serializer (RDF triples to syntax) interface
4 *
5 * Copyright (C) 2002-2008, David Beckett http://www.dajobe.org/
6 * Copyright (C) 2002-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 <rdf_config.h>
28 #endif
29
30 #ifdef WIN32
31 #include <win32_rdf_config.h>
32 #endif
33
34 #include <stdio.h>
35 #include <string.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39 #ifdef HAVE_ERRNO_H
40 #include <errno.h>
41 #endif
42
43 #include <redland.h>
44
45
46 #ifndef STANDALONE
47
48 /**
49 * librdf_init_serializer:
50 * @world: redland world object
51 *
52 * INTERNAL - Initialise the serializer module.
53 *
54 **/
55 void
librdf_init_serializer(librdf_world * world)56 librdf_init_serializer(librdf_world *world)
57 {
58 librdf_serializer_raptor_constructor(world);
59 }
60
61
62 /**
63 * librdf_finish_serializer:
64 * @world: redland world object
65 *
66 * INTERNAL - Terminate the serializer module.
67 *
68 **/
69 void
librdf_finish_serializer(librdf_world * world)70 librdf_finish_serializer(librdf_world *world)
71 {
72 if(world->serializers) {
73 raptor_free_sequence(world->serializers);
74 world->serializers=NULL;
75 }
76 #ifdef HAVE_RAPTOR_RDF_SERIALIZER
77 librdf_serializer_raptor_destructor();
78 #endif
79 }
80
81
82 /* helper functions */
83 static void
librdf_free_serializer_factory(librdf_serializer_factory * factory)84 librdf_free_serializer_factory(librdf_serializer_factory *factory)
85 {
86 if(factory->name)
87 LIBRDF_FREE(char*, factory->name);
88 if(factory->label)
89 LIBRDF_FREE(char*, factory->label);
90 if(factory->mime_type)
91 LIBRDF_FREE(char*, factory->mime_type);
92 if(factory->type_uri)
93 librdf_free_uri(factory->type_uri);
94 LIBRDF_FREE(librdf_serializer_factory, factory);
95 }
96
97
98 /**
99 * librdf_serializer_register_factory:
100 * @world: redland world object
101 * @name: the name of the serializer
102 * @label: the label of the serializer (optional)
103 * @mime_type: MIME type of the syntax (optional)
104 * @uri_string: URI of the syntax (optional)
105 * @factory: function to be called to register the factor parameters
106 *
107 * Register a serializer factory .
108 *
109 **/
110 REDLAND_EXTERN_C
111 void
librdf_serializer_register_factory(librdf_world * world,const char * name,const char * label,const char * mime_type,const unsigned char * uri_string,void (* factory)(librdf_serializer_factory *))112 librdf_serializer_register_factory(librdf_world *world,
113 const char *name, const char *label,
114 const char *mime_type,
115 const unsigned char *uri_string,
116 void (*factory) (librdf_serializer_factory*))
117 {
118 librdf_serializer_factory *serializer;
119
120 librdf_world_open(world);
121
122 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1
123 LIBRDF_DEBUG2("Received registration for serializer %s\n", name);
124 #endif
125
126 if(!world->serializers) {
127 world->serializers = raptor_new_sequence((raptor_data_free_handler)librdf_free_serializer_factory, NULL);
128
129 if(!world->serializers)
130 goto oom;
131 }
132
133 serializer = LIBRDF_CALLOC(librdf_serializer_factory*, 1, sizeof(*serializer));
134 if(!serializer)
135 goto oom;
136
137 serializer->name = LIBRDF_MALLOC(char*, strlen(name) + 1);
138 if(!serializer->name)
139 goto oom_tidy;
140 strcpy(serializer->name, name);
141
142 if(label) {
143 serializer->label = LIBRDF_MALLOC(char*, strlen(label) + 1);
144 if(!serializer->label)
145 goto oom_tidy;
146 strcpy(serializer->label, label);
147 }
148
149 /* register mime type if any */
150 if(mime_type) {
151 serializer->mime_type = LIBRDF_MALLOC(char*, strlen(mime_type) + 1);
152 if(!serializer->mime_type)
153 goto oom_tidy;
154 strcpy(serializer->mime_type, mime_type);
155 }
156
157 /* register URI if any */
158 if(uri_string) {
159 serializer->type_uri=librdf_new_uri(world, uri_string);
160 if(!serializer->type_uri)
161 goto oom_tidy;
162 }
163
164 if(raptor_sequence_push(world->serializers, serializer))
165 goto oom;
166
167 /* Call the serializer registration function on the new object */
168 (*factory)(serializer);
169
170 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1
171 LIBRDF_DEBUG3("%s has context size %d\n", name, serializer->context_length);
172 #endif
173
174 return;
175
176 oom_tidy:
177 librdf_free_serializer_factory(serializer);
178 oom:
179 LIBRDF_FATAL1(world, LIBRDF_FROM_SERIALIZER, "Out of memory");
180 }
181
182
183 /**
184 * librdf_get_serializer_factory:
185 * @world: redland world object
186 * @name: the name of the factory (or NULL or empty string if don't care)
187 * @mime_type: the MIME type of the syntax (NULL or empty string if not used)
188 * @type_uri: URI of syntax (NULL if not used)
189 *
190 * Get a serializer factory by name.
191 *
192 * If all fields are NULL, this means any parser supporting
193 * MIME Type "application/rdf+xml"
194 *
195 * Return value: the factory or NULL if not found
196 **/
197 librdf_serializer_factory*
librdf_get_serializer_factory(librdf_world * world,const char * name,const char * mime_type,librdf_uri * type_uri)198 librdf_get_serializer_factory(librdf_world *world,
199 const char *name, const char *mime_type,
200 librdf_uri *type_uri)
201 {
202 librdf_serializer_factory *factory;
203
204 librdf_world_open(world);
205
206 if(name && !*name)
207 name=NULL;
208 if(!mime_type || (mime_type && !*mime_type)) {
209 if(!name && !type_uri)
210 name="rdfxml";
211 else
212 mime_type=NULL;
213 }
214
215 /* return 1st serializer if no particular one wanted */
216 if(!name && !mime_type && !type_uri) {
217 factory=(librdf_serializer_factory*)raptor_sequence_get_at(world->serializers, 0);
218 if(!factory) {
219 LIBRDF_DEBUG1("No serializers available\n");
220 return NULL;
221 }
222 } else {
223 int i;
224
225 for(i=0;
226 (factory=(librdf_serializer_factory*)raptor_sequence_get_at(world->serializers, i));
227 i++) {
228 /* next if name does not match */
229 if(name && strcmp(factory->name, name))
230 continue;
231
232 /* MIME type may need to match */
233 if(mime_type) {
234 if(!factory->mime_type)
235 continue;
236 if(strcmp(factory->mime_type, mime_type))
237 continue;
238 }
239
240 /* URI may need to match */
241 if(type_uri) {
242 if(!factory->type_uri)
243 continue;
244
245 if(!librdf_uri_equals(factory->type_uri, type_uri))
246 continue;
247 }
248
249 /* found it */
250 break;
251 }
252 /* else FACTORY with given arguments not found */
253 if(!factory)
254 return NULL;
255 }
256
257 return factory;
258 }
259
260
261 /**
262 * librdf_serializer_enumerate:
263 * @world: redland world object
264 * @counter: index into the list of serializers
265 * @name: pointer to store the name of the serializer (or NULL)
266 * @label: pointer to store syntax readable label (or NULL)
267 *
268 * Get information on serializers.
269 *
270 * @Deprecated: use librdf_serializer_get_description() to return more information in a static structure.
271 *
272 * Return value: non 0 on failure of if counter is out of range
273 **/
274 int
librdf_serializer_enumerate(librdf_world * world,const unsigned int counter,const char ** name,const char ** label)275 librdf_serializer_enumerate(librdf_world* world,
276 const unsigned int counter,
277 const char **name, const char **label)
278 {
279 librdf_serializer_factory *factory;
280 int ioffset = LIBRDF_GOOD_CAST(int, counter);
281
282 librdf_world_open(world);
283
284 factory = (librdf_serializer_factory*)raptor_sequence_get_at(world->serializers,
285 ioffset);
286 if(!factory)
287 return 1;
288
289 if(name)
290 *name = factory->name;
291
292 if(label)
293 *label = factory->label;
294
295 return 0;
296 }
297
298
299 /**
300 * librdf_serializer_get_description:
301 * @world: world object
302 * @counter: index into the list of serializers
303 *
304 * Get serializer descriptive syntax information
305 *
306 * Return value: description or NULL if counter is out of range
307 **/
308 const raptor_syntax_description*
librdf_serializer_get_description(librdf_world * world,unsigned int counter)309 librdf_serializer_get_description(librdf_world* world,
310 unsigned int counter)
311 {
312 librdf_world_open(world);
313
314 return raptor_world_get_serializer_description(world->raptor_world_ptr,
315 counter);
316 }
317
318
319 /**
320 * librdf_serializer_check_name:
321 * @world: redland world object
322 * @name: name of serializer
323 *
324 * Check if a serializer name is known
325 *
326 * Return value: non 0 if name is a known serializer
327 **/
328 int
librdf_serializer_check_name(librdf_world * world,const char * name)329 librdf_serializer_check_name(librdf_world* world, const char *name)
330 {
331 librdf_serializer_factory *factory;
332 int i;
333
334 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 0);
335
336 librdf_world_open(world);
337
338 for(i = 0;
339 (factory = (librdf_serializer_factory*)raptor_sequence_get_at(world->serializers, i));
340 i++) {
341 if(!strcmp(factory->name, name))
342 return 1;
343 }
344
345 return 0;
346 }
347
348
349 /**
350 * librdf_new_serializer:
351 * @world: redland world object
352 * @name: the serializer factory name (or NULL or empty string if don't care)
353 * @mime_type: the MIME type of the syntax (NULL if not used)
354 * @type_uri: URI of syntax (NULL if not used)
355 *
356 * Constructor - create a new #librdf_serializer object.
357 *
358 * Return value: new #librdf_serializer object or NULL
359 **/
360 librdf_serializer*
librdf_new_serializer(librdf_world * world,const char * name,const char * mime_type,librdf_uri * type_uri)361 librdf_new_serializer(librdf_world *world,
362 const char *name, const char *mime_type,
363 librdf_uri *type_uri)
364 {
365 librdf_serializer_factory* factory;
366
367 librdf_world_open(world);
368
369 factory = librdf_get_serializer_factory(world, name, mime_type, type_uri);
370 if(!factory) {
371 if(name)
372 librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_SERIALIZER, NULL,
373 "serializer '%s' not found", name);
374 else if(mime_type)
375 librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_SERIALIZER, NULL,
376 "serializer for mime_type '%s' not found", mime_type);
377 else if(type_uri)
378 librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_SERIALIZER, NULL,
379 "serializer for type URI '%s' not found",
380 librdf_uri_as_string(type_uri));
381 else
382 librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_SERIALIZER, NULL,
383 "default serializer not found");
384 return NULL;
385 }
386
387 return librdf_new_serializer_from_factory(world, factory);
388 }
389
390
391 /**
392 * librdf_new_serializer_from_factory:
393 * @world: redland world object
394 * @factory: the serializer factory to use to create this serializer
395 *
396 * Constructor - create a new #librdf_serializer object.
397 *
398 * Return value: new #librdf_serializer object or NULL
399 **/
400 librdf_serializer*
librdf_new_serializer_from_factory(librdf_world * world,librdf_serializer_factory * factory)401 librdf_new_serializer_from_factory(librdf_world *world,
402 librdf_serializer_factory *factory)
403 {
404 librdf_serializer* d;
405
406 librdf_world_open(world);
407
408 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(factory, librdf_serializer_factory, NULL);
409
410 d = LIBRDF_CALLOC(librdf_serializer*, 1, sizeof(*d));
411 if(!d)
412 return NULL;
413
414 d->context = LIBRDF_CALLOC(void*, 1, factory->context_length);
415 if(!d->context) {
416 librdf_free_serializer(d);
417 return NULL;
418 }
419
420 d->world=world;
421
422 d->factory=factory;
423
424 if(factory->init)
425 if(factory->init(d, d->context)) {
426 librdf_free_serializer(d);
427 return NULL;
428 }
429
430 return d;
431 }
432
433
434 /**
435 * librdf_free_serializer:
436 * @serializer: the serializer
437 *
438 * Destructor - destroys a #librdf_serializer object.
439 *
440 **/
441 void
librdf_free_serializer(librdf_serializer * serializer)442 librdf_free_serializer(librdf_serializer *serializer)
443 {
444 if(!serializer)
445 return;
446
447 if(serializer->context) {
448 if(serializer->factory->terminate)
449 serializer->factory->terminate(serializer->context);
450 LIBRDF_FREE(serializer_context, serializer->context);
451 }
452 LIBRDF_FREE(librdf_serializer, serializer);
453 }
454
455
456
457 /* methods */
458
459
460 #ifndef REDLAND_DISABLE_DEPRECATED
461 /**
462 * librdf_serializer_serialize_model:
463 * @serializer: the serializer
464 * @handle: file handle to serialize to
465 * @base_uri: the base URI to use (or NULL)
466 * @model: the #librdf_model model to use
467 *
468 * @Deprecated: Use librdf_serializer_serialize_model_to_file_handle()
469 *
470 * Write a serialized #librdf_model to a FILE*.
471 *
472 * Return value: non 0 on failure
473 **/
474 int
librdf_serializer_serialize_model(librdf_serializer * serializer,FILE * handle,librdf_uri * base_uri,librdf_model * model)475 librdf_serializer_serialize_model(librdf_serializer* serializer,
476 FILE *handle, librdf_uri* base_uri,
477 librdf_model* model)
478 {
479 return librdf_serializer_serialize_model_to_file_handle(serializer,
480 handle, base_uri,
481 model);
482 }
483 #endif
484
485
486 /**
487 * librdf_serializer_serialize_stream_to_file_handle:
488 * @serializer: the serializer
489 * @handle: file handle to serialize to
490 * @base_uri: the base URI to use (or NULL)
491 * @stream: the #librdf_stream model to use
492 *
493 * Write a #librdf_stream to a FILE*.
494 *
495 * Return value: non 0 on failure
496 **/
497 int
librdf_serializer_serialize_stream_to_file_handle(librdf_serializer * serializer,FILE * handle,librdf_uri * base_uri,librdf_stream * stream)498 librdf_serializer_serialize_stream_to_file_handle(librdf_serializer* serializer,
499 FILE *handle,
500 librdf_uri* base_uri,
501 librdf_stream* stream)
502 {
503 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, 1);
504 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(handle, FILE*, 1);
505 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, 1);
506
507 return serializer->factory->serialize_stream_to_file_handle(serializer->context,
508 handle, base_uri, stream);
509 }
510
511
512 /**
513 * librdf_serializer_serialize_model_to_file_handle:
514 * @serializer: the serializer
515 * @handle: file handle to serialize to
516 * @base_uri: the base URI to use (or NULL)
517 * @model: the #librdf_model model to use
518 *
519 * Write a serialized #librdf_model to a FILE*.
520 *
521 * Return value: non 0 on failure
522 **/
523 int
librdf_serializer_serialize_model_to_file_handle(librdf_serializer * serializer,FILE * handle,librdf_uri * base_uri,librdf_model * model)524 librdf_serializer_serialize_model_to_file_handle(librdf_serializer* serializer,
525 FILE *handle,
526 librdf_uri* base_uri,
527 librdf_model* model)
528 {
529 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, 1);
530 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(handle, FILE*, 1);
531 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
532
533 return serializer->factory->serialize_model_to_file_handle(serializer->context,
534 handle, base_uri, model);
535 }
536
537
538 /**
539 * librdf_serializer_serialize_stream_to_file:
540 * @serializer: the serializer
541 * @name: filename to serialize to
542 * @base_uri: the base URI to use (or NULL)
543 * @stream: the #librdf_stream stream to use
544 *
545 * Write a #librdf_stream to a file.
546 *
547 * Return value: non 0 on failure
548 **/
549 int
librdf_serializer_serialize_stream_to_file(librdf_serializer * serializer,const char * name,librdf_uri * base_uri,librdf_stream * stream)550 librdf_serializer_serialize_stream_to_file(librdf_serializer* serializer,
551 const char *name,
552 librdf_uri* base_uri,
553 librdf_stream* stream)
554 {
555 FILE* fh;
556 int status;
557
558 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, 1);
559 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, string, 1);
560 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, 1);
561
562 fh=fopen(name, "w+");
563 if(!fh) {
564 librdf_log(serializer->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_SERIALIZER,
565 NULL, "failed to open file '%s' for writing - %s",
566 name, strerror(errno));
567 return 1;
568 }
569
570 status=librdf_serializer_serialize_stream_to_file_handle(serializer, fh,
571 base_uri, stream);
572 fclose(fh);
573 return status;
574 }
575
576
577 /**
578 * librdf_serializer_serialize_model_to_file:
579 * @serializer: the serializer
580 * @name: filename to serialize to
581 * @base_uri: the base URI to use (or NULL)
582 * @model: the #librdf_model model to use
583 *
584 * Write a serialized #librdf_model to a file.
585 *
586 * Return value: non 0 on failure
587 **/
588 int
librdf_serializer_serialize_model_to_file(librdf_serializer * serializer,const char * name,librdf_uri * base_uri,librdf_model * model)589 librdf_serializer_serialize_model_to_file(librdf_serializer* serializer,
590 const char *name,
591 librdf_uri* base_uri,
592 librdf_model* model)
593 {
594 FILE* fh;
595 int status;
596
597 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, 1);
598 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, string, 1);
599 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
600
601 fh=fopen(name, "w+");
602 if(!fh) {
603 librdf_log(serializer->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_SERIALIZER,
604 NULL, "failed to open file '%s' for writing - %s",
605 name, strerror(errno));
606 return 1;
607 }
608
609 status=librdf_serializer_serialize_model_to_file_handle(serializer, fh,
610 base_uri, model);
611 fclose(fh);
612 return status;
613 }
614
615
616 /**
617 * librdf_serializer_serialize_stream_to_counted_string:
618 * @serializer: the serializer
619 * @base_uri: the base URI to use (or NULL)
620 * @stream: the #librdf_stream stream to use
621 * @length_p: pointer to store length or NULL
622 *
623 * Write a #librdf_stream to a counted string.
624 * Caller should free the string with librdf_free_memory().
625 *
626 * Return value: stream as string or NULL on failure
627 **/
628 unsigned char*
librdf_serializer_serialize_stream_to_counted_string(librdf_serializer * serializer,librdf_uri * base_uri,librdf_stream * stream,size_t * length_p)629 librdf_serializer_serialize_stream_to_counted_string(librdf_serializer* serializer,
630 librdf_uri* base_uri,
631 librdf_stream* stream,
632 size_t* length_p)
633 {
634 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, NULL);
635 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, NULL);
636
637 if(length_p)
638 *length_p=0;
639
640 return serializer->factory->serialize_stream_to_counted_string(serializer->context,
641 base_uri,
642 stream,
643 length_p);
644 }
645
646
647 /**
648 * librdf_serializer_serialize_model_to_counted_string:
649 * @serializer: the serializer
650 * @base_uri: the base URI to use (or NULL)
651 * @model: the #librdf_model model to use
652 * @length_p: pointer to store length or NULL
653 *
654 * Write a serialized #librdf_model to a counted string.
655 * The returned string must be freed by the caller using librdf_free_memory().
656 *
657 * Return value: non 0 on failure
658 **/
659 unsigned char*
librdf_serializer_serialize_model_to_counted_string(librdf_serializer * serializer,librdf_uri * base_uri,librdf_model * model,size_t * length_p)660 librdf_serializer_serialize_model_to_counted_string(librdf_serializer* serializer,
661 librdf_uri* base_uri,
662 librdf_model* model,
663 size_t* length_p)
664 {
665 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, NULL);
666 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
667
668 if(length_p)
669 *length_p=0;
670
671 return serializer->factory->serialize_model_to_counted_string(serializer->context,
672 base_uri, model,
673 length_p);
674 }
675
676
677 /**
678 * librdf_serializer_serialize_stream_to_string:
679 * @serializer: the serializer
680 * @base_uri: the base URI to use (or NULL)
681 * @stream: the #librdf_stream stream to use
682 *
683 * Write a #librdf_stream to a string.
684 *
685 * Return value: NULL on failure
686 **/
687 unsigned char*
librdf_serializer_serialize_stream_to_string(librdf_serializer * serializer,librdf_uri * base_uri,librdf_stream * stream)688 librdf_serializer_serialize_stream_to_string(librdf_serializer* serializer,
689 librdf_uri* base_uri,
690 librdf_stream* stream)
691 {
692 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, NULL);
693 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, NULL);
694
695 return serializer->factory->serialize_stream_to_counted_string(serializer->context,
696 base_uri,
697 stream,
698 NULL);
699 }
700
701
702 /**
703 * librdf_serializer_serialize_model_to_string:
704 * @serializer: the serializer
705 * @base_uri: the base URI to use (or NULL)
706 * @model: the #librdf_model model to use
707 *
708 * Write a serialized #librdf_model to a string.
709 * The returned string must be freed by the caller using librdf_free_memory().
710 *
711 * Return value: NULL on failure
712 **/
713 unsigned char*
librdf_serializer_serialize_model_to_string(librdf_serializer * serializer,librdf_uri * base_uri,librdf_model * model)714 librdf_serializer_serialize_model_to_string(librdf_serializer* serializer,
715 librdf_uri* base_uri,
716 librdf_model* model)
717 {
718 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, NULL);
719 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
720
721 return serializer->factory->serialize_model_to_counted_string(serializer->context,
722 base_uri, model,
723 NULL);
724 }
725
726
727 /**
728 * librdf_serializer_serialize_stream_to_iostream:
729 * @serializer: the serializer
730 * @base_uri: the base URI to use (or NULL)
731 * @stream: the #librdf_stream stream to use
732 * @iostr: the #raptor_iostream to write to
733 *
734 * Write a #librdf_stream to a #raptor_iostream.
735 * This function takes ownership of the iostream and frees it.
736 *
737 * Return value: non-0 on failure
738 **/
739 int
librdf_serializer_serialize_stream_to_iostream(librdf_serializer * serializer,librdf_uri * base_uri,librdf_stream * stream,raptor_iostream * iostr)740 librdf_serializer_serialize_stream_to_iostream(librdf_serializer* serializer,
741 librdf_uri* base_uri,
742 librdf_stream *stream,
743 raptor_iostream* iostr)
744 {
745 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, 1);
746 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, 1);
747
748 return serializer->factory->serialize_stream_to_iostream(serializer->context,
749 base_uri, stream,
750 iostr);
751 }
752
753
754
755 /**
756 * librdf_serializer_serialize_model_to_iostream:
757 * @serializer: the serializer
758 * @base_uri: the base URI to use (or NULL)
759 * @model: the #librdf_model model to use
760 * @iostr: the #raptor_iostream to write to
761 *
762 * Write a serialized #librdf_model to a #raptor_iostream.
763 * This function takes ownership of the iostream and frees it.
764 *
765 * Return value: non-0 on failure
766 **/
767 int
librdf_serializer_serialize_model_to_iostream(librdf_serializer * serializer,librdf_uri * base_uri,librdf_model * model,raptor_iostream * iostr)768 librdf_serializer_serialize_model_to_iostream(librdf_serializer* serializer,
769 librdf_uri* base_uri,
770 librdf_model *model,
771 raptor_iostream* iostr)
772 {
773 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, 1);
774 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
775
776 return serializer->factory->serialize_model_to_iostream(serializer->context,
777 base_uri, model,
778 iostr);
779 }
780
781
782 #ifndef REDLAND_DISABLE_DEPRECATED
783 /**
784 * librdf_serializer_set_error:
785 * @serializer: the serializer
786 * @user_data: user data to pass to function
787 * @error_fn: pointer to the function
788 *
789 * @Deprecated: Does nothing
790 *
791 * Set the serializer error handling function.
792 *
793 **/
794 REDLAND_EXTERN_C
795 void
librdf_serializer_set_error(librdf_serializer * serializer,void * user_data,void (* error_fn)(void * user_data,const char * msg,...))796 librdf_serializer_set_error(librdf_serializer* serializer, void *user_data,
797 void (*error_fn)(void *user_data, const char *msg, ...))
798 {
799 }
800 #endif
801
802
803 #ifndef REDLAND_DISABLE_DEPRECATED
804 /**
805 * librdf_serializer_set_warning:
806 * @serializer: the serializer
807 * @user_data: user data to pass to function
808 * @warning_fn: pointer to the function
809 *
810 * @Deprecated: Does nothing
811 *
812 * Set the serializer warning handling function.
813 *
814 **/
815 REDLAND_EXTERN_C
816 void
librdf_serializer_set_warning(librdf_serializer * serializer,void * user_data,void (* warning_fn)(void * user_data,const char * msg,...))817 librdf_serializer_set_warning(librdf_serializer* serializer, void *user_data,
818 void (*warning_fn)(void *user_data, const char *msg, ...))
819 {
820 }
821 #endif
822
823
824 /**
825 * librdf_serializer_get_feature:
826 * @serializer: serializer object
827 * @feature: URI of feature
828 *
829 * Get the value of a serializer feature.
830 *
831 * Return value: the value of the feature or NULL if no such feature
832 * exists or the value is empty.
833 **/
834 librdf_node*
librdf_serializer_get_feature(librdf_serializer * serializer,librdf_uri * feature)835 librdf_serializer_get_feature(librdf_serializer* serializer, librdf_uri *feature)
836 {
837 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, NULL);
838 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, NULL);
839
840 if(serializer->factory->get_feature)
841 return serializer->factory->get_feature(serializer->context, feature);
842
843 return NULL;
844 }
845
846 /**
847 * librdf_serializer_set_feature:
848 * @serializer: serializer object
849 * @feature: URI of feature
850 * @value: value to set
851 *
852 * Set the value of a serializer feature.
853 *
854 * Return value: non 0 on failure (negative if no such feature)
855 **/
856
857 int
librdf_serializer_set_feature(librdf_serializer * serializer,librdf_uri * feature,librdf_node * value)858 librdf_serializer_set_feature(librdf_serializer* serializer,
859 librdf_uri *feature, librdf_node* value)
860 {
861 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, -1);
862 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, -1);
863 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, librdf_node, -1);
864
865 if(serializer->factory->set_feature)
866 return serializer->factory->set_feature(serializer->context, feature, value);
867
868 return (-1);
869 }
870
871 /**
872 * librdf_serializer_set_namespace:
873 * @serializer: serializer object
874 * @uri: URI of namespace or NULL
875 * @prefix: prefix to use or NULL
876 *
877 * Set a namespace URI/prefix mapping.
878 *
879 * Return value: non 0 on failure
880 **/
881
882 int
librdf_serializer_set_namespace(librdf_serializer * serializer,librdf_uri * uri,const char * prefix)883 librdf_serializer_set_namespace(librdf_serializer* serializer,
884 librdf_uri *uri, const char *prefix)
885 {
886 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(serializer, librdf_serializer, 1);
887 if(uri && !*librdf_uri_as_string(uri))
888 uri=NULL;
889 if(prefix && !*prefix)
890 prefix=NULL;
891
892 if(serializer->factory->set_namespace)
893 return serializer->factory->set_namespace(serializer->context, uri, prefix);
894 return 1;
895 }
896
897 #endif
898
899
900 /* TEST CODE */
901
902
903 #ifdef STANDALONE
904
905 #ifdef HAVE_SYS_STAT_H
906 #include <sys/stat.h>
907 #endif
908
909 #ifdef HAVE_UNISTD_H
910 #include <unistd.h>
911 #endif
912
913 /* one more prototype */
914 int main(int argc, char *argv[]);
915
916
917 struct log_data {
918 int errors;
919 int warnings;
920 } LogData;
921
922
923 static int REDLAND_CALLBACK_STDCALL
log_handler(void * user_data,librdf_log_message * message)924 log_handler(void *user_data, librdf_log_message *message)
925 {
926 struct log_data* ld=(struct log_data*)user_data;
927
928 switch(message->level) {
929 case LIBRDF_LOG_ERROR:
930 ld->errors++;
931 break;
932 case LIBRDF_LOG_WARN:
933 ld->warnings++;
934 break;
935
936 case LIBRDF_LOG_NONE:
937 case LIBRDF_LOG_DEBUG:
938 case LIBRDF_LOG_INFO:
939 case LIBRDF_LOG_FATAL:
940 default:
941 break;
942 }
943
944 return 1;
945 }
946
947
948 #define EXPECTED_ERRORS1 3
949 /* Extra error is another UTF-8 encoding error */
950 #define EXPECTED_ERRORS2 4
951 #define EXPECTED_WARNINGS 0
952
953 #define SYNTAX_TYPE "ntriples"
954 #define SYNTAX_CONTENT \
955 "<http://purl.org/net/dajobe/> <http://purl.org/dc/elements/1.1/creator> \"Dave Beckett\" .\n" \
956 "<http://purl.org/net/dajobe/> <http://purl.org/dc/elements/1.1/description> \"The generic home page of Dave Beckett.\" .\n" \
957 "<http://purl.org/net/dajobe/> <http://purl.org/dc/elements/1.1/title> \"Dave Beckett's Home Page\" . \n"
958
959
960 int
main(int argc,char * argv[])961 main(int argc, char *argv[])
962 {
963 const char *program=librdf_basename((const char*)argv[0]);
964 const char *test_serializer_types[]={"rdfxml", "ntriples", NULL};
965 int i;
966 const char *type;
967 unsigned char *string;
968 size_t string_length;
969 librdf_world *world;
970 librdf_storage *storage;
971 librdf_model* model;
972 librdf_uri* base_uri;
973 librdf_statement* statement;
974 librdf_serializer* serializer;
975 librdf_parser* parser;
976 librdf_stream* stream;
977 FILE *fh;
978 struct stat st_buf;
979
980 world=librdf_new_world();
981 librdf_world_open(world);
982
983 librdf_world_set_logger(world, &LogData, log_handler);
984
985 for(i=0; (type=test_serializer_types[i]); i++) {
986 fprintf(stderr, "%s: Trying to create new %s serializer\n", program, type);
987 serializer=librdf_new_serializer(world, type, NULL, NULL);
988 if(!serializer) {
989 fprintf(stderr, "%s: Failed to create new serializer type %s\n", program, type);
990 continue;
991 }
992
993 fprintf(stderr, "%s: Freeing serializer\n", program);
994 librdf_free_serializer(serializer);
995 }
996
997
998 storage=librdf_new_storage(world, NULL, NULL, NULL);
999 model=librdf_new_model(world, storage, NULL);
1000
1001 /* ERROR: Subject URI is bad UTF-8 */
1002 statement=librdf_new_statement_from_nodes(world,
1003 librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/foo\xfc"),
1004 librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/bar"),
1005 librdf_new_node_from_literal(world, (const unsigned char*)"blah", NULL, 0));
1006
1007 librdf_model_add_statement(model, statement);
1008 librdf_free_statement(statement);
1009
1010 /* ERROR: Predicate URI is not serializable */
1011 statement=librdf_new_statement_from_nodes(world,
1012 librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/foo"),
1013 librdf_new_node_from_uri_string(world, (const unsigned char*)"http://bad.example.org/"),
1014 librdf_new_node_from_literal(world, (const unsigned char*)"blah", NULL, 0));
1015
1016 librdf_model_add_statement(model, statement);
1017 librdf_free_statement(statement);
1018
1019 /* ERROR: Object literal is bad UTF-8 */
1020 statement=librdf_new_statement_from_nodes(world,
1021 librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/foo"),
1022 librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/abc"),
1023 librdf_new_node_from_literal(world, (const unsigned char*)"\xfc", NULL, 0));
1024
1025 librdf_model_add_statement(model, statement);
1026 librdf_free_statement(statement);
1027
1028 serializer=librdf_new_serializer(world, "rdfxml", NULL, NULL);
1029 base_uri=librdf_new_uri(world, (const unsigned char*)"http://example.org/base#");
1030
1031 string=librdf_serializer_serialize_model_to_counted_string(serializer,
1032 base_uri, model,
1033 &string_length);
1034 #define EXPECTED_BAD_STRING_LENGTH1 382
1035 /* Raptor 2.0.11 changed the serialization slightly */
1036 #define EXPECTED_BAD_STRING_LENGTH2 378
1037 if(string_length != EXPECTED_BAD_STRING_LENGTH1 &&
1038 string_length != EXPECTED_BAD_STRING_LENGTH2) {
1039 fprintf(stderr, "%s: Serialising model to RDF/XML returned string '%s' size %d, expected %d or %d\n", program, string,
1040 (int)string_length,
1041 EXPECTED_BAD_STRING_LENGTH1, EXPECTED_BAD_STRING_LENGTH2);
1042 return 1;
1043 }
1044
1045 librdf_free_memory(string);
1046
1047 librdf_free_uri(base_uri); base_uri=NULL;
1048 librdf_free_model(model); model=NULL;
1049 librdf_free_storage(storage); storage=NULL;
1050
1051
1052 if(LogData.errors != EXPECTED_ERRORS1 && LogData.errors != EXPECTED_ERRORS2) {
1053 fprintf(stderr, "%s: Serialising to RDF/XML returned %d errors, expected %d or %d\n", program,
1054 LogData.errors, EXPECTED_ERRORS1, EXPECTED_ERRORS2);
1055 return 1;
1056 }
1057
1058 if(LogData.warnings != EXPECTED_WARNINGS) {
1059 fprintf(stderr, "%s: Serialising to RDF/XML returned %d warnings, expected %d\n", program,
1060 LogData.warnings, EXPECTED_WARNINGS);
1061 return 1;
1062 }
1063
1064
1065 /* Good model to serialize */
1066 storage=librdf_new_storage(world, NULL, NULL, NULL);
1067 model=librdf_new_model(world, storage, NULL);
1068
1069 parser=librdf_new_parser(world, SYNTAX_TYPE, NULL, NULL);
1070 if(!parser) {
1071 fprintf(stderr, "%s: Failed to create new parser type %s\n", program,
1072 SYNTAX_TYPE);
1073 return 1;
1074 }
1075
1076 fprintf(stderr, "%s: Adding %s string content\n", program, SYNTAX_TYPE);
1077 if(librdf_parser_parse_string_into_model(parser,
1078 (const unsigned char*)SYNTAX_CONTENT,
1079 NULL /* no base URI*/,
1080 model)) {
1081 fprintf(stderr, "%s: Failed to parse RDF from %s string into model\n",
1082 SYNTAX_TYPE, program);
1083 return 1;
1084 }
1085 librdf_free_parser(parser);
1086
1087
1088 fprintf(stderr, "%s: Serializing stream to a string\n", program);
1089
1090 stream=librdf_model_as_stream(model);
1091 string_length=0;
1092 string=librdf_serializer_serialize_stream_to_counted_string(serializer,
1093 NULL, stream,
1094 &string_length);
1095 #define EXPECTED_GOOD_STRING_LENGTH 668
1096 if(string_length != EXPECTED_GOOD_STRING_LENGTH) {
1097 fprintf(stderr, "%s: Serialising stream to RDF/XML returned string '%s' size %d, expected %d\n", program, string,
1098 (int)string_length, EXPECTED_GOOD_STRING_LENGTH);
1099 return 1;
1100 }
1101 librdf_free_stream(stream);
1102
1103 librdf_free_memory(string);
1104
1105
1106 fprintf(stderr, "%s: Serializing stream to a file handle\n", program);
1107
1108 stream=librdf_model_as_stream(model);
1109
1110 #define FILENAME "test.rdf"
1111 fh=fopen(FILENAME, "w");
1112 if(!fh) {
1113 fprintf(stderr, "%s: Failed to fopen for writing '%s' - %s\n",
1114 program, FILENAME, strerror(errno));
1115 return 1;
1116 }
1117 librdf_serializer_serialize_stream_to_file_handle(serializer, fh, NULL,
1118 stream);
1119 fclose(fh);
1120 stat(FILENAME, &st_buf);
1121
1122 if((int)st_buf.st_size != EXPECTED_GOOD_STRING_LENGTH) {
1123 fprintf(stderr, "%s: Serialising stream to file handle returned file '%s' of size %d bytes, expected %d\n", program, FILENAME, (int)st_buf.st_size,
1124 EXPECTED_GOOD_STRING_LENGTH);
1125 return 1;
1126 }
1127 unlink(FILENAME);
1128
1129 librdf_free_stream(stream);
1130
1131
1132 librdf_free_serializer(serializer); serializer=NULL;
1133 librdf_free_model(model); model=NULL;
1134 librdf_free_storage(storage); storage=NULL;
1135
1136
1137 librdf_free_world(world);
1138
1139 /* keep gcc -Wall happy */
1140 return(0);
1141 }
1142
1143 #endif
1144