Add iri_dup; hide implementation details of iri_t.
[platform/upstream/libiri.git] / libiri / dup.c
1 /*
2  * libiri: An IRI/URI/URL parsing library
3  * @(#) $Id$
4  */
5
6 /*
7  * Copyright (c) 2005, 2008 Mo McRoberts.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * 3. The names of the author(s) of this software may not be used to endorse
18  * or promote products derived from this software without specific prior
19  * written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
22  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
23  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24  * AUTHORS OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include "p_libiri.h"
38
39 static inline void
40 iri__dupcopy(const char **dest, const char *src, const char *srcbase, size_t buflen, const char *destbase)
41 {
42         if(NULL == src)
43         {
44                 *dest = NULL;
45         }
46         else if(src >= srcbase && src <= srcbase + buflen)
47         {
48                 *dest = destbase + (src - srcbase);
49         }
50         else
51         {
52                 *dest = strdup(src);
53         }
54 }
55
56 iri_t *
57 iri_dup(iri_t *iri)
58 {
59         iri_t *p;
60         
61         if(NULL == (p = (iri_t *) calloc(1, sizeof(iri_t))))
62         {
63                 return NULL;
64         }
65         if(NULL == (p->base = (char *) calloc(1, iri->nbytes)))
66         {
67                 free(p);
68                 return NULL;
69         }
70         p->nbytes = iri->nbytes;
71         p->iri.port = iri->iri.port;
72         memcpy(p->base, iri->base, p->nbytes);
73         iri__dupcopy(&(p->iri.display), iri->iri.display, iri->base, iri->nbytes, p->base);
74         iri__dupcopy(&(p->iri.scheme), iri->iri.scheme, iri->base, iri->nbytes, p->base);
75         iri__dupcopy(&(p->iri.user), iri->iri.user, iri->base, iri->nbytes, p->base);
76         iri__dupcopy(&(p->iri.auth), iri->iri.auth, iri->base, iri->nbytes, p->base);
77         iri__dupcopy(&(p->iri.password), iri->iri.password, iri->base, iri->nbytes, p->base);
78         iri__dupcopy(&(p->iri.host), iri->iri.host, iri->base, iri->nbytes, p->base);
79         iri__dupcopy(&(p->iri.path), iri->iri.path, iri->base, iri->nbytes, p->base);
80         iri__dupcopy(&(p->iri.query), iri->iri.query, iri->base, iri->nbytes, p->base);
81         iri__dupcopy(&(p->iri.anchor), iri->iri.anchor, iri->base, iri->nbytes, p->base);
82         return p;
83 }