/* return 1 if path looks like a url; 0 otherwise */ int NC_testurl(const char* path) { int isurl = 0; NC_URL* tmpurl = NULL; char* p; if(path == NULL) return 0; /* find leading non-blank */ for(p=path;*p;p++) {if(*p != ' ') break;} /* Do some initial checking to see if this looks like a file path */ if(*p == '/') return 0; /* probably an absolute file path */ /* Ok, try to parse as a url */ if(nc_urlparse(path,&tmpurl) == NC_NOERR) { /* Do some extra testing to make sure this really is a url */ /* Look for a knownprotocol */ struct NCPROTOCOLLIST* protolist; for(protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(tmpurl->protocol,protolist->protocol) == 0) { isurl=1; break; } } nc_urlfree(tmpurl); return isurl; } return 0; }
int NC_urlmodel(const char* path) { int model = 0; NC_URL* tmpurl = NULL; struct NCPROTOCOLLIST* protolist; if(nc_urlparse(path,&tmpurl) != NC_NOERR) goto done; /* Look at any prefixed parameters */ if(nc_urllookup(tmpurl,"netcdf4") || nc_urllookup(tmpurl,"netcdf-4")) { model = (NC_DISPATCH_NC4|NC_DISPATCH_NCD); } else if(nc_urllookup(tmpurl,"netcdf3") || nc_urllookup(tmpurl,"netcdf-3")) { model = (NC_DISPATCH_NC3|NC_DISPATCH_NCD); } else if(nc_urllookup(tmpurl,"cdmremote") || nc_urllookup(tmpurl,"cdmr")) { model = (NC_DISPATCH_NCR|NC_DISPATCH_NC4); } /* Now look at the protocol */ for(protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(tmpurl->protocol,protolist->protocol) == 0) { model |= protolist->modelflags; if(protolist->substitute) nc_urlsetprotocol(tmpurl,protolist->substitute); break; } } /* Force NC_DISPATCH_NC3 if necessary */ if((model & NC_DISPATCH_NC4) == 0) model |= (NC_DISPATCH_NC3 | NC_DISPATCH_NCD); done: nc_urlfree(tmpurl); return model; }
/* See ncd4dispatch.c for other version */ int NCCR_open(const char * path, int mode, int basepe, size_t *chunksizehintp, int useparallel, void* mpidata, NC_Dispatch* dispatch, NC** ncpp) { NCerror ncstat = NC_NOERR; NC_URL* tmpurl; NCCR* nccr = NULL; /* reuse the ncdap3 structure*/ NCCDMR* cdmr = NULL; NC_HDF5_FILE_INFO_T* h5 = NULL; NC_GRP_INFO_T *grp = NULL; int ncid = -1; int fd; char* tmpname = NULL; NClist* shows; bytes_t buf; long filetime; ast_runtime* rt = NULL; ast_err aststat = AST_NOERR; Header* hdr = NULL; LOG((1, "nc_open_file: path %s mode %d", path, mode)); if(nc_urlparse(path,&tmpurl) != NC_NOERR) PANIC("libcdmr: non-url path"); nc_urlfree(tmpurl); /* no longer needed */ /* Check for legal mode flags */ if((mode & NC_WRITE) != 0) ncstat = NC_EINVAL; else if(mode & (NC_WRITE|NC_CLOBBER)) ncstat = NC_EPERM; if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} mode = (mode & ~(NC_MPIIO | NC_MPIPOSIX)); /* Despite the above check, we want the file to be initially writable */ mode |= (NC_WRITE|NC_CLOBBER); /* Use NCCR code to establish a pseudo file */ tmpname = nulldup(PSEUDOFILE); fd = mkstemp(tmpname); if(fd < 0) {THROWCHK(errno); goto done;} /* Now, use the file to create the hdf5 file */ ncstat = NC4_create(tmpname,NC_NETCDF4|NC_CLOBBER, 0,0,NULL,0,NULL,dispatch,(NC**)&nccr); ncid = nccr->info.ext_ncid; /* unlink the temp file so it will automatically be reclaimed */ unlink(tmpname); free(tmpname); /* Avoid fill */ dispatch->set_fill(ncid,NC_NOFILL,NULL); if(ncstat) {THROWCHK(ncstat); goto done;} /* Find our metadata for this file. */ ncstat = nc4_find_nc_grp_h5(ncid, (NC_FILE_INFO_T**)&nccr, &grp, &h5); if(ncstat) {THROWCHK(ncstat); goto done;} /* Setup tentative NCCR state*/ nccr->info.dispatch = dispatch; cdmr = (NCCDMR*)calloc(1,sizeof(NCCDMR)); if(cdmr == NULL) {ncstat = NC_ENOMEM; goto done;} nccr->cdmr = cdmr; nccr->cdmr->controller = (NC*)nccr; nccr->cdmr->urltext = nulldup(path); nc_urlparse(nccr->cdmr->urltext,&nccr->cdmr->url); /* Create the curl connection (does not make the server connection)*/ ncstat = nccr_curlopen(&nccr->cdmr->curl.curl); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} shows = nc_urllookup(nccr->cdmr->url,"show"); if(nc_urllookupvalue(shows,"fetch")) nccr->cdmr->controls |= SHOWFETCH; /* Parse the projection */ /* fetch meta data */ buf = bytes_t_null; NCbytes* completeurl = ncbytesnew(); ncbytescat(completeurl,nccr->cdmr->url->url); ncbytescat(completeurl,"?req=header"); ncstat = nccr_fetchurl(nccr->cdmr->curl.curl,ncbytescontents(completeurl), &buf,&filetime); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Parse the meta data */ ncstat = nccr_decodeheader(&buf,&hdr); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} if(buf.bytes != NULL) free(buf.bytes); /* Compute various things about the Header tree */ /* Collect all nodes and fill in the CRnode part*/ cdmr->nodeset = nclistnew(); ncstat = nccr_walk_Header(hdr,cdmr->nodeset); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Compute the pathnames */ ncstat = nccr_compute_pathnames(cdmr->nodeset); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Map dimension references to matching declaration */ ncstat = nccr_map_dimensions(cdmr->nodeset); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Replace dimension references with matching declaration */ nccr_deref_dimensions(cdmr->nodeset); /* Elide any variables not in the url projection */ ncstat = nccr_elide_vars(cdmr); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* build the meta data */ ncstat = nccr_buildnc(nccr,hdr); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Mark as no longer indef and no longer writable*/ h5->flags &= ~(NC_INDEF); h5->no_write = 1; done: if(aststat != AST_NOERR) {ncstat = nccr_cvtasterr(aststat);} if(ncstat) { if(nccr != NULL) { int ncid = nccr->info.ext_ncid; NCCR_abort(ncid); } } else { if(ncpp) *ncpp = (NC*)nccr; } return THROW(ncstat); }