netcdf-c/libhdf4/hdf4var.c

100 lines
2.9 KiB
C
Raw Normal View History

2018-02-08 21:20:58 +08:00
/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying
* and redistribution conditions.*/
/**
* @file @internal This file handles the variable functions for the
* HDF4 dispatch layer.
*
* @author Ed Hartnett
*/
2018-04-05 04:11:44 +08:00
#include "config.h"
2018-02-08 21:20:58 +08:00
#include <nc4internal.h>
2018-04-05 04:11:44 +08:00
#include "hdf4dispatch.h"
2018-02-08 21:20:58 +08:00
#include "nc4dispatch.h"
2018-04-05 04:11:44 +08:00
#include <mfhdf.h>
2018-02-08 21:20:58 +08:00
/**
2018-04-05 04:11:44 +08:00
* Read an array of values. This is called by nc_get_vara() for
* netCDF-4 files, as well as all the other nc_get_vara_*
* functions. HDF4 files are handled as a special case.
2018-02-08 21:20:58 +08:00
*
* @param ncid File ID.
* @param varid Variable ID.
2018-04-24 06:38:08 +08:00
* @param startp Array of start indices.
2018-04-05 04:11:44 +08:00
* @param countp Array of counts.
* @param ip pointer that gets the data.
* @param memtype The type of these data after it is read into memory.
2019-07-05 00:23:11 +08:00
*
2018-04-05 04:11:44 +08:00
* @return ::NC_NOERR for success.
* @return ::NC_EBADID Bad ncid.
2019-07-05 00:22:13 +08:00
* @return ::NC_EINVAL Invalid input.
2019-07-05 00:23:11 +08:00
* @return ::NC_EHDFERR HDF4 error.
* @return ::NC_ENOMEM Out of memory.
2018-02-08 21:20:58 +08:00
* @author Ed Hartnett, Dennis Heimbigner
*/
int
2018-04-05 04:11:44 +08:00
NC_HDF4_get_vara(int ncid, int varid, const size_t *startp,
const size_t *countp, void *ip, int memtype)
2018-02-08 21:20:58 +08:00
{
NC_VAR_HDF4_INFO_T *hdf4_var;
NC_VAR_INFO_T *var;
int32 start32[NC_MAX_VAR_DIMS], edge32[NC_MAX_VAR_DIMS];
size_t nelem = 1;
void *data;
int retval, d;
int range_error;
2018-02-08 21:20:58 +08:00
LOG((2, "%s: ncid 0x%x varid %d memtype %d", __func__, ncid, varid,
memtype));
2018-04-05 04:11:44 +08:00
/* No scalars in HDF4 SD API. Caller must also provide place to put
* data. */
if (!startp || !countp || !ip)
return NC_EINVAL;
2018-04-05 04:11:44 +08:00
/* Find our metadata for this file, group, and var. */
if ((retval = nc4_find_grp_h5_var(ncid, varid, NULL, NULL, &var)))
return retval;
assert(var && var->hdr.name && var->format_var_info);
2018-04-05 04:11:44 +08:00
/* Get the HDF4 specific var metadata. */
hdf4_var = (NC_VAR_HDF4_INFO_T *)var->format_var_info;
2018-04-05 04:11:44 +08:00
/* Convert starts/edges to the int32 type HDF4 wants. Also learn
* how many elements of data are being read. */
for (d = 0; d < var->ndims; d++)
{
start32[d] = startp[d];
edge32[d] = countp[d];
nelem *= countp[d];
}
2018-02-08 21:20:58 +08:00
/* If memtype was not give, use variable type. */
if (memtype == NC_NAT)
memtype = var->type_info->hdr.id;
2018-02-08 21:20:58 +08:00
/* If we need to convert data, allocate temp storage. */
if (var->type_info->hdr.id == memtype)
data = ip;
else
if (!(data = malloc(var->type_info->size * nelem)))
return NC_ENOMEM;
2018-02-08 21:20:58 +08:00
/* Read the data with HDF4. */
if (SDreaddata(hdf4_var->sdsid, start32, NULL, edge32, data))
return NC_EHDFERR;
2018-02-08 21:20:58 +08:00
/* Do we need to convert data? */
if (var->type_info->hdr.id != memtype)
{
if ((retval = nc4_convert_type(data, ip, var->type_info->hdr.id, memtype, nelem,
2021-08-25 15:31:26 +08:00
&range_error, NULL, 0, NC_NOQUANTIZE, 0)))
return retval;
free(data);
if (range_error)
return range_error;
}
2018-02-08 21:20:58 +08:00
return NC_NOERR;
2018-02-08 21:20:58 +08:00
}