mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-27 08:49:16 +08:00
Merged latest from trunk.
This commit is contained in:
commit
0d37707254
@ -2,12 +2,12 @@ NCLIB=../liblib/.libs/libnetcdf.a
|
||||
NCINCL=-I ../liblib
|
||||
|
||||
#CYGWIN
|
||||
LFLAG=-L/usr/local/lib
|
||||
#LFLAG=-L/usr/local/lib
|
||||
#HDF5LIB=/usr/local/lib/libhdf5_hl.a /usr/local/lib/libhdf5.a
|
||||
|
||||
#!CYGWIN
|
||||
#LFLAG=-L/upc/share/ed/local/${HOST}/lib
|
||||
#HDF5LIB=/share/ed/local/${HOST}/lib/libhdf5_hl.a /share/ed/local/${HOST}/lib/libhdf5.a
|
||||
LFLAG=-L/upc/share/ed/local/${HOST}/lib
|
||||
HDF5LIB=/share/ed/local/${HOST}/lib/libhdf5_hl.a /share/ed/local/${HOST}/lib/libhdf5.a
|
||||
|
||||
CURLLIB=-lcurl
|
||||
ZLIB=-lz
|
||||
@ -258,7 +258,7 @@ fix::
|
||||
done
|
||||
|
||||
##################################################
|
||||
T=civ
|
||||
T=civ2
|
||||
|
||||
v::
|
||||
cc -g -c ${T}.c ${INCL}
|
||||
|
@ -79,9 +79,6 @@ NCD3_open(const char * path, int mode,
|
||||
NCDAPCOMMON* dapcomm = NULL;
|
||||
const char* value;
|
||||
|
||||
/* We will use a fake file descriptor as our internal in-memory filename */
|
||||
char tmpname[32];
|
||||
|
||||
if(!nc3dinitialized) nc3dinitialize();
|
||||
|
||||
if(path == NULL)
|
||||
@ -137,11 +134,18 @@ NCD3_open(const char * path, int mode,
|
||||
}
|
||||
|
||||
/* Use libsrc code for storing metadata */
|
||||
{
|
||||
char tmpname[32];
|
||||
|
||||
snprintf(tmpname,sizeof(tmpname),"%d",drno->int_ncid);
|
||||
/* Now, use the file to create the netcdf file; always 64 bit */
|
||||
ncstat = nc_create(tmpname,NC_DISKLESS|NC_64BIT_OFFSET,&drno->substrate);
|
||||
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
|
||||
/* Create fake file name: exact name must be unique,
|
||||
but is otherwise irrelevant because we are using NC_DISKLESS
|
||||
*/
|
||||
snprintf(tmpname,sizeof(tmpname),"%d",drno->int_ncid);
|
||||
|
||||
/* Now, use the file to create the netcdf file; force classic. */
|
||||
ncstat = nc_create(tmpname,NC_DISKLESS|NC_CLASSIC_MODEL,&drno->substrate);
|
||||
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
|
||||
}
|
||||
|
||||
/* Avoid fill */
|
||||
nc_set_fill(drno->substrate,NC_NOFILL,NULL);
|
||||
|
@ -1446,6 +1446,8 @@ NC_create(const char *path, int cmode, size_t initialsz,
|
||||
if(model == 0) {
|
||||
if(cmode & NC_NETCDF4 || cmode & NC_PNETCDF)
|
||||
model = NC_DISPATCH_NC4;
|
||||
else if(cmode & NC_CLASSIC_MODEL)
|
||||
model = NC_DISPATCH_NC3;
|
||||
}
|
||||
|
||||
if(model == 0) {
|
||||
|
@ -1383,6 +1383,10 @@ atomic type; it will not read user defined types. For this
|
||||
function, the type of the data in memory must match the type
|
||||
of the variable - no data conversion is done.
|
||||
|
||||
Use of this family of functions is discouraged, although not
|
||||
formally deprecated. The reason is the complexity of the
|
||||
algorithm makes its use difficult for users to properly use.
|
||||
|
||||
\param ncid NetCDF or group ID, from a previous call to nc_open(),
|
||||
nc_create(), nc_def_grp(), or associated inquiry functions such as
|
||||
nc_inq_ncid().
|
||||
|
@ -1305,6 +1305,10 @@ atomic type; it will not write user defined types. For this
|
||||
function, the type of the data in memory must match the type
|
||||
of the variable - no data conversion is done.
|
||||
|
||||
Use of this family of functions is discouraged, although not
|
||||
formally deprecated. The reason is the complexity of the
|
||||
algorithm makes its use difficult for users to properly use.
|
||||
|
||||
\param ncid NetCDF or group ID, from a previous call to nc_open(),
|
||||
nc_create(), nc_def_grp(), or associated inquiry functions such as
|
||||
nc_inq_ncid().
|
||||
|
@ -4,4 +4,4 @@ Attributes {
|
||||
Int32 a1 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
Dataset {
|
||||
Sequence {
|
||||
Sequence {
|
||||
Float32 v4;
|
||||
} Q2;
|
||||
} Q1;
|
||||
} SYNTH8;
|
@ -300,8 +300,10 @@ dapsetwordchars(DAPlexstate* lexstate, int kind)
|
||||
void
|
||||
daplexinit(char* input, DAPlexstate** lexstatep)
|
||||
{
|
||||
DAPlexstate* lexstate = (DAPlexstate*)malloc(sizeof(DAPlexstate));
|
||||
if(lexstatep) *lexstatep = lexstate;
|
||||
DAPlexstate* lexstate;
|
||||
if(lexstatep == NULL) return; /* no point in building it */
|
||||
lexstate = (DAPlexstate*)malloc(sizeof(DAPlexstate));
|
||||
*lexstatep = lexstate;
|
||||
if(lexstate == NULL) return;
|
||||
memset((void*)lexstate,0,sizeof(DAPlexstate));
|
||||
lexstate->input = strdup(input);
|
||||
@ -309,8 +311,6 @@ daplexinit(char* input, DAPlexstate** lexstatep)
|
||||
lexstate->yytext = ocbytesnew();
|
||||
lexstate->reclaim = oclistnew();
|
||||
dapsetwordchars(lexstate,0); /* Assume DDS */
|
||||
if(!lexstatep)
|
||||
free(lexstate);
|
||||
}
|
||||
|
||||
void
|
||||
|
146
oc2/oc.c
146
oc2/oc.c
@ -539,7 +539,7 @@ Obtain a dds node by name from a dds structure or dataset node.
|
||||
\param[in] link The link through which the server is accessed.
|
||||
\param[in] ddsnode The container node of interest.
|
||||
\param[in] name The name of the field to return.
|
||||
\param[out] fieldnodep A pointer into which the name'th field node is stored.
|
||||
\param[out] fieldp A pointer into which the name'th field node is stored.
|
||||
|
||||
\retval OC_NOERR The procedure executed normally.
|
||||
\retval OC_EINDEX No field with the given name was found.
|
||||
@ -836,7 +836,7 @@ oc_das_attr(OCobject link, OCobject dasnode, size_t index, OCtype* atomtypep, ch
|
||||
/**@}*/
|
||||
|
||||
/**************************************************/
|
||||
/*! Node Interconnection Management */
|
||||
/*!\defgroup Interconnection Node Interconnection Management */
|
||||
|
||||
/**@{*/
|
||||
|
||||
@ -875,7 +875,7 @@ oc_merge_das(OCobject link, OCobject dasroot, OCobject ddsroot)
|
||||
|
||||
/**************************************************/
|
||||
|
||||
/*! Data Management */
|
||||
/*!\defgroup Data Data Management */
|
||||
/**@{*/
|
||||
|
||||
/*!
|
||||
@ -963,8 +963,14 @@ OCerror
|
||||
oc_data_fieldbyname(OCobject link, OCobject datanode, const char* name, OCobject* fieldp)
|
||||
{
|
||||
OCerror err = OC_NOERR;
|
||||
OCstate* state;
|
||||
OCdata* data;
|
||||
size_t count,i;
|
||||
OCobject ddsnode;
|
||||
OCVERIFY(OC_State,link);
|
||||
OCDEREF(OCstate*,state,link);
|
||||
OCVERIFY(OC_Data,datanode);
|
||||
OCDEREF(OCdata*,data,datanode);
|
||||
|
||||
/* Get the dds node for this datanode */
|
||||
err = oc_data_ddsnode(link,datanode,&ddsnode);
|
||||
@ -1492,11 +1498,140 @@ oc_data_readn(OCobject link, OCobject datanode,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
This procedure has the same semantics as oc_data_read.
|
||||
However, it takes an OCddsnode as argument.
|
||||
The limitation is that the DDS node must be a top-level,
|
||||
atomic variable.
|
||||
Top-level means that it is not nested in a Sequence or a
|
||||
dimensioned Structure; being in a Grid is ok as is being in
|
||||
a scalar structure.
|
||||
|
||||
\param[in] link The link through which the server is accessed.
|
||||
\param[in] ddsnode The dds node instance of interest.
|
||||
\param[in] start A vector of indices specifying the starting element
|
||||
to return.
|
||||
\param[in] edges A vector of indices specifying the count in each dimension
|
||||
of the number of elements to return.
|
||||
\param[in] memsize The size (in bytes) of the memory argument.
|
||||
\param[out] memory User allocated memory into which the extracted
|
||||
data is to be stored. The caller is responsible for allocating and free'ing
|
||||
this argument.
|
||||
|
||||
\retval OC_NOERR The procedure executed normally.
|
||||
\retval OC_EINVAL The memsize argument is too small to hold
|
||||
the specified data.
|
||||
\retval OC_EINVALCOORDS The start and/or edges argument is outside
|
||||
the range of legal indices.
|
||||
\retval OC_EDATADDS The data retrieved from the server was malformed
|
||||
and the read request cannot be completed.
|
||||
|
||||
*/
|
||||
|
||||
OCerror
|
||||
oc_dds_read(OCobject link, OCobject ddsnode,
|
||||
size_t* start, size_t* edges,
|
||||
size_t memsize, void* memory)
|
||||
{
|
||||
OCdata* data;
|
||||
OCnode* dds;
|
||||
|
||||
OCVERIFY(OC_Node,ddsnode);
|
||||
OCDEREF(OCnode*,dds,ddsnode);
|
||||
|
||||
/* Get the data associated with this top-level node */
|
||||
data = dds->data;
|
||||
if(data == NULL) return OC_EINVAL;
|
||||
return oc_data_read(link,data,start,edges,memsize,memory);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
This procedure is a variant of oc_data_read for reading a single scalar.
|
||||
This procedure has the same semantics as oc_data_readscalar.
|
||||
However, it takes an OCddsnode as argument.
|
||||
The limitation is that the DDS node must be a top-level, atomic variable.
|
||||
Top-level means that it is not nested in a Sequence or a
|
||||
dimensioned Structure; being in a Grid is ok as is being in
|
||||
a scalar structure.
|
||||
|
||||
\param[in] link The link through which the server is accessed.
|
||||
\param[in] ddsnode The dds node instance of interest.
|
||||
\param[in] memsize The size (in bytes) of the memory argument.
|
||||
\param[out] memory User allocated memory into which the extracted
|
||||
data is to be stored. The caller is responsible for allocating and free'ing
|
||||
this argument.
|
||||
|
||||
\retval OC_NOERR The procedure executed normally.
|
||||
\retval OC_EINVAL The memsize argument is too small to hold
|
||||
the specified data.
|
||||
\retval OC_ESCALAR The data instance is not a scalar.
|
||||
\retval OC_EDATADDS The data retrieved from the server was malformed
|
||||
and the read request cannot be completed.
|
||||
\retval OC_EINVAL One of the arguments (link, etc.) was invalid.
|
||||
*/
|
||||
|
||||
OCerror
|
||||
oc_dds_readscalar(OCobject link, OCobject ddsnode,
|
||||
size_t memsize, void* memory)
|
||||
{
|
||||
return oc_dds_readn(link,ddsnode,NULL,0,memsize,memory);
|
||||
}
|
||||
|
||||
/*!
|
||||
This procedure is a variant of oc_dds_read for reading
|
||||
nelements of values starting at a given index position.
|
||||
If the variable is a scalar, then the
|
||||
index vector and count will be ignored.
|
||||
This procedure has the same semantics as oc_data_readn.
|
||||
However, it takes an OCddsnode as argument.
|
||||
The limitation is that the DDS node must be a top-level, atomic variable.
|
||||
Top-level means that it is not nested in a Sequence or a
|
||||
dimensioned Structure; being in a Grid is ok as is being in
|
||||
a scalar structure.
|
||||
|
||||
\param[in] link The link through which the server is accessed.
|
||||
\param[in] ddsnode The dds node instance of interest.
|
||||
\param[in] start A vector of indices specifying the starting element
|
||||
to return.
|
||||
\param[in] N The number of elements to read. Reading is assumed
|
||||
to use row-major order.
|
||||
\param[in] memsize The size (in bytes) of the memory argument.
|
||||
\param[out] memory User allocated memory into which the extracted
|
||||
data is to be stored. The caller is responsible for allocating and free'ing
|
||||
this argument.
|
||||
|
||||
\retval OC_NOERR The procedure executed normally.
|
||||
\retval OC_EINVAL The memsize argument is too small to hold
|
||||
the specified data.
|
||||
\retval OC_EINVALCOORDS The start and/or count argument is outside
|
||||
the range of legal indices.
|
||||
\retval OC_EDATADDS The data retrieved from the server was malformed
|
||||
and the read request cannot be completed.
|
||||
\retval OC_EINVAL One of the arguments (link, etc.) was invalid.
|
||||
*/
|
||||
|
||||
OCerror
|
||||
oc_dds_readn(OCobject link, OCobject ddsnode,
|
||||
size_t* start, size_t N,
|
||||
size_t memsize, void* memory)
|
||||
{
|
||||
OCdata* data;
|
||||
OCnode* dds;
|
||||
|
||||
OCVERIFY(OC_Node,ddsnode);
|
||||
OCDEREF(OCnode*,dds,ddsnode);
|
||||
|
||||
/* Get the data associated with this top-level node */
|
||||
data = dds->data;
|
||||
if(data == NULL) return OC_EINVAL;
|
||||
return oc_data_readn(link,data,start,N,memsize,memory);
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**************************************************/
|
||||
/* OCtype Management */
|
||||
|
||||
/*!\defgroup OCtype OCtype Management
|
||||
@{*/
|
||||
|
||||
@ -1775,6 +1910,7 @@ oc_ping(const char* url)
|
||||
/*!
|
||||
Set the user agent field.
|
||||
|
||||
\param[in] link The link through which the server is accessed.
|
||||
\param[in] agent The user agent string
|
||||
|
||||
\retval OC_NOERR if the request succeeded.
|
||||
|
19
oc2/oc.h
19
oc2/oc.h
@ -400,12 +400,14 @@ extern OCerror oc_data_recordcount(OClink, OCdatanode, size_t*);
|
||||
If scalar, then index and count are ignored.
|
||||
Caller is responsible for allocating memory(of proper size)
|
||||
and free'ing it.
|
||||
See also oc_dds_read().
|
||||
*/
|
||||
extern OCerror oc_data_read(OClink, OCdatanode, size_t*, size_t*, size_t, void*);
|
||||
|
||||
/* Like oc_data_read, but for reading a scalar.
|
||||
Caller is responsible for allocating memory(of proper size)
|
||||
and free'ing it.
|
||||
See also oc_dds_readscalar().
|
||||
*/
|
||||
extern OCerror oc_data_readscalar(OClink, OCdatanode, size_t, void*);
|
||||
|
||||
@ -413,6 +415,7 @@ extern OCerror oc_data_readscalar(OClink, OCdatanode, size_t, void*);
|
||||
and count of the number of elements to read.
|
||||
Caller is responsible for allocating memory(of proper size)
|
||||
and free'ing it.
|
||||
See also oc_dds_readn().
|
||||
*/
|
||||
extern OCerror oc_data_readn(OClink, OCdatanode, size_t*, size_t, size_t, void*);
|
||||
|
||||
@ -446,6 +449,22 @@ extern int oc_data_indexed(OClink, OCdatanode);
|
||||
*/
|
||||
extern int oc_data_indexable(OClink, OCdatanode);
|
||||
|
||||
/**************************************************/
|
||||
/*
|
||||
For top-level, atomic variables, it is possible to directly
|
||||
read the associated data without having to use the oc_data_XXX
|
||||
procedures. Provide special procedures to support this.
|
||||
*/
|
||||
|
||||
/* See oc_data_read for semantics */
|
||||
extern OCerror oc_dds_read(OClink, OCddsnode, size_t*, size_t*, size_t, void*);
|
||||
|
||||
/* See oc_data_readscalar for semantics */
|
||||
extern OCerror oc_dds_readscalar(OClink, OCddsnode, size_t, void*);
|
||||
|
||||
/* See oc_data_readn for semantics */
|
||||
extern OCerror oc_dds_readn(OClink, OCddsnode, size_t*, size_t, size_t, void*);
|
||||
|
||||
/**************************************************/
|
||||
/* Misc. OCtype-related functions */
|
||||
|
||||
|
@ -12,14 +12,18 @@
|
||||
#include "ocdebug.h"
|
||||
#include "ocdump.h"
|
||||
|
||||
/* Mnemonic */
|
||||
#define TOPLEVEL 1
|
||||
|
||||
/* Forward */
|
||||
static OCdata* newocdata(OCnode* template);
|
||||
static size_t ocxdrsize(OCtype etype,int isscalar);
|
||||
static OCerror occompile1(OCstate*, OCnode*, XXDR*, OCdata**);
|
||||
static OCerror occompilerecord(OCstate*, OCnode*, XXDR*, OCdata**);
|
||||
static OCerror occompilefields(OCstate*, OCdata*, XXDR*);
|
||||
static OCerror occompilefields(OCstate*, OCdata*, XXDR*, int istoplevel);
|
||||
static OCerror occompileatomic(OCstate*, OCdata*, XXDR*);
|
||||
static int ocerrorstring(XXDR* xdrs);
|
||||
static int istoplevel(OCnode* node);
|
||||
|
||||
/* Sequence tag constant */
|
||||
const char StartOfSequence = '\x5A';
|
||||
@ -86,13 +90,13 @@ occompile1(OCstate* state, OCnode* xnode, XXDR* xxdrs, OCdata** datap)
|
||||
|
||||
case OC_Dataset:
|
||||
case OC_Grid: /* Always scalars */
|
||||
ocstat = occompilefields(state,data,xxdrs);
|
||||
ocstat = occompilefields(state,data,xxdrs,istoplevel(xnode));
|
||||
if(ocstat != OC_NOERR) goto fail;
|
||||
break;
|
||||
|
||||
case OC_Structure:
|
||||
if(xnode->array.rank == 0) {/* scalar */
|
||||
ocstat = occompilefields(state,data,xxdrs);
|
||||
ocstat = occompilefields(state,data,xxdrs,istoplevel(xnode));
|
||||
if(ocstat != OC_NOERR) goto fail;
|
||||
} else { /* dimensioned structure */
|
||||
unsigned int xdrcount;
|
||||
@ -124,7 +128,7 @@ occompile1(OCstate* state, OCnode* xnode, XXDR* xxdrs, OCdata** datap)
|
||||
/* capture the current instance position */
|
||||
instance->xdroffset = xxdr_getpos(xxdrs);
|
||||
/* Now compile the fields of this instance */
|
||||
ocstat = occompilefields(state,instance,xxdrs);
|
||||
ocstat = occompilefields(state,instance,xxdrs,!TOPLEVEL);
|
||||
if(ocstat != OC_NOERR) {goto fail;}
|
||||
}
|
||||
}
|
||||
@ -210,7 +214,7 @@ occompilerecord(OCstate* state, OCnode* xnode, XXDR* xxdrs, OCdata** recordp)
|
||||
/* capture the current record position */
|
||||
record->xdroffset = xxdr_getpos(xxdrs);
|
||||
/* Compile the fields of this record */
|
||||
ocstat = OCTHROW(occompilefields(state,record,xxdrs));
|
||||
ocstat = OCTHROW(occompilefields(state,record,xxdrs,!TOPLEVEL));
|
||||
if(ocstat == OC_NOERR) {
|
||||
if(recordp) *recordp = record;
|
||||
}
|
||||
@ -218,7 +222,7 @@ occompilerecord(OCstate* state, OCnode* xnode, XXDR* xxdrs, OCdata** recordp)
|
||||
}
|
||||
|
||||
static OCerror
|
||||
occompilefields(OCstate* state, OCdata* data, XXDR* xxdrs)
|
||||
occompilefields(OCstate* state, OCdata* data, XXDR* xxdrs, int istoplevel)
|
||||
{
|
||||
int i;
|
||||
OCerror ocstat = OC_NOERR;
|
||||
@ -246,6 +250,15 @@ occompilefields(OCstate* state, OCdata* data, XXDR* xxdrs)
|
||||
fieldinstance->index = i;
|
||||
}
|
||||
|
||||
/* If top-level, then link the OCnode to the OCdata directly */
|
||||
if(istoplevel) {
|
||||
for(i=0;i<nelements;i++) {
|
||||
OCnode* fieldnode = (OCnode*)oclistget(xnode->subnodes,i);
|
||||
OCdata* fieldinstance = data->instances[i];
|
||||
fieldnode->data = fieldinstance;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return OCTHROW(ocstat);
|
||||
|
||||
@ -373,6 +386,23 @@ newocdata(OCnode* template)
|
||||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
istoplevel(OCnode* node)
|
||||
{
|
||||
if(node == NULL)
|
||||
return 1; /* base case */
|
||||
if(!istoplevel(node->container))
|
||||
return 0;
|
||||
switch (node->octype) {
|
||||
case OC_Dataset: case OC_Grid: case OC_Atomic: return 1;
|
||||
case OC_Structure:
|
||||
return (node->array.rank == 0 ? 1 : 0); /* Toplevel if scalar */
|
||||
case OC_Sequence: default: return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* XDR representation size depends on if this is scalar or not */
|
||||
static size_t
|
||||
ocxdrsize(OCtype etype, int isscalar)
|
||||
|
@ -205,5 +205,4 @@ extern int ocinternalinitialize(void);
|
||||
|
||||
extern OCerror ocsetuseragent(OCstate* state, const char* agent);
|
||||
|
||||
|
||||
#endif /*COMMON_H*/
|
||||
|
@ -152,7 +152,7 @@ number of arguments and operates like the stdio
|
||||
printf function.
|
||||
|
||||
\param[in] tag Indicate the kind of this log message.
|
||||
\param[in] format Format specification as with printf.
|
||||
\param[in] fmt Format specification as with printf.
|
||||
*/
|
||||
|
||||
void
|
||||
@ -186,8 +186,10 @@ oclogtext(int tag, const char* text)
|
||||
/*!
|
||||
Send arbitrarily long text as a logging message.
|
||||
Each line will be sent using oclog with the specified tag.
|
||||
|
||||
\param[in] tag Indicate the kind of this log message.
|
||||
\param[in] text Arbitrary text to send as a logging message.
|
||||
\param[in] count Maximum ength of the text to write.
|
||||
*/
|
||||
|
||||
void
|
||||
|
@ -57,6 +57,7 @@ struct OCnode {
|
||||
OClist* subnodes; /*oclist<OCnode*>*/
|
||||
/*int attributed;*/ /* 1 if merge was done*/
|
||||
OClist* attributes; /* oclist<OCattribute*>*/
|
||||
OCdata* data; /* Defined only if this node is a top-level atomic variable*/
|
||||
};
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
|
Loading…
Reference in New Issue
Block a user