netcdf-c/oc/dapurl.c
2010-06-03 13:24:43 +00:00

213 lines
5.3 KiB
C

/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
See the COPYRIGHT file for more information. */
#include "oclist.h"
#include "ocinternal.h"
#include "occlientparams.h"
#include "ocdebug.h"
#define LBRACKET '['
#define RBRACKET ']'
static char* legalprotocols[] = {
"file:",
"http:",
"https:",
"ftp:",
NULL /* NULL terminate*/
};
/* Do a simple url parse*/
int
dapurlparse(const char* url0, DAPURL* dapurl)
{
char* url;
char** pp;
char* p;
char* p1;
int c;
/* accumulate parse points*/
char* protocol = NULL;
char* params = NULL;
char* baseurl = NULL;
char* constraints = NULL;
char* stop;
memset((void*)dapurl,0,sizeof(DAPURL));
/* copy url and remove all whitespace*/
url = strdup(url0);
p = url;
p1 = url;
while((c=*p1++)) {if(c != ' ' && c != '\t') *p++ = c;}
p = url;
stop = p + strlen(p);
/* break up the url string into pieces*/
if(*p == LBRACKET) {
params = p+1;
/* find end of the clientparams*/
for(;*p;p++) {if(p[0] == RBRACKET && p[1] != LBRACKET) break;}
if(*p == 0) goto fail; /* malformed client params*/
*p = '\0'; /* leave off the trailing rbracket for now */
p++; /* move past the params*/
}
/* verify that the url starts with an acceptable protocol*/
for(pp=legalprotocols;*pp;pp++) {
if(strncmp(p,*pp,strlen(*pp))==0) break;
}
if(*pp == NULL) goto fail; /* illegal protocol*/
/* save the protocol */
protocol = *pp;
baseurl = p;
/* Look for '?' */
constraints = strchr(p,'?');
if(constraints) {
*constraints++ = '\0';
}
/* assemble the component pieces*/
dapurl->url = strdup(url0);
dapurl->base = strdup(baseurl);
dapurl->protocol = strdup(protocol);
/* remove trailing ':' */
dapurl->protocol[strlen(protocol)-1] = '\0';
dapurlsetconstraints(dapurl,constraints);
if(params != NULL) {
dapurl->params = (char*)ocmalloc(1+2+strlen(params));
strcpy(dapurl->params,"[");
strcat(dapurl->params,params);
strcat(dapurl->params,"]");
}
if(ocdebug) {
fprintf(stderr,"dapurl: params=|%s| base=|%s| projection=|%s| selection=|%s|\n",
dapurl->params, dapurl->base, dapurl->projection, dapurl->selection);
}
free(url);
return 1;
fail:
if(url != NULL) free(url);
return 0;
}
/* Call must free the actual url instance.*/
void
dapurlclear(DAPURL* dapurl)
{
if(dapurl->url != NULL) {free(dapurl->url);}
if(dapurl->base != NULL) {free(dapurl->base);}
if(dapurl->protocol != NULL) {free(dapurl->protocol);}
if(dapurl->projection != NULL) {free(dapurl->projection);}
if(dapurl->selection != NULL) {free(dapurl->selection);}
if(dapurl->params != NULL) {free(dapurl->params);}
if(dapurl->paramlist != NULL) ocparamfree(dapurl->paramlist);
memset((void*)dapurl,0,sizeof(DAPURL));
}
/* Replace the constraints */
void
dapurlsetconstraints(DAPURL* durl,const char* constraints)
{
char* proj = NULL;
char* select = NULL;
const char* p;
if(durl->projection != NULL) ocfree(durl->projection);
if(durl->selection != NULL) ocfree(durl->selection);
durl->projection = NULL;
durl->selection = NULL;
if(constraints == NULL || strlen(constraints)==0) return;
p = constraints;
if(p[0] == '?') p++;
proj = (char*) p;
select = strchr(proj,'&');
if(select != NULL) {
size_t plen = (select - proj);
if(plen == 0) {
proj = NULL;
} else {
proj = (char*)ocmalloc(plen+1);
memcpy((void*)proj,p,plen);
proj[plen] = '\0';
}
select = strdup(select);
} else {
proj = strdup(proj);
select = NULL;
}
durl->projection = proj;
durl->selection = select;
}
/* Construct a complete DAP URL without the client params
and optionally with the constraints;
caller frees returned string
*/
char*
dapurlgeturl(DAPURL* durl, const char* prefix, const char* suffix,
int withconstraints)
{
size_t len = 0;
char* newurl;
len += strlen(durl->base);
if(prefix != NULL) len += strlen(prefix);
if(suffix != NULL) len += strlen(suffix);
if(withconstraints
&& (durl->projection != NULL || durl->selection != NULL)) {
len += 1; /* leading '?' */
if(durl->projection != NULL) len += strlen(durl->projection);
if(durl->selection != NULL) len += strlen(durl->selection);
}
len += 1; /* null terminator */
newurl = (char*)ocmalloc(len);
if(!newurl) return NULL;
newurl[0] = '\0';
if(prefix != NULL) strcat(newurl,prefix);
strcat(newurl,durl->base);
if(suffix != NULL) strcat(newurl,suffix);
if(withconstraints
&& (durl->projection != NULL || durl->selection != NULL)) {
strcat(newurl,"?");
if(durl->projection != NULL) strcat(newurl,durl->projection);
if(durl->selection != NULL) strcat(newurl,durl->selection);
}
return newurl;
}
int
dapurldecodeparams(DAPURL* dapurl)
{
int ok = 0;
if(dapurl->paramlist == NULL && dapurl->params != NULL) {
OClist* list = ocparamdecode(dapurl->params);
dapurl->paramlist = list;
ok = 1;
}
return ok;
}
/*! NULL result => entry not found.
Empty value should be represented as a zero length string */
const char*
dapurllookup(DAPURL* durl, const char* clientparam)
{
/* make sure that durl->paramlist exists */
if(durl->paramlist == NULL) dapurldecodeparams(durl);
return ocparamlookup(durl->paramlist,clientparam);
}