File: hdf4var.c

package info (click to toggle)
netcdf-parallel 1%3A4.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 105,352 kB
  • sloc: ansic: 229,114; sh: 11,180; yacc: 2,561; makefile: 1,390; lex: 1,173; xml: 173; awk: 2
file content (99 lines) | stat: -rw-r--r-- 3,002 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* 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
 */

#include "config.h"
#include <nc4internal.h>
#include "hdf4dispatch.h"
#include "nc4dispatch.h"
#include <mfhdf.h>

/**
 * 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.
 *
 * @param ncid File ID.
 * @param varid Variable ID.
 * @param startp Array of start indices.
 * @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.
 *
 * @return ::NC_NOERR for success.
 * @return ::NC_EBADID Bad ncid.
 * @return ::NC_EINVAL Invalid input.
 * @return ::NC_EHDFERR HDF4 error.
 * @return ::NC_ENOMEM Out of memory.
 * @author Ed Hartnett, Dennis Heimbigner
 */
int
NC_HDF4_get_vara(int ncid, int varid, const size_t *startp,
                 const size_t *countp, void *ip, int memtype)
{
    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;

    LOG((2, "%s: ncid 0x%x varid %d memtype %d", __func__, ncid, varid,
         memtype));

    /* No scalars in HDF4 SD API. Caller must also provide place to put
     * data. */
    if (!startp || !countp || !ip)
        return NC_EINVAL;

    /* 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);

    /* Get the HDF4 specific var metadata. */
    hdf4_var = (NC_VAR_HDF4_INFO_T *)var->format_var_info;

    /* 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];
    }

    /* If memtype was not give, use variable type. */
    if (memtype == NC_NAT)
        memtype = var->type_info->hdr.id;

    /* 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;

    /* Read the data with HDF4. */
    if (SDreaddata(hdf4_var->sdsid, start32, NULL, edge32, data))
        return NC_EHDFERR;

    /* 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,
                                       &range_error, NULL, 0)))
            return retval;
        free(data);
        if (range_error)
            return range_error;
    }

    return NC_NOERR;
}