mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-21 08:39:46 +08:00
591 lines
13 KiB
Plaintext
591 lines
13 KiB
Plaintext
/*
|
|
Copyright 2018 University Corporation for Atmospheric
|
|
Research/Unidata. See COPYRIGHT file for more info.
|
|
|
|
This file defines most of the netcdf API in terms of the dispatch
|
|
functions along with a few functions that are overlays over the
|
|
dispatch functions.
|
|
|
|
"$Id: netcdf.m4,v 1.16 2010/06/01 15:34:50 ed Exp $"
|
|
*/
|
|
|
|
#include "ncdispatch.h"
|
|
#define INITCOORD1 if(coord_one[0] != 1) {int i; for(i=0;i<NC_MAX_VAR_DIMS;i++) coord_one[i] = 1;}
|
|
|
|
static nc_type longtype = (sizeof(long) == sizeof(int)?NC_INT:NC_INT64);
|
|
/*static nc_type ulongtype = (sizeof(unsigned long) == sizeof(unsigned int)?NC_UINT:NC_UINT64);*/
|
|
|
|
NC_Dispatch* NC3_dispatch_table = NULL;
|
|
|
|
#ifdef USE_NETCDF4
|
|
NC_Dispatch* NC4_dispatch_table = NULL;
|
|
#endif
|
|
|
|
#ifdef USE_DAP
|
|
NC_Dispatch* NCD2_dispatch_table = NULL;
|
|
#endif
|
|
|
|
#ifndef NC_ENOTNC4
|
|
#define NC_ENOTNC4 (-111)
|
|
#endif
|
|
|
|
#ifndef X_INT_MAX
|
|
#define X_INT_MAX 2147483647
|
|
#endif
|
|
|
|
|
|
/**************************************************/
|
|
|
|
int
|
|
NC_testurl(const char* path)
|
|
{
|
|
#ifdef USE_DAP
|
|
void* tmpurl = NULL;
|
|
if(NCDAP_urlparse(path,&tmpurl) == NC_NOERR) {
|
|
NCDAP_urlfree(tmpurl);
|
|
return 1;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
NC_urlmodel(const char* path)
|
|
{
|
|
int model = 0;
|
|
#ifdef USE_DAP
|
|
void* tmpurl = NULL;
|
|
if(NCDAP_urlparse(path,&tmpurl) == NC_NOERR) {
|
|
if(NCDAP_urllookup(tmpurl,"netcdf4")
|
|
|| NCDAP_urllookup(tmpurl,"netcdf-4")) {
|
|
model = 4;
|
|
} else if(NCDAP_urllookup(tmpurl,"netcdf3")
|
|
|| NCDAP_urllookup(tmpurl,"netcdf-3")) {
|
|
model = 3;
|
|
} else {
|
|
model = 0;
|
|
}
|
|
NCDAP_urlfree(tmpurl);
|
|
}
|
|
#endif
|
|
return model;
|
|
}
|
|
|
|
/* Override dispatch table management */
|
|
static NC_Dispatch* NC_dispatch_override = NULL;
|
|
|
|
/* Override dispatch table management */
|
|
NC_Dispatch*
|
|
NC_get_dispatch_override(void) {
|
|
return NC_dispatch_override;
|
|
}
|
|
|
|
void NC_set_dispatch_override(NC_Dispatch* d)
|
|
{
|
|
NC_dispatch_override = d;
|
|
}
|
|
|
|
/**************************************************/
|
|
/* Wrapper */
|
|
|
|
|
|
/* Overlay by treating the tables as arrays of void*.
|
|
Overlay rules are:
|
|
overlay base merge
|
|
------- ---- -----
|
|
null null null
|
|
null y y
|
|
x null x
|
|
x y x
|
|
*/
|
|
|
|
int
|
|
NC_dispatch_overlay(const NC_Dispatch* overlay, const NC_Dispatch* base, NC_Dispatch* merge)
|
|
{
|
|
void** voverlay = (void**)overlay;
|
|
void** vmerge;
|
|
int i, count = sizeof(NC_Dispatch) / sizeof(void*);
|
|
/* dispatch table must be exact multiple of sizeof(void*) */
|
|
assert(count * sizeof(void*) == sizeof(NC_Dispatch));
|
|
*merge = *base;
|
|
vmerge = (void**)merge;
|
|
for(i=0;i<count;i++) {
|
|
if(voverlay[i] == NULL) continue;
|
|
vmerge[i] = voverlay[i];
|
|
}
|
|
/* Finally, the merge model should always be the overlay model */
|
|
merge->model = overlay->model;
|
|
return NC_NOERR;
|
|
}
|
|
|
|
/**************************************************/
|
|
/* Output type specific interface */
|
|
|
|
/* Public */
|
|
|
|
/**************************************************/
|
|
|
|
/**************************************************/
|
|
|
|
#ifdef USE_DAP
|
|
|
|
/* allow access to nc_urlparse and params while minimizing exposing nc.h */
|
|
int
|
|
NCDAP_urlparse(const char* s, void** dapurlp)
|
|
{
|
|
DAPURL* dapurl = NULL;
|
|
dapurl = calloc(1,sizeof(DAPURL));
|
|
if(dapurl == 0) return NC_ENOMEM;
|
|
if(!dapurlparse(s,dapurl)) {
|
|
dapurlclear(dapurl);
|
|
free(dapurl);
|
|
return NC_EINVAL;
|
|
}
|
|
if(dapurlp) *dapurlp = dapurl;
|
|
return NC_NOERR;
|
|
}
|
|
|
|
void
|
|
NCDAP_urlfree(void* durl)
|
|
{
|
|
DAPURL* dapurl = (DAPURL*)durl;
|
|
if(dapurl != NULL) {
|
|
dapurlclear(dapurl);
|
|
free(dapurl);
|
|
}
|
|
}
|
|
|
|
const char*
|
|
NCDAP_urllookup(void* durl, const char* param)
|
|
{
|
|
DAPURL* dapurl = (DAPURL*)durl;
|
|
if(param == NULL || strlen(param) == 0 || dapurl == NULL) return NULL;
|
|
return dapurllookup(dapurl,param);
|
|
}
|
|
|
|
#else /*!USE_DAP*/
|
|
int
|
|
NCDAP_urlparse(const char* s, void** dapurlp)
|
|
{
|
|
return NC_EINVAL;
|
|
}
|
|
|
|
void
|
|
NCDAP_urlfree(void* durl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const char*
|
|
NCDAP_urllookup(void* durl, const char* param)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
#endif /*!USE_DAP*/
|
|
|
|
/**************************************************/
|
|
/* M4 generated */
|
|
dnl
|
|
dnl NCGETVAR1(Abbrev, Type)
|
|
dnl
|
|
define(`NCGETVAR1',dnl
|
|
`dnl
|
|
int
|
|
nc_get_var1_$1(int ncid, int varid, const size_t *coord, $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
INITCOORD1;
|
|
return NC_get_var1(ncid,varid,coord,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCGETVAR1(text,char)
|
|
NCGETVAR1(schar,signed char)
|
|
NCGETVAR1(uchar,unsigned char)
|
|
NCGETVAR1(short,short)
|
|
NCGETVAR1(int,int)
|
|
NCGETVAR1(long,long)
|
|
dnl NCGETVAR1(ulong,ulong)
|
|
NCGETVAR1(float,float)
|
|
NCGETVAR1(double,double)
|
|
NCGETVAR1(ubyte,unsigned char)
|
|
NCGETVAR1(ushort,unsigned short)
|
|
NCGETVAR1(uint,unsigned int)
|
|
NCGETVAR1(longlong,long long)
|
|
NCGETVAR1(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCGETVAR1(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCPUTVAR1(Abbrev, Type)
|
|
dnl
|
|
define(`NCPUTVAR1',dnl
|
|
`dnl
|
|
int
|
|
nc_put_var1_$1(int ncid, int varid, const size_t *coord, const $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
INITCOORD1;
|
|
return NC_put_var1(ncid,varid,coord,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCPUTVAR1(text,char)
|
|
NCPUTVAR1(schar,signed char)
|
|
NCPUTVAR1(uchar,unsigned char)
|
|
NCPUTVAR1(short,short)
|
|
NCPUTVAR1(int,int)
|
|
NCPUTVAR1(long,long)
|
|
dnl NCPUTVAR1(ulong,ulong)
|
|
NCPUTVAR1(float,float)
|
|
NCPUTVAR1(double,double)
|
|
NCPUTVAR1(ubyte,unsigned char)
|
|
NCPUTVAR1(ushort,unsigned short)
|
|
NCPUTVAR1(uint,unsigned int)
|
|
NCPUTVAR1(longlong,long long)
|
|
NCPUTVAR1(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCPUTVAR1(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCGETVAR(Abbrev, Type)
|
|
dnl
|
|
define(`NCGETVAR',dnl
|
|
`dnl
|
|
int
|
|
nc_get_var_$1(int ncid, int varid, $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_get_var(ncid,varid,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCGETVAR(text,char)
|
|
NCGETVAR(schar,signed char)
|
|
NCGETVAR(uchar,unsigned char)
|
|
NCGETVAR(short,short)
|
|
NCGETVAR(int,int)
|
|
NCGETVAR(long,long)
|
|
dnl NCGETVAR(ulong,ulong)
|
|
NCGETVAR(float,float)
|
|
NCGETVAR(double,double)
|
|
NCGETVAR(ubyte,unsigned char)
|
|
NCGETVAR(ushort,unsigned short)
|
|
NCGETVAR(uint,unsigned int)
|
|
NCGETVAR(longlong,long long)
|
|
NCGETVAR(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCGETVAR(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCPUTVAR(Abbrev, Type)
|
|
dnl
|
|
define(`NCPUTVAR',dnl
|
|
`dnl
|
|
int
|
|
nc_put_var_$1(int ncid, int varid, const $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_put_var(ncid,varid,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCPUTVAR(text,char)
|
|
NCPUTVAR(schar,signed char)
|
|
NCPUTVAR(uchar,unsigned char)
|
|
NCPUTVAR(short,short)
|
|
NCPUTVAR(int,int)
|
|
NCPUTVAR(long,long)
|
|
dnl NCPUTVAR(ulong,ulong)
|
|
NCPUTVAR(float,float)
|
|
NCPUTVAR(double,double)
|
|
NCPUTVAR(ubyte,unsigned char)
|
|
NCPUTVAR(ushort,unsigned short)
|
|
NCPUTVAR(uint,unsigned int)
|
|
NCPUTVAR(longlong,long long)
|
|
NCPUTVAR(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCPUTVAR(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
|
|
dnl
|
|
dnl NCPUTVARA(Abbrv, Type)
|
|
dnl
|
|
define(`NCPUTVARA',dnl
|
|
`dnl
|
|
int
|
|
nc_put_vara_$1(int ncid, int varid,
|
|
const size_t *start, const size_t *edges, const $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_put_vara(ncid,varid,start,edges,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCPUTVARA(text,char)
|
|
NCPUTVARA(schar,signed char)
|
|
NCPUTVARA(uchar,unsigned char)
|
|
NCPUTVARA(short,short)
|
|
NCPUTVARA(int,int)
|
|
NCPUTVARA(long,long)
|
|
dnl NCPUTVARA(ulong,ulong)
|
|
NCPUTVARA(float,float)
|
|
NCPUTVARA(double,double)
|
|
NCPUTVARA(ubyte,unsigned char)
|
|
NCPUTVARA(ushort,unsigned short)
|
|
NCPUTVARA(uint,unsigned int)
|
|
NCPUTVARA(longlong,long long)
|
|
NCPUTVARA(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCPUTVARA(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCGETVARA(Abbrv, Type)
|
|
dnl
|
|
define(`NCGETVARA',dnl
|
|
`dnl
|
|
int
|
|
nc_get_vara_$1(int ncid, int varid,
|
|
const size_t *start, const size_t *edges, $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_get_vara(ncid,varid,start,edges,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCGETVARA(text,char)
|
|
NCGETVARA(schar,signed char)
|
|
NCGETVARA(uchar,unsigned char)
|
|
NCGETVARA(short,short)
|
|
NCGETVARA(int,int)
|
|
NCGETVARA(long,long)
|
|
dnl NCGETVARA(ulong,ulong)
|
|
NCGETVARA(float,float)
|
|
NCGETVARA(double,double)
|
|
NCGETVARA(ubyte,unsigned char)
|
|
NCGETVARA(ushort,unsigned short)
|
|
NCGETVARA(uint,unsigned int)
|
|
NCGETVARA(longlong,long long)
|
|
NCGETVARA(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCGETVARA(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCPUTVARM(Abbrv, Type)
|
|
dnl
|
|
define(`NCPUTVARM',dnl
|
|
`dnl
|
|
int
|
|
nc_put_varm_$1(int ncid, int varid,
|
|
const size_t *start, const size_t *edges,
|
|
const ptrdiff_t * stride, const ptrdiff_t * imapp,
|
|
const $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_put_varm(ncid,varid,start,edges,stride,imapp,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCPUTVARM(text,char)
|
|
NCPUTVARM(schar,signed char)
|
|
NCPUTVARM(uchar,unsigned char)
|
|
NCPUTVARM(short,short)
|
|
NCPUTVARM(int,int)
|
|
NCPUTVARM(long,long)
|
|
dnl NCPUTVARM(ulong,ulong)
|
|
NCPUTVARM(float,float)
|
|
NCPUTVARM(double,double)
|
|
NCPUTVARM(ubyte,unsigned char)
|
|
NCPUTVARM(ushort,unsigned short)
|
|
NCPUTVARM(uint,unsigned int)
|
|
NCPUTVARM(longlong,long long)
|
|
NCPUTVARM(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCPUTVARM(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCGETVARM(Abbrv, Type)
|
|
dnl
|
|
define(`NCGETVARM',dnl
|
|
`dnl
|
|
int
|
|
nc_get_varm_$1(int ncid, int varid,
|
|
const size_t *start, const size_t *edges,
|
|
const ptrdiff_t * stride, const ptrdiff_t * imapp,
|
|
$2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_get_varm(ncid,varid,start,edges,stride,imapp,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCGETVARM(text,char)
|
|
NCGETVARM(schar,signed char)
|
|
NCGETVARM(uchar,unsigned char)
|
|
NCGETVARM(short,short)
|
|
NCGETVARM(int,int)
|
|
NCGETVARM(long,long)
|
|
dnl NCGETVARM(ulong,ulong)
|
|
NCGETVARM(float,float)
|
|
NCGETVARM(double,double)
|
|
NCGETVARM(ubyte,unsigned char)
|
|
NCGETVARM(ushort,unsigned short)
|
|
NCGETVARM(uint,unsigned int)
|
|
NCGETVARM(longlong,long long)
|
|
NCGETVARM(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCGETVARM(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCPUTVARS(Abbrv, Type)
|
|
dnl
|
|
define(`NCPUTVARS',dnl
|
|
`dnl
|
|
int
|
|
nc_put_vars_$1(int ncid, int varid,
|
|
const size_t *start, const size_t *edges,
|
|
const ptrdiff_t * stride,
|
|
const $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_put_vars(ncid,varid,start,edges,stride,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCPUTVARS(text,char)
|
|
NCPUTVARS(schar,signed char)
|
|
NCPUTVARS(uchar,unsigned char)
|
|
NCPUTVARS(short,short)
|
|
NCPUTVARS(int,int)
|
|
NCPUTVARS(long,long)
|
|
dnl NCPUTVARS(ulong,ulong)
|
|
NCPUTVARS(float,float)
|
|
NCPUTVARS(double,double)
|
|
NCPUTVARS(ubyte,unsigned char)
|
|
NCPUTVARS(ushort,unsigned short)
|
|
NCPUTVARS(uint,unsigned int)
|
|
NCPUTVARS(longlong,long long)
|
|
NCPUTVARS(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCPUTVARS(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
dnl
|
|
dnl NCGETVARS(Abbrv, Type)
|
|
dnl
|
|
define(`NCGETVARS',dnl
|
|
`dnl
|
|
int
|
|
nc_get_vars_$1(int ncid, int varid,
|
|
const size_t *start, const size_t *edges,
|
|
const ptrdiff_t * stride,
|
|
$2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return NC_get_vars(ncid,varid,start,edges,stride,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NCGETVARS(text,char)
|
|
NCGETVARS(schar,signed char)
|
|
NCGETVARS(uchar,unsigned char)
|
|
NCGETVARS(short,short)
|
|
NCGETVARS(int,int)
|
|
NCGETVARS(long,long)
|
|
dnl NCGETVARS(ulong,ulong)
|
|
NCGETVARS(float,float)
|
|
NCGETVARS(double,double)
|
|
NCGETVARS(ubyte,unsigned char)
|
|
NCGETVARS(ushort,unsigned short)
|
|
NCGETVARS(uint,unsigned int)
|
|
NCGETVARS(longlong,long long)
|
|
NCGETVARS(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NCGETVARS(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
|
|
dnl
|
|
dnl NC_GET_ATT(Abbrv, Type)
|
|
dnl
|
|
define(`NC_GET_ATT',dnl
|
|
`dnl
|
|
int
|
|
nc_get_att_$1(int ncid, int varid, const char *name, $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return ncp->dispatch->get_att(ncid,varid,name,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NC_GET_ATT(text,char)
|
|
NC_GET_ATT(schar, signed char)
|
|
NC_GET_ATT(uchar, unsigned char)
|
|
NC_GET_ATT(short, short)
|
|
NC_GET_ATT(int, int)
|
|
NC_GET_ATT(long,long)
|
|
dnl NC_GET_ATT(ulong,ulong)
|
|
NC_GET_ATT(float, float)
|
|
NC_GET_ATT(double, double)
|
|
NC_GET_ATT(ubyte,unsigned char)
|
|
NC_GET_ATT(ushort,unsigned short)
|
|
NC_GET_ATT(uint,unsigned int)
|
|
NC_GET_ATT(longlong,long long)
|
|
NC_GET_ATT(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
NC_GET_ATT(string,char*)
|
|
#endif /*USE_NETCDF4*/
|
|
|
|
|
|
dnl
|
|
dnl NC_PUT_ATT(Abbrv, Type)
|
|
dnl
|
|
define(`NC_PUT_ATT',dnl
|
|
`dnl
|
|
int
|
|
nc_put_att_$1(int ncid, int varid, const char *name,
|
|
nc_type type, size_t nelems, const $2 *value)
|
|
{
|
|
NC* ncp;
|
|
int stat = NC_check_id(ncid, &ncp);
|
|
if(stat != NC_NOERR) return stat;
|
|
return ncp->dispatch->put_att(ncid,varid,name,type,nelems,(void*)value,T_$1);
|
|
}
|
|
')dnl
|
|
NC_PUT_ATT(schar, signed char)
|
|
NC_PUT_ATT(uchar, unsigned char)
|
|
NC_PUT_ATT(short, short)
|
|
NC_PUT_ATT(int, int)
|
|
NC_PUT_ATT(long,long)
|
|
dnl NC_PUT_ATT(ulong,ulong)
|
|
NC_PUT_ATT(float, float)
|
|
NC_PUT_ATT(double, double)
|
|
NC_PUT_ATT(ubyte,unsigned char)
|
|
NC_PUT_ATT(ushort,unsigned short)
|
|
NC_PUT_ATT(uint,unsigned int)
|
|
NC_PUT_ATT(longlong,long long)
|
|
NC_PUT_ATT(ulonglong,unsigned long long)
|
|
#ifdef USE_NETCDF4
|
|
/*NC_PUT_ATT(string,char*) defined separately */
|
|
#endif /*USE_NETCDF4*/
|