source: XIOS/dev/branch_openmp/extern/src_netcdf4/ddispatch.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.6 KB
Line 
1#include "ncdispatch.h"
2#include "nc_uri.h"
3
4extern int NCSUBSTRATE_intialize(void);
5
6/* Define vectors of zeros and ones for use with various nc_get_varX function*/
7size_t nc_sizevector0[NC_MAX_DIMS];
8size_t nc_sizevector1[NC_MAX_DIMS];
9ptrdiff_t nc_ptrdiffvector1[NC_MAX_DIMS];
10
11/* Define the known protocols and their manipulations */
12static struct NCPROTOCOLLIST {
13    char* protocol;
14    char* substitute;
15    int   modelflags;
16} ncprotolist[] = {
17    {"http",NULL,0},
18    {"https",NULL,0},
19    {"file",NULL,NC_DISPATCH_NCD},
20    {"dods","http",NC_DISPATCH_NCD},
21    {"dodss","https",NC_DISPATCH_NCD},
22    {"cdmr","http",NC_DISPATCH_NCR|NC_DISPATCH_NC4},
23    {"cdmrs","https",NC_DISPATCH_NCR|NC_DISPATCH_NC4},
24    {"cdmremote","http",NC_DISPATCH_NCR|NC_DISPATCH_NC4},
25    {"cdmremotes","https",NC_DISPATCH_NCR|NC_DISPATCH_NC4},
26    {NULL,NULL,0} /* Terminate search */
27};
28
29/* Define the server to ping in order;
30   make the order attempt to optimize
31   against future changes.
32*/
33static const char* servers[] = {
34"http://motherlode.ucar.edu:8081", /* try this first */
35"http://remotetest.unidata.ucar.edu",
36"http://remotetest.ucar.edu",
37"http://motherlode.ucar.edu:8080",
38"http://motherlode.ucar.edu",
39"http://remotetests.unidata.ucar.edu",
40"http://remotetests.ucar.edu",
41NULL
42};
43
44/*
45static nc_type longtype = (sizeof(long) == sizeof(int)?NC_INT:NC_INT64);
46static nc_type ulongtype = (sizeof(unsigned long) == sizeof(unsigned int)?NC_UINT:NC_UINT64);
47*/
48
49/* Allow dispatch to do initialization */
50int
51NCDISPATCH_initialize(void)
52{
53    extern int NCSUBSTRATE_initialize(void);
54    int i;
55    NCSUBSTRATE_initialize();
56    for(i=0;i<NC_MAX_VAR_DIMS;i++) {
57        nc_sizevector0[i] = 0;
58        nc_sizevector1[i] = 1;
59        nc_ptrdiffvector1[i] = 1;
60    }
61    return NC_NOERR;
62}
63
64/* search list of servers and return first that succeeds when
65   concatenated with the specified path part
66*/
67const char*
68NC_findtestserver(const char* path)
69{
70#ifdef USE_DAP
71    /* NCDAP_ping is defined in libdap2/ncdap3.c */
72    const char** svc;
73    if(path == NULL) path = "";
74    for(svc=servers;*svc != NULL;svc++) {
75        int stat;
76        char url[4096];
77        snprintf(url,sizeof(url),"%s%s%s",
78                        *svc,
79                        (path[0] == '/' ? "" : "/"),
80                        path);
81        stat = NCDAP_ping(url);
82        if(stat == NC_NOERR)
83            return *svc;
84    }
85#endif
86    return NULL;
87}
88
89
90/* return 1 if path looks like a url; 0 otherwise */
91int
92NC_testurl(const char* path)
93{
94    int isurl = 0;
95    NC_URI* tmpurl = NULL;
96    char* p;
97
98    if(path == NULL) return 0;
99
100    /* find leading non-blank */
101    for(p=(char*)path;*p;p++) {if(*p != ' ') break;}
102
103    /* Do some initial checking to see if this looks like a file path */
104    if(*p == '/') return 0; /* probably an absolute file path */
105
106    /* Ok, try to parse as a url */
107    if(nc_uriparse(path,&tmpurl)) {
108        /* Do some extra testing to make sure this really is a url */
109        /* Look for a knownprotocol */
110        struct NCPROTOCOLLIST* protolist;
111        for(protolist=ncprotolist;protolist->protocol;protolist++) {
112            if(strcmp(tmpurl->protocol,protolist->protocol) == 0) {
113                isurl=1;
114                break;
115            }           
116        }
117        nc_urifree(tmpurl);
118        return isurl;
119    }
120    return 0;
121}
122
123/*
124Return the OR of some of the NC_DISPATCH flags
125Assumes that the path is known to be a url
126*/
127
128int
129NC_urlmodel(const char* path)
130{
131    int model = 0;
132    NC_URI* tmpurl = NULL;
133    struct NCPROTOCOLLIST* protolist;
134
135    if(!nc_uriparse(path,&tmpurl)) goto done;
136
137    /* Look at any prefixed parameters */
138    if(nc_urilookup(tmpurl,"netcdf4",NULL)
139       || nc_urilookup(tmpurl,"netcdf-4",NULL)) {
140        model = (NC_DISPATCH_NC4|NC_DISPATCH_NCD);
141    } else if(nc_urilookup(tmpurl,"netcdf3",NULL)
142              || nc_urilookup(tmpurl,"netcdf-3",NULL)) {
143        model = (NC_DISPATCH_NC3|NC_DISPATCH_NCD);
144    } else if(nc_urilookup(tmpurl,"cdmremote",NULL)
145              || nc_urilookup(tmpurl,"cdmr",NULL)) {
146        model = (NC_DISPATCH_NCR|NC_DISPATCH_NC4);
147    }
148
149    if(model == 0) {
150        /* Now look at the protocol */
151        for(protolist=ncprotolist;protolist->protocol;protolist++) {
152            if(strcmp(tmpurl->protocol,protolist->protocol) == 0) {
153                model |= protolist->modelflags;
154                if(protolist->substitute) {
155                    if(tmpurl->protocol) free(tmpurl->protocol);
156                    tmpurl->protocol = strdup(protolist->substitute);
157                }
158                break;     
159            }
160        }
161    }   
162
163    /* Force NC_DISPATCH_NC3 if necessary */
164    if((model & NC_DISPATCH_NC4) == 0)
165        model |= (NC_DISPATCH_NC3 | NC_DISPATCH_NCD);
166
167done:
168    nc_urifree(tmpurl);
169    return model;
170}
171
172/* Override dispatch table management */
173static NC_Dispatch* NC_dispatch_override = NULL;
174
175/* Override dispatch table management */
176NC_Dispatch*
177NC_get_dispatch_override(void) {
178    return NC_dispatch_override;
179}
180
181void NC_set_dispatch_override(NC_Dispatch* d)
182{
183    NC_dispatch_override = d;
184}
185
186/* Overlay by treating the tables as arrays of void*.
187   Overlay rules are:
188        overlay    base    merge
189        -------    ----    -----
190          null     null     null
191          null      y        y
192           x       null      x
193           x        y        x
194*/
195
196int
197NC_dispatch_overlay(const NC_Dispatch* overlay, const NC_Dispatch* base, NC_Dispatch* merge)
198{
199    void** voverlay = (void**)overlay;
200    void** vmerge;
201    int i, count = sizeof(NC_Dispatch) / sizeof(void*);
202    /* dispatch table must be exact multiple of sizeof(void*) */
203    assert(count * sizeof(void*) == sizeof(NC_Dispatch));
204    *merge = *base;
205    vmerge = (void**)merge;
206    for(i=0;i<count;i++) {
207        if(voverlay[i] == NULL) continue;
208        vmerge[i] = voverlay[i];
209    }
210    /* Finally, the merge model should always be the overlay model */
211    merge->model = overlay->model;
212    return NC_NOERR;
213}
Note: See TracBrowser for help on using the repository browser.