1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * raptor_qname.c - Raptor XML qname class
4 *
5 * Copyright (C) 2002-2008, David Beckett http://www.dajobe.org/
6 * Copyright (C) 2002-2004, University of Bristol, UK http://www.bristol.ac.uk/
7 *
8 * This package is Free Software and part of Redland http://librdf.org/
9 *
10 * It is licensed under the following three licenses as alternatives:
11 * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12 * 2. GNU General Public License (GPL) V2 or any newer version
13 * 3. Apache License, V2.0 or any newer version
14 *
15 * You may not use this file except in compliance with at least one of
16 * the above three licenses.
17 *
18 * See LICENSE.html or LICENSE.txt at the top of this package for the
19 * complete terms and further detail along with the license texts for
20 * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
21 *
22 *
23 */
24
25
26 #ifdef HAVE_CONFIG_H
27 #include <raptor_config.h>
28 #endif
29
30 #ifdef WIN32
31 #include <win32_raptor_config.h>
32 #endif
33
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include <stdarg.h>
39 #ifdef HAVE_ERRNO_H
40 #include <errno.h>
41 #endif
42 #ifdef HAVE_STDLIB_H
43 #include <stdlib.h>
44 #endif
45
46 /* Raptor includes */
47 #include "raptor.h"
48 #include "raptor_internal.h"
49
50
51 /*
52 * Namespaces in XML
53 * http://www.w3.org/TR/1999/REC-xml-names-19990114/#defaulting
54 * says:
55 *
56 * --------------------------------------------------------------------
57 * 5.2 Namespace Defaulting
58 *
59 * A default namespace is considered to apply to the element where it
60 * is declared (if that element has no namespace prefix), and to all
61 * elements with no prefix within the content of that element.
62 *
63 * If the URI reference in a default namespace declaration is empty,
64 * then unprefixed elements in the scope of the declaration are not
65 * considered to be in any namespace.
66 *
67 * Note that default namespaces do not apply directly to attributes.
68 *
69 * [...]
70 *
71 * 5.3 Uniqueness of Attributes
72 *
73 * In XML documents conforming to this specification, no tag may
74 * contain two attributes which:
75 *
76 * 1. have identical names, or
77 *
78 * 2. have qualified names with the same local part and with
79 * prefixes which have been bound to namespace names that are
80 * identical.
81 * --------------------------------------------------------------------
82 */
83
84 /**
85 * raptor_new_qname:
86 * @nstack: namespace stack to look up for namespaces
87 * @name: element or attribute name
88 * @value: attribute value (else is an element)
89 * @error_handler: function to call on an error
90 * @error_data: user data for error function
91 *
92 * Constructor - create a new XML qname.
93 *
94 * Create a new qname from the local element/attribute name,
95 * with optional (attribute) value. The namespace stack is used
96 * to look up the name and find the namespace and generate the
97 * URI of the qname.
98 *
99 * Return value: a new #raptor_qname object or NULL on failure
100 **/
101 raptor_qname*
raptor_new_qname(raptor_namespace_stack * nstack,const unsigned char * name,const unsigned char * value,raptor_simple_message_handler error_handler,void * error_data)102 raptor_new_qname(raptor_namespace_stack *nstack,
103 const unsigned char *name,
104 const unsigned char *value,
105 raptor_simple_message_handler error_handler,
106 void *error_data)
107 {
108 raptor_qname* qname;
109 const unsigned char *p;
110 raptor_namespace* ns;
111 unsigned char* new_name;
112 int prefix_length;
113 int local_name_length=0;
114
115 #if RAPTOR_DEBUG > 1
116 RAPTOR_DEBUG2("name %s\n", name);
117 #endif
118
119 qname=(raptor_qname*)RAPTOR_CALLOC(raptor_qname, 1, sizeof(raptor_qname));
120 if(!qname)
121 return NULL;
122 qname->world=nstack->world;
123
124 if(value) {
125 int value_length=strlen((char*)value);
126 unsigned char* new_value=(unsigned char*)RAPTOR_MALLOC(cstring, value_length+1);
127
128 if(!new_value) {
129 RAPTOR_FREE(raptor_qname, qname);
130 return NULL;
131 }
132 strcpy((char*)new_value, (char*)value);
133 qname->value=new_value;
134 qname->value_length=value_length;
135 }
136
137
138 /* Find : */
139 for(p=name; *p && *p != ':'; p++)
140 ;
141
142
143 if(!*p) {
144 local_name_length=p-name;
145
146 /* No : in the name */
147 new_name=(unsigned char*)RAPTOR_MALLOC(cstring, local_name_length+1);
148 if(!new_name) {
149 raptor_free_qname(qname);
150 return NULL;
151 }
152 strcpy((char*)new_name, (char*)name);
153 qname->local_name=new_name;
154 qname->local_name_length=local_name_length;
155
156 /* For elements only, pick up the default namespace if there is one */
157 if(!value) {
158 ns=raptor_namespaces_get_default_namespace(nstack);
159
160 if(ns) {
161 qname->nspace=ns;
162 #if RAPTOR_DEBUG > 1
163 RAPTOR_DEBUG2("Found default namespace %s\n", raptor_uri_as_string_v2(nstack->world, ns->uri));
164 #endif
165 } else {
166 #if RAPTOR_DEBUG > 1
167 RAPTOR_DEBUG1("No default namespace defined\n");
168 #endif
169 }
170 } /* if is_element */
171
172 } else {
173 /* There is a namespace prefix */
174
175 prefix_length=p-name;
176 p++;
177
178 /* p now is at start of local_name */
179 local_name_length=strlen((char*)p);
180 new_name=(unsigned char*)RAPTOR_MALLOC(cstring, local_name_length+1);
181 if(!new_name) {
182 raptor_free_qname(qname);
183 return NULL;
184 }
185 strcpy((char*)new_name, (char*)p);
186 qname->local_name=new_name;
187 qname->local_name_length=local_name_length;
188
189 /* Find the namespace */
190 ns=raptor_namespaces_find_namespace(nstack, name, prefix_length);
191
192 if(!ns) {
193 /* failed to find namespace - now what? */
194 if(error_handler)
195 error_handler((raptor_parser*)error_data, "The namespace prefix in \"%s\" was not declared.", name);
196 } else {
197 #if RAPTOR_DEBUG > 1
198 RAPTOR_DEBUG3("Found namespace prefix %s URI %s\n", ns->prefix, raptor_uri_as_string_v2(nstack->world, ns->uri));
199 #endif
200 qname->nspace=ns;
201 }
202 }
203
204
205
206 /* If namespace has a URI and a local_name is defined, create the URI
207 * for this element
208 */
209 if(qname->nspace && local_name_length) {
210 raptor_uri *uri=raptor_namespace_get_uri(qname->nspace);
211 if(uri)
212 uri=raptor_new_uri_from_uri_local_name_v2(qname->world, uri, new_name);
213
214 qname->uri=uri;
215 }
216
217
218 return qname;
219 }
220
221
222 #ifndef RAPTOR_DISABLE_V1
223 /**
224 * raptor_new_qname_from_namespace_local_name:
225 * @ns: namespace of qname (or NULL)
226 * @local_name: element or attribute name
227 * @value: attribute value (else is an element)
228 *
229 * Constructor - create a new XML qname.
230 *
231 * Create a new qname from the namespace and local element/attribute name,
232 * with optional (attribute) value.
233 *
234 * raptor_init() MUST have been called before calling this function.
235 * Use raptor_new_qname_from_namespace_local_name_v2() if using raptor_world APIs.
236 *
237 * Return value: a new #raptor_qname object or NULL on failure
238 **/
239 raptor_qname*
raptor_new_qname_from_namespace_local_name(raptor_namespace * ns,const unsigned char * local_name,const unsigned char * value)240 raptor_new_qname_from_namespace_local_name(raptor_namespace *ns,
241 const unsigned char *local_name,
242 const unsigned char *value)
243 {
244 return raptor_new_qname_from_namespace_local_name_v2(raptor_world_instance(),
245 ns,
246 local_name,
247 value);
248 }
249 #endif
250
251
252 /**
253 * raptor_new_qname_from_namespace_local_name_v2:
254 * @world: raptor_world object
255 * @ns: namespace of qname (or NULL)
256 * @local_name: element or attribute name
257 * @value: attribute value (else is an element)
258 *
259 * Constructor - create a new XML qname.
260 *
261 * Create a new qname from the namespace and local element/attribute name,
262 * with optional (attribute) value.
263 *
264 * Return value: a new #raptor_qname object or NULL on failure
265 **/
266 raptor_qname*
raptor_new_qname_from_namespace_local_name_v2(raptor_world * world,raptor_namespace * ns,const unsigned char * local_name,const unsigned char * value)267 raptor_new_qname_from_namespace_local_name_v2(raptor_world* world,
268 raptor_namespace *ns,
269 const unsigned char *local_name,
270 const unsigned char *value)
271 {
272 raptor_qname* qname;
273 unsigned char* new_name;
274 int local_name_length=strlen((char*)local_name);
275
276 if(!local_name)
277 return NULL;
278
279 qname=(raptor_qname*)RAPTOR_CALLOC(raptor_qname, 1, sizeof(raptor_qname));
280 if(!qname)
281 return NULL;
282 qname->world=world;
283
284 if(value) {
285 int value_length=strlen((char*)value);
286 unsigned char* new_value=(unsigned char*)RAPTOR_MALLOC(cstring, value_length+1);
287
288 if(!new_value) {
289 RAPTOR_FREE(raptor_qname, qname);
290 return NULL;
291 }
292 strcpy((char*)new_value, (char*)value);
293 qname->value=new_value;
294 qname->value_length=value_length;
295 }
296
297 new_name=(unsigned char*)RAPTOR_MALLOC(cstring, local_name_length+1);
298 if(!new_name) {
299 raptor_free_qname(qname);
300 return NULL;
301 }
302 strcpy((char*)new_name, (char*)local_name);
303 qname->local_name=new_name;
304 qname->local_name_length=local_name_length;
305
306 qname->nspace=ns;
307
308 if(qname->nspace) {
309 qname->uri=raptor_namespace_get_uri(qname->nspace);
310 if(qname->uri)
311 qname->uri=raptor_new_uri_from_uri_local_name_v2(qname->world, qname->uri, new_name);
312 }
313
314 return qname;
315 }
316
317
318 /**
319 * raptor_qname_copy:
320 * @qname: existing qname
321 *
322 * Copy constructor - copy an existing XML qname.
323 *
324 * Return value: a new #raptor_qname object or NULL on failure
325 **/
326 raptor_qname*
raptor_qname_copy(raptor_qname * qname)327 raptor_qname_copy(raptor_qname *qname) {
328 raptor_qname* new_qname;
329 unsigned char* new_name;
330
331 new_qname=(raptor_qname*)RAPTOR_CALLOC(raptor_qname, 1, sizeof(raptor_qname));
332 if(!new_qname)
333 return NULL;
334 new_qname->world=qname->world;
335
336 if(qname->value) {
337 int value_length=qname->value_length;
338 unsigned char* new_value=(unsigned char*)RAPTOR_MALLOC(cstring, value_length+1);
339
340 if(!new_value) {
341 RAPTOR_FREE(raptor_qname, qname);
342 return NULL;
343 }
344 strcpy((char*)new_value, (char*)qname->value);
345 new_qname->value=new_value;
346 new_qname->value_length=value_length;
347 }
348
349 new_name=(unsigned char*)RAPTOR_MALLOC(cstring, qname->local_name_length+1);
350 if(!new_name) {
351 raptor_free_qname(new_qname);
352 return NULL;
353 }
354 strcpy((char*)new_name, (char*)qname->local_name);
355 new_qname->local_name=new_name;
356 new_qname->local_name_length=qname->local_name_length;
357
358 new_qname->nspace=qname->nspace;
359
360 new_qname->uri=raptor_namespace_get_uri(new_qname->nspace);
361 if(new_qname->uri)
362 new_qname->uri=raptor_new_uri_from_uri_local_name_v2(qname->world, new_qname->uri, new_name);
363
364 return new_qname;
365 }
366
367
368 #ifdef RAPTOR_DEBUG
369 void
raptor_qname_print(FILE * stream,raptor_qname * name)370 raptor_qname_print(FILE *stream, raptor_qname* name)
371 {
372 if(name->nspace) {
373 const unsigned char *prefix=raptor_namespace_get_prefix(name->nspace);
374 if(prefix)
375 fprintf(stream, "%s:%s", prefix, name->local_name);
376 else
377 fprintf(stream, "(default):%s", name->local_name);
378 } else
379 fputs((char*)name->local_name, stream);
380 }
381 #endif
382
383
384 /**
385 * raptor_free_qname:
386 * @name: #raptor_qname object
387 *
388 * Destructor - destroy a raptor_qname object.
389 **/
390 void
raptor_free_qname(raptor_qname * name)391 raptor_free_qname(raptor_qname* name)
392 {
393 RAPTOR_ASSERT_OBJECT_POINTER_RETURN(name, raptor_qname);
394
395 if(name->local_name)
396 RAPTOR_FREE(cstring, (void*)name->local_name);
397
398 if(name->uri && name->nspace)
399 raptor_free_uri_v2(name->world, name->uri);
400
401 if(name->value)
402 RAPTOR_FREE(cstring, (void*)name->value);
403 RAPTOR_FREE(raptor_qname, name);
404 }
405
406
407 /**
408 * raptor_qname_equal:
409 * @name1: first #raptor_qname
410 * @name2: second #raptor_name
411 *
412 * Compare two XML Qnames for equality.
413 *
414 * Return value: non-0 if the qnames are equal.
415 **/
416 int
raptor_qname_equal(raptor_qname * name1,raptor_qname * name2)417 raptor_qname_equal(raptor_qname *name1, raptor_qname *name2)
418 {
419 if(name1->nspace != name2->nspace)
420 return 0;
421 if(name1->local_name_length != name2->local_name_length)
422 return 0;
423 if(strcmp((char*)name1->local_name, (char*)name2->local_name))
424 return 0;
425 return 1;
426 }
427
428
429
430 /**
431 * raptor_qname_string_to_uri:
432 * @nstack: #raptor_namespace_stack to decode the namespace
433 * @name: QName string or NULL
434 * @name_len: QName string length
435 * @error_handler: function to call on an error
436 * @error_data: user data for error function
437 *
438 * Get the URI for a qname.
439 *
440 * Utility function to turn a string representing a QName in the
441 * N3 style, into a new URI representing it. A NULL name or name ":"
442 * returns the default namespace URI. A name "p:" returns
443 * namespace name (URI) for the namespace with prefix "p".
444 *
445 * Partially equivalent to
446 * qname=raptor_new_qname(nstack, name, NULL, error_handler, error_data);
447 * uri=raptor_uri_copy(qname->uri);
448 * raptor_free_qname(qname)
449 * but without making the qname, and it also handles the NULL and
450 * ":" name cases as well as error checking.
451 *
452 * Return value: new #raptor_uri object or NULL on failure
453 **/
454 raptor_uri*
raptor_qname_string_to_uri(raptor_namespace_stack * nstack,const unsigned char * name,size_t name_len,raptor_simple_message_handler error_handler,void * error_data)455 raptor_qname_string_to_uri(raptor_namespace_stack *nstack,
456 const unsigned char *name, size_t name_len,
457 raptor_simple_message_handler error_handler,
458 void *error_data)
459 {
460 raptor_uri *uri=NULL;
461 const unsigned char *p;
462 const unsigned char *original_name=name;
463 const unsigned char *local_name=NULL;
464 int local_name_length=0;
465 raptor_namespace* ns;
466
467 /* Empty string is default namespace URI */
468 if(!name) {
469 ns=raptor_namespaces_get_default_namespace(nstack);
470 } else {
471 /* If starts with :, it is relative to default namespace, so skip it */
472 if(*name == ':') {
473 name++;
474 name_len--;
475 }
476
477 for(p=name; *p && *p != ':'; p++)
478 ;
479
480 /* If ends with :, it is the URI of a namespace */
481 if(p-name == (int)(name_len-1)) {
482 ns=raptor_namespaces_find_namespace(nstack, name, name_len-1);
483 } else {
484 if(!*p) {
485 local_name=name;
486 local_name_length=p-name;
487
488 /* pick up the default namespace if there is one */
489 ns=raptor_namespaces_get_default_namespace(nstack);
490 } else {
491 /* There is a namespace prefix */
492 int prefix_length=p-name;
493 p++;
494
495 local_name=p;
496 local_name_length=strlen((char*)p);
497
498 /* Find the namespace */
499 ns=raptor_namespaces_find_namespace(nstack, name, prefix_length);
500 }
501 }
502 }
503
504 if(!ns) {
505 if(error_handler)
506 error_handler((raptor_parser*)error_data, "The namespace prefix in \"%s\" was not declared.", original_name);
507 }
508
509
510
511 /* If namespace has a URI and a local_name is defined, return the URI
512 * for this name
513 */
514 if(ns && (uri=raptor_namespace_get_uri(ns))) {
515 if(local_name_length)
516 uri=raptor_new_uri_from_uri_local_name_v2(nstack->world, uri, local_name);
517 else
518 uri=raptor_uri_copy_v2(nstack->world, uri);
519 }
520
521 return uri;
522 }
523
524
525 /**
526 * raptor_iostream_write_qname:
527 * @iostr: raptor iosteram
528 * @qname: QName to write
529 *
530 * Write a formatted qname to an iostream
531 *
532 * Return value: non-0 on failure
533 **/
534 int
raptor_iostream_write_qname(raptor_iostream * iostr,raptor_qname * qname)535 raptor_iostream_write_qname(raptor_iostream* iostr, raptor_qname *qname)
536 {
537 if(qname->nspace && qname->nspace->prefix_length > 0) {
538 raptor_iostream_write_counted_string(iostr, qname->nspace->prefix,
539 qname->nspace->prefix_length);
540 raptor_iostream_write_byte(iostr, ':');
541 }
542
543 raptor_iostream_write_counted_string(iostr, qname->local_name,
544 qname->local_name_length);
545 return 0;
546 }
547
548
549 /**
550 * raptor_qname_to_counted_name:
551 * @qname: QName to write
552 * @length_p: pointer to variable to store length of name (or NULL)
553 *
554 * Get the string form of a QName name
555 *
556 * Return value: string or NULL on failure
557 **/
558 unsigned char*
raptor_qname_to_counted_name(raptor_qname * qname,size_t * length_p)559 raptor_qname_to_counted_name(raptor_qname *qname, size_t* length_p)
560 {
561 size_t len=qname->local_name_length;
562 unsigned char* s;
563 unsigned char *p;
564
565 if(qname->nspace && qname->nspace->prefix_length > 0)
566 len+= 1 + qname->nspace->prefix_length;
567
568 if(length_p)
569 *length_p=len;
570
571 s=(unsigned char*)RAPTOR_MALLOC(cstring, len+1);
572 if(!s)
573 return NULL;
574
575 p=s;
576 if(qname->nspace && qname->nspace->prefix_length > 0) {
577 strncpy((char*)p, (const char*)qname->nspace->prefix,
578 qname->nspace->prefix_length);
579 p+= qname->nspace->prefix_length;
580 *p++ = ':';
581 }
582
583 strncpy((char*)p, (const char*)qname->local_name, qname->local_name_length+1);
584
585 return s;
586 }
587
588
589 /**
590 * raptor_qname_get_namespace:
591 * @name: #raptor_qname object
592 *
593 * Get the #raptor_namespace of an XML QName.
594 *
595 * Return value: the namespace
596 **/
597 const raptor_namespace*
raptor_qname_get_namespace(raptor_qname * name)598 raptor_qname_get_namespace(raptor_qname* name)
599 {
600 return name->nspace;
601 }
602
603
604 /**
605 * raptor_qname_get_local_name:
606 * @name: #raptor_qname object
607 *
608 * Get the #raptor_local_name of an XML QName.
609 *
610 * Return value: the local_name
611 **/
612 const unsigned char*
raptor_qname_get_local_name(raptor_qname * name)613 raptor_qname_get_local_name(raptor_qname* name)
614 {
615 return name->local_name;
616 }
617
618
619 /**
620 * raptor_qname_get_value:
621 * @name: #raptor_qname object
622 *
623 * Get the #raptor_value of an XML QName.
624 *
625 * Return value: the value
626 **/
627 const unsigned char*
raptor_qname_get_value(raptor_qname * name)628 raptor_qname_get_value(raptor_qname* name)
629 {
630 return name->value;
631 }
632
633 /**
634 * raptor_qname_get_counted_value:
635 * @name: #raptor_qname object
636 * @length_p: pointer to variable to store length of name (or NULL)
637 *
638 * Get the #raptor_value of an XML QName.
639 *
640 * Return value: the value
641 **/
642 const unsigned char*
raptor_qname_get_counted_value(raptor_qname * name,size_t * length_p)643 raptor_qname_get_counted_value(raptor_qname* name, size_t* length_p)
644 {
645 if(length_p)
646 *length_p=name->value_length;
647 return name->value;
648 }
649