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