From: mo@ilaven.net Date: Sun, 23 Nov 2008 22:16:46 +0000 (+0000) Subject: Add iri_dup; hide implementation details of iri_t. X-Git-Tag: upstream/1.1~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=22b20971745ee0fea8b00b6811351f02287aea2a;p=platform%2Fupstream%2Flibiri.git Add iri_dup; hide implementation details of iri_t. git-svn-id: http://libiri.googlecode.com/svn/trunk@6 68b1170a-6346-0410-b79c-01ab32b2924b --- diff --git a/include/iri.h b/include/iri.h index 2adefab..32a0fa3 100644 --- a/include/iri.h +++ b/include/iri.h @@ -33,11 +33,12 @@ #ifndef IRI_H_ # define IRI_H_ 1 +# if !defined(LIBIRI_INTERNAL) typedef struct iri_struct iri_t; +# endif struct iri_struct { - void *_private; const char *display; const char *scheme; const char *user; @@ -60,5 +61,6 @@ struct iri_struct EXTERNC_ iri_t *iri_parse(const char *src); EXTERNC_ void iri_destroy(iri_t *iri); +EXTERNC_ iri_t *iri_dup(iri_t *iri); #endif /* !IRI_H_ */ diff --git a/libiri/Makefile.am b/libiri/Makefile.am index 056f50c..3763392 100644 --- a/libiri/Makefile.am +++ b/libiri/Makefile.am @@ -29,7 +29,9 @@ lib_LTLIBRARIES = libiri.la libiri_la_LDFLAGS = -avoid-version +libiri_la_CPPFLAGS = -DLIBIRI_INTERNAL=1 + libiri_la_SOURCES = \ p_libiri.h \ - parse.c destroy.c + parse.c destroy.c dup.c diff --git a/libiri/destroy.c b/libiri/destroy.c index 24bbd8c..ff2533d 100644 --- a/libiri/destroy.c +++ b/libiri/destroy.c @@ -41,7 +41,7 @@ iri_destroy(iri_t *iri) { if(NULL != iri) { - free(iri->_private); + free(iri->base); free(iri); } } diff --git a/libiri/dup.c b/libiri/dup.c new file mode 100644 index 0000000..7ce1eb7 --- /dev/null +++ b/libiri/dup.c @@ -0,0 +1,83 @@ +/* + * libiri: An IRI/URI/URL parsing library + * @(#) $Id$ + */ + +/* + * Copyright (c) 2005, 2008 Mo McRoberts. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the author(s) of this software may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * AUTHORS OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "p_libiri.h" + +static inline void +iri__dupcopy(const char **dest, const char *src, const char *srcbase, size_t buflen, const char *destbase) +{ + if(NULL == src) + { + *dest = NULL; + } + else if(src >= srcbase && src <= srcbase + buflen) + { + *dest = destbase + (src - srcbase); + } + else + { + *dest = strdup(src); + } +} + +iri_t * +iri_dup(iri_t *iri) +{ + iri_t *p; + + if(NULL == (p = (iri_t *) calloc(1, sizeof(iri_t)))) + { + return NULL; + } + if(NULL == (p->base = (char *) calloc(1, iri->nbytes))) + { + free(p); + return NULL; + } + p->nbytes = iri->nbytes; + p->iri.port = iri->iri.port; + memcpy(p->base, iri->base, p->nbytes); + iri__dupcopy(&(p->iri.display), iri->iri.display, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.scheme), iri->iri.scheme, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.user), iri->iri.user, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.auth), iri->iri.auth, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.password), iri->iri.password, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.host), iri->iri.host, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.path), iri->iri.path, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.query), iri->iri.query, iri->base, iri->nbytes, p->base); + iri__dupcopy(&(p->iri.anchor), iri->iri.anchor, iri->base, iri->nbytes, p->base); + return p; +} diff --git a/libiri/p_libiri.h b/libiri/p_libiri.h index beb2610..077f27b 100644 --- a/libiri/p_libiri.h +++ b/libiri/p_libiri.h @@ -37,6 +37,15 @@ #include #include +typedef struct iri_internal_struct iri_t; + #include "iri.h" -#endif /* !P_LIBIRI_H_ */ \ No newline at end of file +struct iri_internal_struct +{ + struct iri_struct iri; + void *base; + size_t nbytes; +}; + +#endif /* !P_LIBIRI_H_ */ diff --git a/libiri/parse.c b/libiri/parse.c index d96a350..368e841 100644 --- a/libiri/parse.c +++ b/libiri/parse.c @@ -97,13 +97,14 @@ iri__copychar_decode(char **dest, const char *src, int convert_space) } static inline char * -iri__allocbuf(const char *src) +iri__allocbuf(const char *src, size_t *len) { /* Calculate the size of the buffer required to hold a decoded version of * src, including enough breathing space for null bytes. */ /* XXX: This is way too much; we need to actually count it */ - return (char *) calloc(1, (strlen(src) * 4) + 16); + *len = (strlen(src) * 4) + 16; + return (char *) calloc(1, *len); } iri_t * @@ -112,17 +113,19 @@ iri_parse(const char *src) iri_t *p; char *bufstart, *endp, *bufp; const char *at, *colon, *slash; + size_t buflen; if(NULL == (p = (iri_t *) calloc(1, sizeof(iri_t)))) { return NULL; } - if(NULL == (bufstart = iri__allocbuf(src))) + if(NULL == (bufstart = iri__allocbuf(src, &buflen))) { free(p); return NULL; } - p->_private = bufp = bufstart; + p->base = bufp = bufstart; + p->nbytes = buflen; at = strchr(src, '@'); slash = strchr(src, '/'); colon = strchr(src, ':'); @@ -134,7 +137,7 @@ iri_parse(const char *src) if(colon && !at) { /* Definitely a scheme */ - p->scheme = bufp; + p->iri.scheme = bufp; while(*src && *src != ':') { src = iri__copychar_decode(&bufp, src, 0); @@ -150,7 +153,7 @@ iri_parse(const char *src) /* This could be scheme://user[;auth][:password]@host or [scheme:]user[;auth][:password]@host (urgh) */ if(colon[1] == '/') { - p->scheme = bufp; + p->iri.scheme = bufp; while(*src && *src != ':') { src = iri__copychar_decode(&bufp, src, 0); @@ -160,11 +163,11 @@ iri_parse(const char *src) src++; /* src[0-1] SHOULD == '/' */ for(; *src == '/'; src++); - p->user = bufp; + p->iri.user = bufp; } else { - p->scheme = bufp; + p->iri.scheme = bufp; } while(*src && *src != ':' && *src != '@' && *src != ';') { @@ -176,7 +179,7 @@ iri_parse(const char *src) { /* Following authentication parameters */ src++; - p->auth = bufp; + p->iri.auth = bufp; while(*src && *src != ':' && *src != '@') { /* Don't decode, so it can be extracted properly */ @@ -189,7 +192,7 @@ iri_parse(const char *src) { /* Following password data */ src++; - p->password = bufp; + p->iri.password = bufp; while(*src && *src != ':' && *src != '@') { src = iri__copychar_decode(&bufp, src, 0); @@ -200,8 +203,8 @@ iri_parse(const char *src) { src++; /* It was actually scheme:user:auth@host */ - p->user = p->auth; - p->password = bufp; + p->iri.user = p->iri.auth; + p->iri.password = bufp; while(*src && *src != '@') { src = iri__copychar_decode(&bufp, src, 0); @@ -223,7 +226,7 @@ iri_parse(const char *src) else if(at) { /* user[;auth]@host[/path...] */ - p->user = bufp; + p->iri.user = bufp; while(*src != '@' && *src != ';') { src = iri__copychar_decode(&bufp, src, 0); @@ -233,7 +236,7 @@ iri_parse(const char *src) if(*src == ';') { src++; - p->auth = bufp; + p->iri.auth = bufp; while(*src && *src != '@') { /* Don't decode, so it can be extracted properly */ @@ -247,7 +250,7 @@ iri_parse(const char *src) src++; } } - p->host = bufp; + p->iri.host = bufp; while(*src && *src != ':' && *src != '/' && *src != '?' && *src != '#') { src = iri__copychar_decode(&bufp, src, 0); @@ -259,12 +262,12 @@ iri_parse(const char *src) /* Port part */ src++; endp = (char *) src; - p->port = strtol(src, &endp, 10); + p->iri.port = strtol(src, &endp, 10); src = endp; } if(*src == '/') { - p->path = bufp; + p->iri.path = bufp; while(*src && *src != '?' && *src != '#') { src = iri__copychar_decode(&bufp, src, 0); @@ -274,7 +277,7 @@ iri_parse(const char *src) } if(*src == '?') { - p->query = bufp; + p->iri.query = bufp; src++; while(*src && *src != '#') { @@ -287,7 +290,7 @@ iri_parse(const char *src) } if(*src == '#') { - p->anchor = bufp; + p->iri.anchor = bufp; while(*src) { src = iri__copychar_decode(&bufp, src, 0); @@ -298,7 +301,7 @@ iri_parse(const char *src) if(*src) { /* Still stuff left? It must be a path... of sorts */ - p->path = bufp; + p->iri.path = bufp; while(*src && *src != '?' && *src != '#') { src = iri__copychar_decode(&bufp, src, 0);