1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * rdf_term.c - RDF Term (RDF URI, Literal, Blank Node) Interface
4 *
5 * Copyright (C) 2010-2011, 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 <rdf_config.h>
27 #endif
28
29 #ifdef WIN32
30 #include <win32_rdf_config.h>
31 #endif
32
33 #include <stdio.h>
34 #include <string.h>
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38
39 #include <redland.h>
40 /* needed for utf8 functions and definition of 'byte' */
41 #include <rdf_utf8.h>
42
43
44
45 #ifndef STANDALONE
46
47 /**
48 * librdf_init_node:
49 * @world: redland world object
50 *
51 * INTERNAL - Initialise the node module.
52 *
53 **/
54 void
librdf_init_node(librdf_world * world)55 librdf_init_node(librdf_world* world)
56 {
57 }
58
59
60 /**
61 * librdf_finish_node:
62 * @world: redland world object
63 *
64 * INTERNAL - Terminate the node module.
65 *
66 **/
67 void
librdf_finish_node(librdf_world * world)68 librdf_finish_node(librdf_world* world)
69 {
70 }
71
72
73 /* constructors */
74
75 /**
76 * librdf_new_node:
77 * @world: redland world object
78 *
79 * Constructor - create a new #librdf_node object with a private identifier.
80 *
81 * Calls librdf_new_node_from_blank_identifier(world, NULL) to
82 * construct a new redland blank node identifier and make a
83 * new librdf_node object for it.
84 *
85 * Return value: a new #librdf_node object or NULL on failure
86 **/
87 librdf_node*
librdf_new_node(librdf_world * world)88 librdf_new_node(librdf_world *world)
89 {
90 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
91
92 librdf_world_open(world);
93
94 return librdf_new_node_from_blank_identifier(world, (unsigned char*)NULL);
95 }
96
97
98 /**
99 * librdf_new_node_from_uri_string:
100 * @world: redland world object
101 * @uri_string: string representing a URI
102 *
103 * Constructor - create a new #librdf_node object from a URI string.
104 *
105 * Return value: a new #librdf_node object or NULL on failure
106 **/
107 librdf_node*
librdf_new_node_from_uri_string(librdf_world * world,const unsigned char * uri_string)108 librdf_new_node_from_uri_string(librdf_world *world,
109 const unsigned char *uri_string)
110 {
111 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
112
113 librdf_world_open(world);
114
115 return raptor_new_term_from_uri_string(world->raptor_world_ptr, uri_string);
116 }
117
118
119 /**
120 * librdf_new_node_from_counted_uri_string:
121 * @world: redland world object
122 * @uri_string: string representing a URI
123 * @len: length of string
124 *
125 * Constructor - create a new #librdf_node object from a counted URI string.
126 *
127 * Return value: a new #librdf_node object or NULL on failure
128 **/
129 librdf_node*
librdf_new_node_from_counted_uri_string(librdf_world * world,const unsigned char * uri_string,size_t len)130 librdf_new_node_from_counted_uri_string(librdf_world *world,
131 const unsigned char *uri_string,
132 size_t len)
133 {
134 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
135
136 librdf_world_open(world);
137
138 return raptor_new_term_from_counted_uri_string(world->raptor_world_ptr,
139 uri_string, len);
140 }
141
142
143 /* Create a new (Resource) Node and set the URI. */
144
145 /**
146 * librdf_new_node_from_uri:
147 * @world: redland world object
148 * @uri: #librdf_uri object
149 *
150 * Constructor - create a new resource #librdf_node object with a given URI.
151 *
152 * Return value: a new #librdf_node object or NULL on failure
153 **/
154 librdf_node*
librdf_new_node_from_uri(librdf_world * world,librdf_uri * uri)155 librdf_new_node_from_uri(librdf_world *world, librdf_uri *uri)
156 {
157 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
158
159 librdf_world_open(world);
160
161 return raptor_new_term_from_uri(world->raptor_world_ptr, uri);
162 }
163
164
165 /**
166 * librdf_new_node_from_uri_local_name:
167 * @world: redland world object
168 * @uri: #librdf_uri object
169 * @local_name: local name to append to URI
170 *
171 * Constructor - create a new resource #librdf_node object with a given URI and local name.
172 *
173 * Return value: a new #librdf_node object or NULL on failure
174 **/
175 librdf_node*
librdf_new_node_from_uri_local_name(librdf_world * world,librdf_uri * uri,const unsigned char * local_name)176 librdf_new_node_from_uri_local_name(librdf_world *world,
177 librdf_uri *uri,
178 const unsigned char *local_name)
179 {
180 raptor_uri *new_uri;
181 librdf_node* node;
182
183 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
184
185 librdf_world_open(world);
186
187 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(uri, raptor_uri, NULL);
188 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(local_name, string, NULL);
189
190 new_uri = raptor_new_uri_from_uri_local_name(world->raptor_world_ptr,
191 uri, local_name);
192 if(!new_uri)
193 return NULL;
194
195 node = raptor_new_term_from_uri(world->raptor_world_ptr, new_uri);
196 raptor_free_uri(new_uri);
197 return node;
198 }
199
200
201 /**
202 * librdf_new_node_from_normalised_uri_string:
203 * @world: redland world object
204 * @uri_string: UTF-8 encoded string representing a URI
205 * @source_uri: source URI
206 * @base_uri: base URI
207 *
208 * Constructor - create a new #librdf_node object from a UTF-8 encoded URI string normalised to a new base URI.
209 *
210 * Return value: a new #librdf_node object or NULL on failure
211 **/
212 librdf_node*
librdf_new_node_from_normalised_uri_string(librdf_world * world,const unsigned char * uri_string,librdf_uri * source_uri,librdf_uri * base_uri)213 librdf_new_node_from_normalised_uri_string(librdf_world *world,
214 const unsigned char *uri_string,
215 librdf_uri *source_uri,
216 librdf_uri *base_uri)
217 {
218 librdf_uri* new_uri;
219 librdf_node* node;
220
221 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
222
223 librdf_world_open(world);
224
225 new_uri = librdf_new_uri_normalised_to_base(uri_string,
226 source_uri, base_uri);
227 if(!new_uri)
228 return NULL;
229
230 node = raptor_new_term_from_uri(world->raptor_world_ptr, new_uri);
231 raptor_free_uri(new_uri);
232 return node;
233 }
234
235
236 #define LIBRDF_XSD_BOOLEAN_TRUE (const unsigned char*)"true"
237 #define LIBRDF_XSD_BOOLEAN_TRUE_LEN 4
238 #define LIBRDF_XSD_BOOLEAN_FALSE (const unsigned char*)"false"
239 #define LIBRDF_XSD_BOOLEAN_FALSE_LEN 5
240
241 static int
librdf_xsd_boolean_value_from_string(const unsigned char * string,unsigned int len)242 librdf_xsd_boolean_value_from_string(const unsigned char* string,
243 unsigned int len)
244 {
245 int integer = 0;
246
247 /* FIXME
248 * Strictly only {true, false, 1, 0} are allowed according to
249 * http://www.w3.org/TR/xmlschema-2/#boolean
250 */
251 if((len == LIBRDF_XSD_BOOLEAN_TRUE_LEN &&
252 (!strcmp(LIBRDF_GOOD_CAST(const char*, string), "true") ||
253 !strcmp(LIBRDF_GOOD_CAST(const char*, string), "TRUE"))
254 )
255 ||
256 (len == 1 &&
257 !strcmp(LIBRDF_GOOD_CAST(const char*, string), "1")
258 )
259 )
260 integer = 1;
261
262 return integer;
263 }
264
265
266 /*
267 * librdf_node_normalize:
268 * @world: world
269 * @node: node
270 *
271 * INTERNAL - Normalize the literal of datatyped literals to canonical form
272 *
273 * Currently handles xsd:boolean.
274 *
275 * FIXME: This should be in Raptor or Rasqal since
276 * librdf_xsd_boolean_value_from_string and the canonicalization was
277 * ripped out of Rasqal.
278 *
279 * Return value: new node (or same one if no action was taken)
280 */
281 static librdf_node*
librdf_node_normalize(librdf_world * world,librdf_node * node)282 librdf_node_normalize(librdf_world* world, librdf_node* node)
283 {
284 if(!node)
285 return NULL;
286
287 if(node->value.literal.datatype) {
288 librdf_uri* dt_uri;
289
290 dt_uri = librdf_new_uri_from_uri_local_name(world->xsd_namespace_uri,
291 LIBRDF_GOOD_CAST(const unsigned char*, "boolean"));
292 if(raptor_uri_equals(node->value.literal.datatype, dt_uri)) {
293 const unsigned char* value;
294 size_t value_len;
295 int bvalue;
296
297 bvalue = librdf_xsd_boolean_value_from_string(node->value.literal.string,
298 node->value.literal.string_len);
299
300 value = bvalue ? LIBRDF_XSD_BOOLEAN_TRUE :
301 LIBRDF_XSD_BOOLEAN_FALSE;
302 value_len = bvalue ? LIBRDF_XSD_BOOLEAN_TRUE_LEN :
303 LIBRDF_XSD_BOOLEAN_FALSE_LEN;
304
305 if(node->value.literal.string_len != value_len ||
306 strcmp(LIBRDF_GOOD_CAST(const char*, node->value.literal.string),
307 LIBRDF_GOOD_CAST(const char*, value))) {
308 /* If literal is not canonical, replace the node */
309 librdf_free_node(node);
310 node = NULL;
311
312 /* Have to use Raptor constructor here since
313 * librdf_new_node_from_typed_counted_literal() calls this
314 */
315 node = raptor_new_term_from_counted_literal(world->raptor_world_ptr,
316 value, value_len,
317 dt_uri,
318 (const unsigned char*)NULL,
319 (unsigned char)0);
320 }
321 }
322
323 if(dt_uri)
324 librdf_free_uri(dt_uri);
325 }
326
327 return node;
328 }
329
330
331 /**
332 * librdf_new_node_from_literal:
333 * @world: redland world object
334 * @string: literal UTF-8 encoded string value
335 * @xml_language: literal XML language (or NULL, empty string)
336 * @is_wf_xml: non 0 if literal is XML
337 *
338 * Constructor - create a new literal #librdf_node object.
339 *
340 * 0.9.12: xml_space argument deleted
341 *
342 * An @xml_language cannot be used when @is_wf_xml is non-0. If both
343 * are given, NULL is returned. If @xml_language is the empty string,
344 * it is the equivalent to NULL.
345 *
346 * Return value: new #librdf_node object or NULL on failure
347 **/
348 librdf_node*
librdf_new_node_from_literal(librdf_world * world,const unsigned char * string,const char * xml_language,int is_wf_xml)349 librdf_new_node_from_literal(librdf_world *world,
350 const unsigned char *string,
351 const char *xml_language,
352 int is_wf_xml)
353 {
354 librdf_uri* datatype_uri;
355 librdf_node* n;
356
357 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
358
359 librdf_world_open(world);
360
361 datatype_uri = (is_wf_xml ? LIBRDF_RS_XMLLiteral_URI(world) : NULL);
362
363 n = raptor_new_term_from_literal(world->raptor_world_ptr,
364 string, datatype_uri,
365 (const unsigned char*)xml_language);
366 return librdf_node_normalize(world, n);
367 }
368
369
370 /**
371 * librdf_new_node_from_typed_literal:
372 * @world: redland world object
373 * @value: literal UTF-8 encoded string value
374 * @xml_language: literal XML language (or NULL, empty string)
375 * @datatype_uri: URI of typed literal datatype or NULL
376 *
377 * Constructor - create a new typed literal #librdf_node object.
378 *
379 * Only one of @xml_language or @datatype_uri may be given. If both
380 * are given, NULL is returned. If @xml_language is the empty string,
381 * it is the equivalent to NULL.
382 *
383 * Return value: new #librdf_node object or NULL on failure
384 **/
385 librdf_node*
librdf_new_node_from_typed_literal(librdf_world * world,const unsigned char * value,const char * xml_language,librdf_uri * datatype_uri)386 librdf_new_node_from_typed_literal(librdf_world *world,
387 const unsigned char *value,
388 const char *xml_language,
389 librdf_uri *datatype_uri)
390 {
391 librdf_node* n;
392
393 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
394
395 librdf_world_open(world);
396
397 n = raptor_new_term_from_literal(world->raptor_world_ptr,
398 value, datatype_uri,
399 (const unsigned char*)xml_language);
400 return librdf_node_normalize(world, n);
401 }
402
403
404 /**
405 * librdf_new_node_from_typed_counted_literal:
406 * @world: redland world object
407 * @value: literal UTF-8 encoded string value
408 * @value_len: literal string value length
409 * @xml_language: literal XML language (or NULL, empty string)
410 * @xml_language_len: literal XML language length (not used if @xml_language is NULL)
411 * @datatype_uri: URI of typed literal datatype or NULL
412 *
413 * Constructor - create a new typed literal #librdf_node object.
414 *
415 * Takes copies of the passed in @value, @datatype_uri and @xml_language.
416 *
417 * Only one of @xml_language or @datatype_uri may be given. If both
418 * are given, NULL is returned. If @xml_language is the empty string,
419 * it is the equivalent to NULL.
420 *
421 * Return value: new #librdf_node object or NULL on failure
422 **/
423 librdf_node*
librdf_new_node_from_typed_counted_literal(librdf_world * world,const unsigned char * value,size_t value_len,const char * xml_language,size_t xml_language_len,librdf_uri * datatype_uri)424 librdf_new_node_from_typed_counted_literal(librdf_world *world,
425 const unsigned char *value,
426 size_t value_len,
427 const char *xml_language,
428 size_t xml_language_len,
429 librdf_uri *datatype_uri)
430 {
431 librdf_node* n;
432
433 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
434
435 librdf_world_open(world);
436
437 n = raptor_new_term_from_counted_literal(world->raptor_world_ptr,
438 value, value_len,
439 datatype_uri,
440 (const unsigned char*)xml_language,
441 (unsigned char)xml_language_len);
442 return librdf_node_normalize(world, n);
443 }
444
445
446 /**
447 * librdf_new_node_from_counted_blank_identifier:
448 * @world: redland world object
449 * @identifier: UTF-8 encoded blank node identifier or NULL
450 * @identifier_len: length of @identifier
451 *
452 * Constructor - create a new blank node #librdf_node object from a blank node counted length identifier.
453 *
454 * If no @identifier string is given (NULL) this creates a new
455 * internal identifier and uses it.
456 *
457 * Return value: new #librdf_node object or NULL on failure
458 **/
459 librdf_node*
librdf_new_node_from_counted_blank_identifier(librdf_world * world,const unsigned char * identifier,size_t identifier_len)460 librdf_new_node_from_counted_blank_identifier(librdf_world *world,
461 const unsigned char *identifier,
462 size_t identifier_len)
463 {
464 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
465
466 librdf_world_open(world);
467
468 return raptor_new_term_from_counted_blank(world->raptor_world_ptr,
469 identifier, identifier_len);
470 }
471
472
473 /**
474 * librdf_new_node_from_blank_identifier:
475 * @world: redland world object
476 * @identifier: UTF-8 encoded blank node identifier or NULL
477 *
478 * Constructor - create a new blank node #librdf_node object from a blank node identifier.
479 *
480 * If no @identifier string is given (NULL) this creates a new
481 * internal identifier and uses it.
482 *
483 * Return value: new #librdf_node object or NULL on failure
484 **/
485 librdf_node*
librdf_new_node_from_blank_identifier(librdf_world * world,const unsigned char * identifier)486 librdf_new_node_from_blank_identifier(librdf_world *world,
487 const unsigned char *identifier)
488 {
489 const unsigned char *blank = identifier;
490 librdf_node* node = NULL;
491
492 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
493
494 librdf_world_open(world);
495
496 if(!identifier)
497 blank = librdf_world_get_genid(world);
498
499 node = raptor_new_term_from_blank(world->raptor_world_ptr, blank);
500
501 if(!identifier)
502 LIBRDF_FREE(char*, (char*)blank);
503
504 return node;
505 }
506
507
508 /**
509 * librdf_new_node_from_node:
510 * @node: #librdf_node object to copy
511 *
512 * Copy constructor - create a new librdf_node object from an existing librdf_node object.
513 *
514 * Return value: a new #librdf_node object or NULL on failure
515 **/
516 librdf_node*
librdf_new_node_from_node(librdf_node * node)517 librdf_new_node_from_node(librdf_node *node)
518 {
519 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
520
521 return raptor_term_copy(node);
522 }
523
524
525 /**
526 * librdf_free_node:
527 * @node: #librdf_node object
528 *
529 * Destructor - destroy an #librdf_node object.
530 *
531 **/
532 void
librdf_free_node(librdf_node * node)533 librdf_free_node(librdf_node *node)
534 {
535 if(!node)
536 return;
537
538 raptor_free_term(node);
539 }
540
541
542 /* functions / methods */
543
544 /**
545 * librdf_node_get_uri:
546 * @node: the node object
547 *
548 * Get the URI for a node object.
549 *
550 * Returns a pointer to the URI object held by the node, it must be
551 * copied if it is wanted to be used by the caller.
552 *
553 * Return value: URI object or NULL if node has no URI.
554 **/
555 librdf_uri*
librdf_node_get_uri(librdf_node * node)556 librdf_node_get_uri(librdf_node *node)
557 {
558 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
559
560 if(node->type != RAPTOR_TERM_TYPE_URI)
561 return NULL;
562
563 return node->value.uri;
564 }
565
566
567 /**
568 * librdf_node_get_type:
569 * @node: the node object
570 *
571 * Get the type of the node.
572 *
573 * See also librdf_node_is_resource(), librdf_node_is_literal() and
574 * librdf_node_is_blank() for testing individual types.
575 *
576 * Return value: the node type
577 **/
578 librdf_node_type
librdf_node_get_type(librdf_node * node)579 librdf_node_get_type(librdf_node *node)
580 {
581 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, LIBRDF_NODE_TYPE_UNKNOWN);
582
583 return (librdf_node_type)node->type;
584 }
585
586
587 /**
588 * librdf_node_get_literal_value:
589 * @node: the node object
590 *
591 * Get the literal value of the node as a UTF-8 encoded string.
592 *
593 * Returns a pointer to the UTF-8 encoded literal value held by the
594 * node, it must be copied if it is wanted to be used by the caller.
595 *
596 * Return value: the UTF-8 encoded literal string or NULL if node is not a literal
597 **/
598 unsigned char*
librdf_node_get_literal_value(librdf_node * node)599 librdf_node_get_literal_value(librdf_node *node)
600 {
601 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
602
603 if(node->type != RAPTOR_TERM_TYPE_LITERAL)
604 return NULL;
605
606 return node->value.literal.string;
607 }
608
609
610 /**
611 * librdf_node_get_literal_value_as_counted_string:
612 * @node: the node object
613 * @len_p: pointer to location to store the string length (or NULL)
614 *
615 * Get the literal value of the node as a counted UTF-8 encoded string.
616 *
617 * Returns a pointer to the UTF-8 encoded literal string value held
618 * by the node, it must be copied if it is wanted to be used by the
619 * caller.
620 *
621 * Return value: the UTF-8 encoded literal string or NULL if node is not a literal
622 **/
623 unsigned char*
librdf_node_get_literal_value_as_counted_string(librdf_node * node,size_t * len_p)624 librdf_node_get_literal_value_as_counted_string(librdf_node *node,
625 size_t *len_p)
626 {
627 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
628
629 if(node->type != RAPTOR_TERM_TYPE_LITERAL)
630 return NULL;
631
632 if(len_p)
633 *len_p = node->value.literal.string_len;
634
635 return node->value.literal.string;
636 }
637
638
639 /**
640 * librdf_node_get_literal_value_as_latin1:
641 * @node: the node object
642 *
643 * Get the string literal value of the node as ISO Latin-1.
644 *
645 * Returns a newly allocated string containing the conversion of the
646 * node literal value held by the node into ISO Latin-1. Discards
647 * characters outside the U+0000 to U+00FF range (inclusive).
648 *
649 * Return value: the Latin-1 literal string or NULL if node is not a literal
650 **/
651 char*
librdf_node_get_literal_value_as_latin1(librdf_node * node)652 librdf_node_get_literal_value_as_latin1(librdf_node *node)
653 {
654 size_t slen;
655 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
656
657 if(node->type != RAPTOR_TERM_TYPE_LITERAL)
658 return NULL;
659
660 if(!node->value.literal.string)
661 return NULL;
662
663 slen = LIBRDF_GOOD_CAST(size_t, node->value.literal.string_len);
664 return (char*)librdf_utf8_to_latin1_2((const unsigned char*)node->value.literal.string,
665 slen, '\0', NULL);
666 }
667
668
669 /**
670 * librdf_node_get_literal_value_language:
671 * @node: the node object
672 *
673 * Get the XML language of the node.
674 *
675 * Returns a pointer to the literal language value held by the node,
676 * it must be copied if it is wanted to be used by the caller.
677 * Language strings are ASCII, not UTF-8 encoded Unicode.
678 *
679 * Return value: the XML language string or NULL if node is not a literal
680 * or there is no XML language defined.
681 **/
682 char*
librdf_node_get_literal_value_language(librdf_node * node)683 librdf_node_get_literal_value_language(librdf_node *node)
684 {
685 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
686
687 if(node->type != RAPTOR_TERM_TYPE_LITERAL)
688 return NULL;
689
690 return (char*)node->value.literal.language;
691 }
692
693
694 /**
695 * librdf_node_get_literal_value_is_wf_xml:
696 * @node: the node object
697 *
698 * Get the XML well-formness property of the node.
699 *
700 * Return value: 0 if the XML literal is NOT well formed XML content, or the node is not a literal
701 **/
702 int
librdf_node_get_literal_value_is_wf_xml(librdf_node * node)703 librdf_node_get_literal_value_is_wf_xml(librdf_node *node)
704 {
705 raptor_uri* rdf_xml_literal_uri;
706 int rc;
707
708 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0);
709
710 if(node->type != RAPTOR_TERM_TYPE_LITERAL)
711 return 0;
712
713 if(!node->value.literal.datatype)
714 return 0;
715
716 rdf_xml_literal_uri = raptor_new_uri_for_rdf_concept(node->world,
717 (const unsigned char *)"XMLLiteral");
718
719 rc = librdf_uri_equals(node->value.literal.datatype, rdf_xml_literal_uri);
720 raptor_free_uri(rdf_xml_literal_uri);
721
722 return rc;
723 }
724
725
726 /**
727 * librdf_node_get_literal_value_datatype_uri:
728 * @node: the node object
729 *
730 * Get the typed literal datatype URI of the literal node.
731 *
732 * Return value: shared URI of the datatyped literal or NULL if the node is not a literal, or has no datatype URI
733 **/
734 librdf_uri*
librdf_node_get_literal_value_datatype_uri(librdf_node * node)735 librdf_node_get_literal_value_datatype_uri(librdf_node *node)
736 {
737 if(node->type != RAPTOR_TERM_TYPE_LITERAL)
738 return NULL;
739
740 return node->value.literal.datatype;
741 }
742
743
744 /**
745 * librdf_node_get_li_ordinal:
746 * @node: the node object
747 *
748 * Get the node li object ordinal value.
749 *
750 * Return value: the li ordinal value or < 1 on failure
751 **/
752 int
librdf_node_get_li_ordinal(librdf_node * node)753 librdf_node_get_li_ordinal(librdf_node *node)
754 {
755 unsigned char *uri_string;
756
757 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0);
758
759 if(node->type != RAPTOR_TERM_TYPE_URI)
760 return -1;
761
762 uri_string = raptor_uri_as_string(node->value.uri);
763 if(strncmp((const char*)uri_string,
764 (const char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#_", 44))
765 return -1;
766
767 return atoi((const char*)uri_string+44);
768 }
769
770
771 /**
772 * librdf_node_get_blank_identifier:
773 * @node: the node object
774 *
775 * Get the blank node identifier as a UTF-8 encoded string.
776 *
777 * Return value: the UTF-8 encoded blank node identifier value or NULL on failure
778 **/
779 unsigned char*
librdf_node_get_blank_identifier(librdf_node * node)780 librdf_node_get_blank_identifier(librdf_node *node)
781 {
782 return node->value.blank.string;
783 }
784
785
786 /**
787 * librdf_node_get_counted_blank_identifier:
788 * @node: the node object
789 * @len_p: pointer to variable to store length (or NULL)
790 *
791 * Get the blank node identifier as a counted UTF-8 encoded string.
792 *
793 * Return value: the UTF-8 encoded blank node identifier value or NULL on failure
794 **/
795 unsigned char*
librdf_node_get_counted_blank_identifier(librdf_node * node,size_t * len_p)796 librdf_node_get_counted_blank_identifier(librdf_node* node, size_t* len_p)
797 {
798 if(len_p)
799 *len_p = node->value.blank.string_len;
800 return node->value.blank.string;
801 }
802
803
804 /**
805 * librdf_node_is_resource:
806 * @node: the node object
807 *
808 * Check node is a resource.
809 *
810 * Return value: non-zero if the node is a resource (URI)
811 **/
812 int
librdf_node_is_resource(librdf_node * node)813 librdf_node_is_resource(librdf_node *node)
814 {
815 return (node->type == RAPTOR_TERM_TYPE_URI);
816 }
817
818
819 /**
820 * librdf_node_is_literal:
821 * @node: the node object
822 *
823 * Check node is a literal.
824 *
825 * Return value: non-zero if the node is a literal
826 **/
827 int
librdf_node_is_literal(librdf_node * node)828 librdf_node_is_literal(librdf_node *node)
829 {
830 return (node->type == RAPTOR_TERM_TYPE_LITERAL);
831 }
832
833
834 /**
835 * librdf_node_is_blank:
836 * @node: the node object
837 *
838 * Check node is a blank nodeID.
839 *
840 * Return value: non-zero if the node is a blank nodeID
841 **/
842 int
librdf_node_is_blank(librdf_node * node)843 librdf_node_is_blank(librdf_node *node)
844 {
845 return (node->type == RAPTOR_TERM_TYPE_BLANK);
846 }
847
848
849 /**
850 * librdf_node_encode:
851 * @node: the node to serialise
852 * @buffer: the buffer to use
853 * @length: buffer size
854 *
855 * Serialise a node into a buffer.
856 *
857 * Encodes the given node in the buffer, which must be of sufficient
858 * size. If buffer is NULL, no work is done but the size of buffer
859 * required is returned.
860 *
861 * If the node cannot be encoded due to restrictions of the encoding
862 * format, a redland error is generated
863 *
864 * Return value: the number of bytes written or 0 on failure.
865 **/
866 size_t
librdf_node_encode(librdf_node * node,unsigned char * buffer,size_t length)867 librdf_node_encode(librdf_node *node,
868 unsigned char *buffer, size_t length)
869 {
870 size_t total_length = 0;
871 unsigned char *string;
872 size_t string_length;
873 size_t language_length = 0;
874 unsigned char *datatype_uri_string = NULL;
875 size_t datatype_uri_length = 0;
876
877 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0);
878
879 switch(node->type) {
880 case RAPTOR_TERM_TYPE_URI:
881 string = (unsigned char*)librdf_uri_as_counted_string(node->value.uri,
882 &string_length);
883
884 total_length = 3 + string_length + 1; /* +1 for \0 at end */
885
886 if(length && total_length > length)
887 return 0;
888
889 if(string_length > 0xFFFF)
890 return 0;
891
892 if(buffer) {
893 buffer[0] = 'R';
894 buffer[1] = (string_length & 0xff00) >> 8;
895 buffer[2] = (string_length & 0x00ff);
896 memcpy((char*)buffer + 3, string, string_length + 1);
897 }
898 break;
899
900 case RAPTOR_TERM_TYPE_LITERAL:
901 string = (unsigned char*)node->value.literal.string;
902 string_length = node->value.literal.string_len;
903 if(node->value.literal.language)
904 language_length = LIBRDF_GOOD_CAST(size_t, node->value.literal.language_len);
905
906 if(node->value.literal.datatype) {
907 datatype_uri_string = librdf_uri_as_counted_string(node->value.literal.datatype, &datatype_uri_length);
908 }
909
910 total_length = 6 + string_length + 1; /* +1 for \0 at end */
911 if(string_length > 0xFFFF) /* for long literal - type 'N' */
912 total_length += 2;
913
914 if(language_length)
915 total_length += language_length + 1;
916
917 if(datatype_uri_length)
918 total_length += datatype_uri_length + 1;
919
920 if(length && total_length > length)
921 return 0;
922
923 if(datatype_uri_length > 0xFFFF)
924 return 0;
925
926
927 if(buffer) {
928 if(string_length > 0xFFFF) {
929 /* long literal type N (string length > 0x10000) */
930 buffer[0] = 'N';
931 buffer[1] = (string_length & 0xff000000) >> 24;
932 buffer[2] = (string_length & 0x00ff0000) >> 16;
933 buffer[3] = (string_length & 0x0000ff00) >> 8;
934 buffer[4] = (string_length & 0x000000ff);
935 buffer[5] = (datatype_uri_length & 0xff00) >> 8;
936 buffer[6] = (datatype_uri_length & 0x00ff);
937 buffer[7] = (language_length & 0x00ff);
938 buffer += 8;
939 } else {
940 /* short literal type M (string length <= 0xFFFF) */
941 buffer[0] = 'M';
942 buffer[1] = (string_length & 0xff00) >> 8;
943 buffer[2] = (string_length & 0x00ff);
944 buffer[3] = (datatype_uri_length & 0xff00) >> 8;
945 buffer[4] = (datatype_uri_length & 0x00ff);
946 buffer[5] = (language_length & 0x00ff);
947 buffer += 6;
948 }
949 memcpy(buffer, string, string_length + 1);
950 buffer += string_length + 1;
951
952 if(datatype_uri_length) {
953 memcpy(buffer, datatype_uri_string, datatype_uri_length + 1);
954 buffer += datatype_uri_length + 1;
955 }
956
957 if(language_length)
958 memcpy(buffer, node->value.literal.language, language_length + 1);
959 } /* end if buffer */
960
961 break;
962
963 case RAPTOR_TERM_TYPE_BLANK:
964 string = (unsigned char*)node->value.blank.string;
965 string_length = node->value.blank.string_len;
966
967 total_length = 3 + string_length + 1; /* +1 for \0 at end */
968
969 if(length && total_length > length)
970 return 0;
971
972 if(string_length > 0xFFFF)
973 return 0;
974
975 if(buffer) {
976 buffer[0] = 'B';
977 buffer[1] = (string_length & 0xff00) >> 8;
978 buffer[2] = (string_length & 0x00ff);
979 memcpy((char*)buffer + 3, string, string_length + 1);
980 }
981 break;
982
983 case RAPTOR_TERM_TYPE_UNKNOWN:
984 default:
985 return 0;
986 }
987
988 return total_length;
989 }
990
991
992 /**
993 * librdf_node_decode:
994 * @world: librdf_world
995 * @size_p: pointer to bytes used or NULL
996 * @buffer: the buffer to use
997 * @length: buffer size
998 *
999 * Deserialise a node from a buffer.
1000 *
1001 * Decodes the serialised node (as created by librdf_node_encode() )
1002 * from the given buffer.
1003 *
1004 * Return value: new node or NULL on failure (bad encoding, allocation failure)
1005 **/
1006 librdf_node*
librdf_node_decode(librdf_world * world,size_t * size_p,unsigned char * buffer,size_t length)1007 librdf_node_decode(librdf_world *world, size_t *size_p,
1008 unsigned char *buffer, size_t length)
1009 {
1010 int is_wf_xml;
1011 size_t string_length;
1012 size_t total_length;
1013 size_t language_length;
1014 unsigned char *datatype_uri_string = NULL;
1015 size_t datatype_uri_length;
1016 librdf_uri* datatype_uri = NULL;
1017 unsigned char *language = NULL;
1018 int status = 0;
1019 librdf_node* node = NULL;
1020
1021 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, librdf_world, NULL);
1022
1023 librdf_world_open(world);
1024
1025 /* absolute minimum - first byte is type */
1026 if (length < 1)
1027 return NULL;
1028
1029 switch(buffer[0]) {
1030 case 'R': /* URI / Resource */
1031 /* min */
1032 if(length < 3)
1033 return NULL;
1034
1035 string_length = LIBRDF_GOOD_CAST(size_t, (buffer[1] << 8) | buffer[2]);
1036 total_length = 3 + string_length + 1;
1037
1038 node = librdf_new_node_from_uri_string(world, buffer + 3);
1039
1040 break;
1041
1042 case 'L': /* Old encoding form for Literal */
1043 /* min */
1044 if(length < 6)
1045 return NULL;
1046
1047 is_wf_xml = (buffer[1] & 0xf0)>>8;
1048 string_length = LIBRDF_GOOD_CAST(size_t, (buffer[2] << 8) | buffer[3]);
1049 language_length = LIBRDF_GOOD_CAST(size_t, buffer[5]);
1050
1051 total_length = 6 + string_length + 1; /* +1 for \0 at end */
1052 if(language_length) {
1053 language = buffer + total_length;
1054 total_length += language_length + 1;
1055 }
1056
1057 node = librdf_new_node_from_typed_counted_literal(world,
1058 buffer + 6,
1059 string_length,
1060 (const char*)language,
1061 LIBRDF_GOOD_CAST(unsigned char, language_length),
1062 is_wf_xml ? LIBRDF_RS_XMLLiteral_URI(world) : NULL);
1063
1064 break;
1065
1066 case 'M': /* Literal for Redland 0.9.12+ */
1067 /* min */
1068 if(length < 6)
1069 return NULL;
1070
1071 string_length = LIBRDF_GOOD_CAST(size_t, (buffer[1] << 8) | buffer[2]);
1072 datatype_uri_length = LIBRDF_GOOD_CAST(size_t, (buffer[3] << 8) | buffer[4]);
1073 language_length = buffer[5];
1074
1075 total_length = 6 + string_length + 1; /* +1 for \0 at end */
1076 if(datatype_uri_length) {
1077 datatype_uri_string = buffer + total_length;
1078 total_length += datatype_uri_length + 1;
1079 }
1080 if(language_length) {
1081 language = buffer + total_length;
1082 total_length += language_length + 1;
1083 }
1084
1085 if(datatype_uri_string)
1086 datatype_uri = librdf_new_uri(world, datatype_uri_string);
1087
1088 node = librdf_new_node_from_typed_counted_literal(world,
1089 buffer + 6,
1090 string_length,
1091 (const char*)language,
1092 LIBRDF_GOOD_CAST(unsigned char, language_length),
1093 datatype_uri);
1094 if(datatype_uri)
1095 librdf_free_uri(datatype_uri);
1096
1097 if(status)
1098 return NULL;
1099
1100 break;
1101
1102 case 'N': /* Literal for redland 1.0.5+ (long literal) */
1103 /* min */
1104 if(length < 8)
1105 return NULL;
1106
1107 string_length = LIBRDF_GOOD_CAST(size_t, (buffer[1] << 24) | (buffer[2] << 16) | (buffer[3] << 8) | buffer[4]);
1108 datatype_uri_length = LIBRDF_GOOD_CAST(size_t, (buffer[5] << 8) | buffer[6]);
1109 language_length = buffer[7];
1110
1111 total_length = 8 + string_length + 1; /* +1 for \0 at end */
1112 if(datatype_uri_length) {
1113 datatype_uri_string = buffer + total_length;
1114 total_length += datatype_uri_length + 1;
1115 }
1116 if(language_length) {
1117 language = buffer + total_length;
1118 total_length += language_length + 1;
1119 }
1120
1121 if(datatype_uri_string)
1122 datatype_uri = librdf_new_uri(world, datatype_uri_string);
1123
1124 node = librdf_new_node_from_typed_counted_literal(world,
1125 buffer + 8,
1126 string_length,
1127 (const char*)language,
1128 LIBRDF_GOOD_CAST(size_t, language_length),
1129 datatype_uri);
1130 if(datatype_uri)
1131 librdf_free_uri(datatype_uri);
1132
1133 if(status)
1134 return NULL;
1135
1136 break;
1137
1138 case 'B': /* RAPTOR_TERM_TYPE_BLANK */
1139 /* min */
1140 if(length < 3)
1141 return NULL;
1142
1143 string_length = LIBRDF_GOOD_CAST(size_t, (buffer[1] << 8) | buffer[2]);
1144
1145 total_length = 3 + string_length + 1; /* +1 for \0 at end */
1146
1147 node = librdf_new_node_from_blank_identifier(world, buffer+3);
1148
1149 break;
1150
1151 default:
1152 return NULL;
1153 }
1154
1155 if(size_p)
1156 *size_p = total_length;
1157
1158 return node;
1159 }
1160
1161
1162 #ifndef REDLAND_DISABLE_DEPRECATED
1163 /**
1164 * librdf_node_to_string:
1165 * @node: the node object
1166 *
1167 * Format the node as a string in a debugging format.
1168 *
1169 * Note a new string is allocated which must be freed by the caller.
1170 *
1171 * @Deprecated: Use librdf_node_write() to write to #raptor_iostream
1172 * which can be made to write to a string. Use a #librdf_serializer
1173 * to write proper syntax formats.
1174 *
1175 * Return value: a string value representing the node or NULL on failure
1176 **/
1177 unsigned char*
librdf_node_to_string(librdf_node * node)1178 librdf_node_to_string(librdf_node *node)
1179 {
1180 raptor_iostream* iostr;
1181 unsigned char *s;
1182 int rc;
1183
1184 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
1185
1186 iostr = raptor_new_iostream_to_string(node->world,
1187 (void**)&s, NULL, malloc);
1188 if(!iostr)
1189 return NULL;
1190
1191 rc = librdf_node_write(node, iostr);
1192 raptor_free_iostream(iostr);
1193 if(rc) {
1194 raptor_free_memory(s);
1195 s = NULL;
1196 }
1197
1198 return s;
1199 }
1200 #endif
1201
1202
1203 #ifndef REDLAND_DISABLE_DEPRECATED
1204 /**
1205 * librdf_node_to_counted_string:
1206 * @node: the node object
1207 * @len_p: pointer to location to store length
1208 *
1209 * Format the node as a counted string in a debugging format.
1210 *
1211 * Note a new string is allocated which must be freed by the caller.
1212 *
1213 * @Deprecated: Use librdf_node_write() to write to #raptor_iostream
1214 * which can be made to write to a string. Use a #librdf_serializer
1215 * to write proper syntax formats.
1216 *
1217 * Return value: a string value representing the node or NULL on failure
1218 **/
1219 unsigned char*
librdf_node_to_counted_string(librdf_node * node,size_t * len_p)1220 librdf_node_to_counted_string(librdf_node *node, size_t *len_p)
1221 {
1222 raptor_iostream* iostr;
1223 unsigned char *s;
1224 int rc;
1225
1226 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
1227
1228 iostr = raptor_new_iostream_to_string(node->world,
1229 (void**)&s, len_p, malloc);
1230 if(!iostr)
1231 return NULL;
1232
1233 rc = librdf_node_write(node, iostr);
1234 raptor_free_iostream(iostr);
1235
1236 if(rc) {
1237 raptor_free_memory(s);
1238 s = NULL;
1239 }
1240
1241 return s;
1242 }
1243 #endif
1244
1245
1246 /**
1247 * librdf_node_print:
1248 * @node: the node
1249 * @fh: file handle
1250 *
1251 * Pretty print the node to a file descriptor.
1252 *
1253 * This method is for debugging and the format of the output should
1254 * not be relied on.
1255 *
1256 **/
1257 void
librdf_node_print(librdf_node * node,FILE * fh)1258 librdf_node_print(librdf_node *node, FILE *fh)
1259 {
1260 raptor_iostream *iostr;
1261
1262 LIBRDF_ASSERT_OBJECT_POINTER_RETURN(node, librdf_node);
1263 LIBRDF_ASSERT_OBJECT_POINTER_RETURN(fh, FILE*);
1264
1265 if(!node)
1266 return;
1267
1268 iostr = raptor_new_iostream_to_file_handle(node->world, fh);
1269 if(!iostr)
1270 return;
1271
1272 librdf_node_write(node, iostr);
1273
1274 raptor_free_iostream(iostr);
1275 }
1276
1277
1278 /**
1279 * librdf_node_equals:
1280 * @first_node: first #librdf_node node
1281 * @second_node: second #librdf_node node
1282 *
1283 * Compare two librdf_node objects for equality.
1284 *
1285 * Note - for literal nodes, XML language, XML space and well-formness are
1286 * presently ignored in the comparison.
1287 *
1288 * Return value: non 0 if nodes are equal. 0 if not-equal or failure
1289 **/
1290 int
librdf_node_equals(librdf_node * first_node,librdf_node * second_node)1291 librdf_node_equals(librdf_node *first_node, librdf_node *second_node)
1292 {
1293 return raptor_term_equals(first_node, second_node);
1294 }
1295
1296
1297 /**
1298 * librdf_node_static_iterator_create:
1299 * @nodes: static array of #librdf_node objects
1300 * @size: size of array
1301 *
1302 * Create an iterator over an array of nodes (ALWAYS FAILS)
1303 *
1304 * This legacy method used to create an iterator for an existing
1305 * static array of librdf_node objects. It was intended for testing
1306 * iterator code.
1307 *
1308 * @deprecated: always returns NULL. Use
1309 * librdf_node_new_static_node_iterator()
1310 *
1311 * Return value: NULL
1312 **/
1313 librdf_iterator*
librdf_node_static_iterator_create(librdf_node ** nodes,int size)1314 librdf_node_static_iterator_create(librdf_node **nodes, int size)
1315 {
1316 return NULL;
1317 }
1318
1319
1320 /**
1321 * librdf_node_write:
1322 * @node: the node
1323 * @iostr: iostream to write to
1324 *
1325 * Write the node to an iostream in N-Triples format.
1326 *
1327 * This method can be used to write a node in a relatively
1328 * readable format. To write more compact formats use a
1329 * serializer to pick a syntax and serialize triples to it.
1330 *
1331 * Return value: non-0 on failure
1332 **/
1333 int
librdf_node_write(librdf_node * node,raptor_iostream * iostr)1334 librdf_node_write(librdf_node* node, raptor_iostream *iostr)
1335 {
1336 const unsigned char* term;
1337 size_t len;
1338
1339 #define NULL_STRING_LENGTH 6
1340 static const unsigned char * const null_string = (const unsigned char *)"(null)";
1341
1342 LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(iostr, raptor_iostream, 1);
1343
1344 if(!node) {
1345 raptor_iostream_counted_string_write(null_string, NULL_STRING_LENGTH, iostr);
1346 return 0;
1347 }
1348
1349 switch(node->type) {
1350 case RAPTOR_TERM_TYPE_LITERAL:
1351 raptor_iostream_write_byte('"', iostr);
1352 raptor_string_ntriples_write(node->value.literal.string,
1353 node->value.literal.string_len,
1354 '"',
1355 iostr);
1356 raptor_iostream_write_byte('"', iostr);
1357 if(node->value.literal.language) {
1358 raptor_iostream_write_byte('@', iostr);
1359 raptor_iostream_string_write(node->value.literal.language, iostr);
1360 }
1361 if(node->value.literal.datatype) {
1362 raptor_iostream_counted_string_write("^^<", 3, iostr);
1363 term = librdf_uri_as_counted_string(node->value.literal.datatype,
1364 &len);
1365 raptor_string_ntriples_write(term, len, '>', iostr);
1366 raptor_iostream_write_byte('>', iostr);
1367 }
1368
1369 break;
1370
1371 case RAPTOR_TERM_TYPE_BLANK:
1372 raptor_iostream_counted_string_write("_:", 2, iostr);
1373 term = (unsigned char*)node->value.blank.string;
1374 len = node->value.blank.string_len;
1375 raptor_iostream_counted_string_write(term, len, iostr);
1376 break;
1377
1378 case RAPTOR_TERM_TYPE_URI:
1379 raptor_iostream_write_byte('<', iostr);
1380 term = librdf_uri_as_counted_string(node->value.uri, &len);
1381 raptor_string_ntriples_write(term, len, '>', iostr);
1382 raptor_iostream_write_byte('>', iostr);
1383 break;
1384
1385 case RAPTOR_TERM_TYPE_UNKNOWN:
1386 default:
1387 /*LIBRDF_FATAL1(node->world, LIBRDF_FROM_NODE, "Unknown node type");*/
1388 return 1;
1389 }
1390
1391 return 0;
1392 }
1393
1394 #endif /* STANDALONE */
1395
1396
1397 /* TEST CODE */
1398
1399
1400 #ifdef STANDALONE
1401
1402 /* one more prototype */
1403 int main(int argc, char *argv[]);
1404
1405
1406 static void
dump_node_as_C(FILE * fh,const char * var,void * buffer,int size)1407 dump_node_as_C(FILE* fh, const char* var, void *buffer, int size) {
1408 int i;
1409 unsigned char* p=(unsigned char*)buffer;
1410
1411 fprintf(fh, "const unsigned char %s[%d] = {", var, size);
1412 for (i=0; i < size; i++) {
1413 if(i)
1414 fputs(", ", fh);
1415 fprintf(fh, "0x%02x", p[i]);
1416 }
1417 fputs("};\n", fh);
1418 }
1419
1420
1421 static int
check_node(const char * program,const unsigned char * expected,void * buffer,size_t size)1422 check_node(const char* program, const unsigned char *expected,
1423 void *buffer, size_t size) {
1424 unsigned int i;
1425 for(i=0; i< size; i++) {
1426 unsigned char c=((unsigned char*)buffer)[i];
1427 if(c != expected[i]) {
1428 fprintf(stderr, "%s: Encoding node byte %d: 0x%02x expected 0x%02x\n",
1429 program, i, c, expected[i]);
1430 return(1);
1431 }
1432 }
1433 return(0);
1434 }
1435
1436
1437 static const char *hp_string1="http://purl.org/net/dajobe/";
1438 static const char *hp_string2="http://purl.org/net/dajobe/";
1439 static const char *lit_string="Dave Beckett";
1440 static const char *genid="genid42";
1441 static const char *datatype_lit_string="Datatyped literal value";
1442 static const char *datatype_uri_string="http://example.org/datatypeURI";
1443
1444 /* Node Encoded (type R) version of hp_string1 */
1445 static const unsigned char hp_uri_encoded[31] = {0x52, 0x00, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x64, 0x61, 0x6a, 0x6f, 0x62, 0x65, 0x2f, 0x00};
1446
1447 /* Node Encoded (type M) version of typed literal with literal value
1448 * datatype_lit_string and datatype URI datatype_uri_string */
1449 static const unsigned char datatyped_literal_M_encoded[61] = {0x4d, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x44, 0x61, 0x74, 0x61, 0x74, 0x79, 0x70, 0x65, 0x64, 0x20, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x74, 0x79, 0x70, 0x65, 0x55, 0x52, 0x49, 0x00};
1450
1451 /* Node Encoded (type N) version of big 100,000-length literal
1452 * (just the first 32 bytes, the rest are 0x58 'X')
1453 */
1454 const unsigned char big_literal_N_encoded[32] = {0x4e, 0x00, 0x01, 0x86, 0xa0, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58};
1455
1456
1457 int
main(int argc,char * argv[])1458 main(int argc, char *argv[])
1459 {
1460 librdf_node *node, *node2, *node3, *node4, *node5, *node6, *node7, *node8, *node9;
1461 librdf_uri *uri, *uri2;
1462 int size, size2;
1463 unsigned char *buffer;
1464 librdf_world *world;
1465 size_t big_literal_length;
1466 unsigned char *big_literal;
1467 unsigned int i;
1468
1469 const char *program=librdf_basename((const char*)argv[0]);
1470
1471 world=librdf_new_world();
1472 librdf_world_open(world);
1473
1474 fprintf(stderr, "%s: Creating home page node from string\n", program);
1475 node=librdf_new_node_from_uri_string(world, (const unsigned char*)hp_string1);
1476 if(!node) {
1477 fprintf(stderr, "%s: librdf_new_node_from_uri_string failed\n", program);
1478 return(1);
1479 }
1480
1481 fprintf(stdout, "%s: Home page URI is ", program);
1482 librdf_uri_print(librdf_node_get_uri(node), stdout);
1483 fputc('\n', stdout);
1484
1485 fprintf(stdout, "%s: Creating URI from string '%s'\n", program,
1486 hp_string2);
1487 uri=librdf_new_uri(world, (const unsigned char*)hp_string2);
1488 fprintf(stdout, "%s: Setting node URI to new URI ", program);
1489 librdf_uri_print(uri, stdout);
1490 fputc('\n', stdout);
1491 librdf_free_uri(uri);
1492
1493 fprintf(stdout, "%s: Node is: ", program);
1494 librdf_node_print(node, stdout);
1495 fputc('\n', stdout);
1496
1497 size=librdf_node_encode(node, NULL, 0);
1498 fprintf(stdout, "%s: Encoding node requires %d bytes\n", program, size);
1499 buffer = LIBRDF_MALLOC(unsigned char*, size);
1500
1501 fprintf(stdout, "%s: Encoding node in buffer\n", program);
1502 size2=librdf_node_encode(node, buffer, size);
1503 if(size2 != size) {
1504 fprintf(stderr, "%s: Encoding node used %d bytes, expected it to use %d\n", program, size2, size);
1505 return(1);
1506 }
1507
1508 if(0)
1509 dump_node_as_C(stdout, "hp_uri_encoded", buffer, size);
1510 if(check_node(program, hp_uri_encoded, buffer, size))
1511 return(1);
1512
1513
1514 fprintf(stdout, "%s: Creating new node\n", program);
1515
1516 fprintf(stdout, "%s: Decoding node from buffer\n", program);
1517 if(!(node2=librdf_node_decode(world, NULL, buffer, size))) {
1518 fprintf(stderr, "%s: Decoding node failed\n", program);
1519 return(1);
1520 }
1521 LIBRDF_FREE(char*, buffer);
1522
1523 fprintf(stdout, "%s: New node is: ", program);
1524 librdf_node_print(node2, stdout);
1525 fputc('\n', stdout);
1526
1527
1528 fprintf(stdout, "%s: Creating new literal string node\n", program);
1529 node3=librdf_new_node_from_literal(world, (const unsigned char*)lit_string, NULL, 0);
1530 if(!node3) {
1531 fprintf(stderr, "%s: librdf_new_node_from_literal failed\n", program);
1532 return(1);
1533 }
1534
1535 buffer=(unsigned char*)librdf_node_get_literal_value_as_latin1(node3);
1536 if(!buffer) {
1537 fprintf(stderr, "%s: Failed to get literal string value as Latin-1\n", program);
1538 return(1);
1539 }
1540 fprintf(stdout, "%s: Node literal string value (Latin-1) is: '%s'\n",
1541 program, buffer);
1542 LIBRDF_FREE(char*, buffer);
1543
1544 fprintf(stdout, "%s: Creating new blank node with identifier %s\n", program, genid);
1545 node4=librdf_new_node_from_blank_identifier(world, (const unsigned char*)genid);
1546 if(!node4) {
1547 fprintf(stderr, "%s: librdf_new_node_from_blank_identifier failed\n", program);
1548 return(1);
1549 }
1550
1551 buffer=librdf_node_get_blank_identifier(node4);
1552 if(!buffer) {
1553 fprintf(stderr, "%s: Failed to get blank node identifier\n", program);
1554 return(1);
1555 }
1556 fprintf(stdout, "%s: Node identifier is: '%s'\n", program, buffer);
1557
1558 node5=librdf_new_node_from_node(node4);
1559 if(!node5) {
1560 fprintf(stderr, "%s: Failed to make new blank node from old one\n", program);
1561 return(1);
1562 }
1563
1564 buffer=librdf_node_get_blank_identifier(node5);
1565 if(!buffer) {
1566 fprintf(stderr, "%s: Failed to get copied blank node identifier\n", program);
1567 return(1);
1568 }
1569 fprintf(stdout, "%s: Copied node identifier is: '%s'\n", program, buffer);
1570
1571 fprintf(stdout, "%s: Creating a new blank node with a generated identifier\n", program);
1572 node6=librdf_new_node(world);
1573 if(!node6) {
1574 fprintf(stderr, "%s: librdf_new_node failed\n", program);
1575 return(1);
1576 }
1577
1578 buffer=librdf_node_get_blank_identifier(node6);
1579 if(!buffer) {
1580 fprintf(stderr, "%s: Failed to get blank node identifier\n", program);
1581 return(1);
1582 }
1583 fprintf(stdout, "%s: Generated node identifier is: '%s'\n", program, buffer);
1584
1585 uri2=librdf_new_uri(world, (const unsigned char*)datatype_uri_string);
1586 node7=librdf_new_node_from_typed_literal(world,
1587 (const unsigned char*)datatype_lit_string,
1588 NULL, uri2);
1589 librdf_free_uri(uri2);
1590
1591 size=librdf_node_encode(node7, NULL, 0);
1592 fprintf(stdout, "%s: Encoding typed node requires %d bytes\n", program, size);
1593 buffer = LIBRDF_MALLOC(unsigned char*, size);
1594
1595 fprintf(stdout, "%s: Encoding typed node in buffer\n", program);
1596 size2=librdf_node_encode(node7, (unsigned char*)buffer, size);
1597 if(size2 != size) {
1598 fprintf(stderr, "%s: Encoding typed node used %d bytes, expected it to use %d\n", program, size2, size);
1599 return(1);
1600 }
1601
1602 if(0)
1603 dump_node_as_C(stdout, "datatyped_literal_M_encoded", buffer, size);
1604 if(check_node(program, datatyped_literal_M_encoded, buffer, size))
1605 return(1);
1606
1607 fprintf(stdout, "%s: Decoding typed node from buffer\n", program);
1608 if(!(node8=librdf_node_decode(world, NULL, (unsigned char*)buffer, size))) {
1609 fprintf(stderr, "%s: Decoding typed node failed\n", program);
1610 return(1);
1611 }
1612 LIBRDF_FREE(char*, buffer);
1613
1614 if(librdf_new_node_from_typed_literal(world,
1615 (const unsigned char*)"Datatyped literal value",
1616 "en-GB", uri2)) {
1617 fprintf(stderr, "%s: Unexpected success allowing a datatyped literal with a language\n", program);
1618 return(1);
1619 }
1620
1621 if(librdf_new_node_from_literal(world,
1622 (const unsigned char*)"XML literal value",
1623 "en-GB", 1)) {
1624 fprintf(stderr, "%s: Unexpected success allowing an XML literal with a language\n", program);
1625 return(1);
1626 }
1627
1628 big_literal_length=100000;
1629 big_literal = LIBRDF_MALLOC(unsigned char*, big_literal_length + 1);
1630 for(i=0; i<big_literal_length; i++)
1631 big_literal[i]='X';
1632
1633 node9=librdf_new_node_from_typed_counted_literal(world,
1634 big_literal, big_literal_length,
1635 NULL, 0, NULL);
1636 if(!node9) {
1637 fprintf(stderr, "%s: Failed to make big %d byte literal\n", program,
1638 (int)big_literal_length);
1639 return(1);
1640 }
1641 LIBRDF_FREE(char*, big_literal);
1642
1643 size=librdf_node_encode(node9, NULL, 0);
1644 fprintf(stdout, "%s: Encoding big literal node requires %d bytes\n", program, size);
1645 buffer = LIBRDF_MALLOC(unsigned char*, size);
1646 fprintf(stdout, "%s: Encoding big literal node in buffer\n", program);
1647 size2=librdf_node_encode(node9, (unsigned char*)buffer, size);
1648 if(size2 != size) {
1649 fprintf(stderr, "%s: Encoding big literal node used %d bytes, expected it to use %d\n", program, size2, size);
1650 return(1);
1651 }
1652
1653 /* Just check first 32 bytes */
1654 if(0)
1655 dump_node_as_C(stdout, "big_literal_N_encoded", buffer, 32);
1656 if(check_node(program, big_literal_N_encoded, buffer, 32))
1657 return(1);
1658 LIBRDF_FREE(char*, buffer);
1659
1660
1661 fprintf(stdout, "%s: Freeing nodes\n", program);
1662 librdf_free_node(node9);
1663 librdf_free_node(node8);
1664 librdf_free_node(node7);
1665 librdf_free_node(node6);
1666 librdf_free_node(node5);
1667 librdf_free_node(node4);
1668 librdf_free_node(node3);
1669 librdf_free_node(node2);
1670 librdf_free_node(node);
1671
1672 librdf_free_world(world);
1673
1674 /* keep gcc -Wall happy */
1675 return(0);
1676 }
1677
1678 #endif
1679