Loading...
Searching...
No Matches
nc4attr.c
Go to the documentation of this file.
/* Copyright 2003-2018, University Corporation for Atmospheric
* Research. See COPYRIGHT file for copying and redistribution
* conditions. */
#include "nc.h"
#include "nc4internal.h"
#include "nc4dispatch.h"
#include "ncdispatch.h"
int
nc4_get_att_ptrs(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var,
const char *name, nc_type *xtype, nc_type mem_type,
size_t *lenp, int *attnum, void *data)
{
NC_ATT_INFO_T *att = NULL;
int my_attnum = -1;
int need_to_convert = 0;
int range_error = NC_NOERR;
void *bufr = NULL;
size_t type_size;
int varid;
int retval;
LOG((3, "%s: mem_type %d", __func__, mem_type));
/* Get the varid, or NC_GLOBAL. */
varid = var ? var->hdr.id : NC_GLOBAL;
if (attnum)
my_attnum = *attnum;
if (name == NULL)
BAIL(NC_EBADNAME);
/* Find the attribute, if it exists. */
if ((retval = nc4_find_grp_att(grp, varid, name, my_attnum, &att)))
return retval;
/* If mem_type is NC_NAT, it means we want to use the attribute's
* file type as the mem type as well. */
if (mem_type == NC_NAT)
mem_type = att->nc_typeid;
/* If the attribute is NC_CHAR, and the mem_type isn't, or vice
* versa, that's a freakish attempt to convert text to
* numbers. Some pervert out there is trying to pull a fast one!
* Send him an NC_ECHAR error. */
if (data && att->len)
if ((att->nc_typeid == NC_CHAR && mem_type != NC_CHAR) ||
(att->nc_typeid != NC_CHAR && mem_type == NC_CHAR))
BAIL(NC_ECHAR); /* take that, you freak! */
/* Copy the info. */
if (lenp)
*lenp = att->len;
if (xtype)
*xtype = att->nc_typeid;
if (attnum) {
*attnum = att->hdr.id;
}
/* Zero len attributes are easy to read! */
if (!att->len)
BAIL(NC_NOERR);
/* Later on, we will need to know the size of this type. */
if ((retval = nc4_get_typelen_mem(h5, mem_type, &type_size)))
BAIL(retval);
/* We may have to convert data. Treat NC_CHAR the same as
* NC_UBYTE. If the mem_type is NAT, don't try any conversion - use
* the attribute's type. */
if (data && att->len && mem_type != att->nc_typeid &&
mem_type != NC_NAT &&
!(mem_type == NC_CHAR &&
(att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE)))
{
if (!(bufr = malloc((size_t)(att->len) * type_size)))
BAIL(NC_ENOMEM);
need_to_convert++;
if ((retval = nc4_convert_type(att->data, bufr, att->nc_typeid,
mem_type, (size_t)att->len, &range_error,
NULL, (h5->cmode & NC_CLASSIC_MODEL),
NC_NOQUANTIZE, 0)))
BAIL(retval);
/* For strict netcdf-3 rules, ignore erange errors between UBYTE
* and BYTE types. */
if ((h5->cmode & NC_CLASSIC_MODEL) &&
(att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE) &&
(mem_type == NC_UBYTE || mem_type == NC_BYTE) &&
range_error)
range_error = 0;
}
else
{
bufr = att->data;
}
/* If the caller wants data, copy it for him. If he hasn't
allocated enough memory for it, he will burn in segmentation
fault hell, writhing with the agony of undiscovered memory
bugs! */
if (data)
{
{
if((retval = NC_copy_data(h5->controller,mem_type,bufr,att->len,data)))
BAIL(retval);
}
}
exit:
if (need_to_convert)
free(bufr);
if (range_error)
retval = NC_ERANGE;
return retval;
}
int
nc4_get_att(int ncid, int varid, const char *name, nc_type *xtype,
nc_type mem_type, size_t *lenp, int *attnum, void *data)
{
NC_FILE_INFO_T *h5;
NC_GRP_INFO_T *grp;
NC_VAR_INFO_T *var = NULL;
char norm_name[NC_MAX_NAME + 1];
int retval;
LOG((3, "%s: ncid 0x%x varid %d mem_type %d", __func__, ncid,
varid, mem_type));
/* Find info for this file, group, and h5 info. */
if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
return retval;
assert(h5 && grp);
/* Check varid */
if (varid != NC_GLOBAL)
{
if (!(var = (NC_VAR_INFO_T*)ncindexith(grp->vars,(size_t)varid)))
return NC_ENOTVAR;
assert(var->hdr.id == varid);
}
/* Name is required. */
if (!name)
return NC_EBADNAME;
/* Normalize name. */
if ((retval = nc4_normalize_name(name, norm_name)))
return retval;
return nc4_get_att_ptrs(h5, grp, var, norm_name, xtype, mem_type, lenp,
attnum, data);
}
int
NC4_inq_att(int ncid, int varid, const char *name, nc_type *xtypep,
size_t *lenp)
{
LOG((2, "%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
return nc4_get_att(ncid, varid, name, xtypep, NC_NAT, lenp, NULL, NULL);
}
int
NC4_inq_attid(int ncid, int varid, const char *name, int *attnump)
{
LOG((2, "%s: ncid 0x%x varid %d name %s", __func__, ncid, varid, name));
return nc4_get_att(ncid, varid, name, NULL, NC_NAT, NULL, attnump, NULL);
}
int
NC4_inq_attname(int ncid, int varid, int attnum, char *name)
{
NC_ATT_INFO_T *att;
int retval;
LOG((2, "nc_inq_attname: ncid 0x%x varid %d attnum %d", ncid, varid,
attnum));
/* Find the attribute metadata. */
if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att)))
return retval;
/* Get the name. */
if (name)
strcpy(name, att->hdr.name);
return NC_NOERR;
}
int
NC4_get_att(int ncid, int varid, const char *name, void *value, nc_type memtype)
{
return nc4_get_att(ncid, varid, name, NULL, memtype, NULL, NULL, value);
}
NC_ECHAR
#define NC_ECHAR
Attempt to convert between text & numbers.
Definition netcdf.h:478
NC_BYTE
#define NC_BYTE
signed 1 byte integer
Definition netcdf.h:35
NC_NAT
#define NC_NAT
Not A Type.
Definition netcdf.h:34
NC_UBYTE
#define NC_UBYTE
unsigned 1 byte int
Definition netcdf.h:42
NC_ENOMEM
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition netcdf.h:497
NC_GLOBAL
#define NC_GLOBAL
Attribute id to put/get a global attribute.
Definition netcdf.h:303
NC_ENOTVAR
#define NC_ENOTVAR
Variable not found.
Definition netcdf.h:471
NC_CLASSIC_MODEL
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition netcdf.h:166
NC_MAX_NAME
#define NC_MAX_NAME
Maximum for classic library.
Definition netcdf.h:330
NC_NOERR
#define NC_NOERR
No Error.
Definition netcdf.h:417
NC_NOQUANTIZE
#define NC_NOQUANTIZE
No quantization in use.
Definition netcdf.h:384
NC_EBADNAME
#define NC_EBADNAME
Attribute or variable name contains illegal characters.
Definition netcdf.h:489
NC_CHAR
#define NC_CHAR
ISO/ASCII character.
Definition netcdf.h:36
NC_ERANGE
#define NC_ERANGE
Math result not representable.
Definition netcdf.h:496
nc_type
int nc_type
The nc_type type is just an int.
Definition netcdf.h:25