source: XIOS/dev/branch_openmp/extern/src_netcdf4/ocread.c @ 1501

Last change on this file since 1501 was 409, checked in by ymipsl, 11 years ago

Add improved nectdf internal library src

YM

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
2   See the COPYRIGHT file for more information. */
3
4#include "config.h"
5#include <sys/stat.h>
6#ifdef HAVE_UNISTD_H
7#include <unistd.h>
8#endif
9#include <fcntl.h>
10#include <sys/types.h>
11#ifdef HAVE_NETINET_IN_H
12#include <netinet/in.h>
13#endif
14#include "ocinternal.h"
15#include "ocdebug.h"
16#include "ochttp.h"
17#include "ocread.h"
18#include "ocrc.h"
19#include "occurlfunctions.h"
20
21extern int oc_curl_file_supported;
22
23/*Forward*/
24static int readpacket(CURL*, OCURI*, OCbytes*, OCdxd, long*);
25static int readfile(char* path, char* suffix, OCbytes* packet);
26static int readfiletofile(char* path, char* suffix, FILE* stream, unsigned long*);
27
28int
29readDDS(OCstate* state, OCtree* tree)
30{
31    int stat = OC_NOERR;
32    long lastmodified = -1;
33
34
35    ocurisetconstraints(state->uri,tree->constraint);
36
37ocset_user_password(state);
38
39    stat = readpacket(state->curl,state->uri,state->packet,OCDDS,
40                        &lastmodified);
41    if(stat == OC_NOERR) state->ddslastmodified = lastmodified;
42
43    return stat;
44}
45
46int
47readDAS(OCstate* state, OCtree* tree)
48{
49    int stat = OC_NOERR;
50
51    ocurisetconstraints(state->uri,tree->constraint);
52    stat = readpacket(state->curl,state->uri,state->packet,OCDAS,NULL);
53
54    return stat;
55}
56
57int
58readversion(CURL* curl, OCURI* url, OCbytes* packet)
59{
60   return readpacket(curl,url,packet,OCVER,NULL);
61}
62
63static
64char* ocdxdextension[] ={
65".dds",  /*OCDDS*/
66".das",  /*OCDAS*/
67".dods", /*OCDATADDS*/
68".vers", /*OCVERS*/
69};
70
71static int
72readpacket(CURL* curl,OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodified)
73{
74   int stat = OC_NOERR;
75   int fileprotocol = 0;
76   char* suffix = ocdxdextension[dxd];
77   char* fetchurl = NULL;
78
79   fileprotocol = (strcmp(url->protocol,"file")==0);
80
81   if(fileprotocol && !oc_curl_file_supported) {
82        /* Short circuit file://... urls*/
83        /* We do this because the test code always needs to read files*/
84        fetchurl = ocuribuild(url,NULL,NULL,0);
85        stat = readfile(fetchurl,suffix,packet);
86    } else {
87        int flags = 0;
88        if(!fileprotocol) flags |= OCURICONSTRAINTS;
89        flags |= OCURIENCODE;
90        fetchurl = ocuribuild(url,NULL,suffix,flags);
91        MEMCHECK(fetchurl,OC_ENOMEM);
92        if(ocdebug > 0)
93            {fprintf(stderr,"fetch url=%s\n",fetchurl); fflush(stderr);}
94        stat = ocfetchurl(curl,fetchurl,packet,lastmodified);
95        if(ocdebug > 0)
96            {fprintf(stderr,"fetch complete\n"); fflush(stderr);}
97    }
98    free(fetchurl);
99    return OCTHROW(stat);
100}
101
102int
103readDATADDS(OCstate* state, OCtree* tree, OCflags flags)
104{
105    int stat = OC_NOERR;
106    long lastmod = -1;
107
108    if((flags & OCONDISK) == 0) {
109        ocurisetconstraints(state->uri,tree->constraint);
110        stat = readpacket(state->curl,state->uri,state->packet,OCDATADDS,&lastmod);
111        if(stat == OC_NOERR)
112            state->datalastmodified = lastmod;
113        tree->data.datasize = ocbyteslength(state->packet);
114    } else {
115        OCURI* url = state->uri;
116        int fileprotocol = 0;
117        char* readurl = NULL;
118
119        fileprotocol = (strcmp(url->protocol,"file")==0);
120
121        if(fileprotocol && !oc_curl_file_supported) {
122            readurl = ocuribuild(url,NULL,NULL,0);
123            stat = readfiletofile(readurl, ".dods", tree->data.file, &tree->data.datasize);
124        } else {
125            int flags = 0;
126            if(!fileprotocol) flags |= OCURICONSTRAINTS;
127            flags |= OCURIENCODE;
128            ocurisetconstraints(url,tree->constraint);
129            readurl = ocuribuild(url,NULL,".dods",flags);
130            MEMCHECK(readurl,OC_ENOMEM);
131            if (ocdebug > 0) 
132                {fprintf(stderr, "fetch url=%s\n", readurl);fflush(stderr);}
133            stat = ocfetchurl_file(state->curl, readurl, tree->data.file,
134                                   &tree->data.datasize, &lastmod);
135            if(stat == OC_NOERR)
136                state->datalastmodified = lastmod;
137            if (ocdebug > 0) 
138                {fprintf(stderr,"fetch complete\n"); fflush(stderr);}
139        }
140        free(readurl);
141    }
142    return OCTHROW(stat);
143}
144
145static int
146readfiletofile(char* path, char* suffix, FILE* stream, unsigned long* sizep)
147{
148    int stat = OC_NOERR;
149    OCbytes* packet = ocbytesnew();
150    size_t len;
151    /* check for leading file:/// */
152    if(ocstrncmp(path,"file:///",8)==0) path += 7; /* assume absolute path*/
153    stat = readfile(path,suffix,packet);
154    if(stat != OC_NOERR) goto unwind;
155    len = oclistlength(packet);
156    if(stat == OC_NOERR) {
157        size_t written;
158        fseek(stream,0,SEEK_SET);
159        written = fwrite(ocbytescontents(packet),1,len,stream);
160        if(written != len) stat = OC_EIO;
161    }
162    if(sizep != NULL) *sizep = len;
163unwind:
164    ocbytesfree(packet);
165    return OCTHROW(stat);
166}
167
168static int
169readfile(char* path, char* suffix, OCbytes* packet)
170{
171    int stat = OC_NOERR;
172    char buf[1024];
173    char filename[1024];
174    int count,size,fd;
175    /* check for leading file:/// */
176    if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/
177    strcpy(filename,path);
178    if(suffix != NULL) strcat(filename,suffix);
179    fd = open(filename,O_RDONLY);
180    if(fd < 0) {
181        oc_log(LOGERR,"open failed:%s",filename);
182        return OCTHROW(OC_EOPEN);
183    }
184    size=0;
185    stat = OC_NOERR;
186    for(;;) {
187        count = read(fd,buf,sizeof(buf));
188        if(count <= 0)
189            break;
190        else if(count <  0) {
191            stat = OC_EIO;
192            oc_log(LOGERR,"read failed: %s",filename);
193            break;
194        }
195        ocbytesappendn(packet,buf,count);
196        size += count;
197    }
198    close(fd);
199    return OCTHROW(stat);
200}
201
202
Note: See TracBrowser for help on using the repository browser.