/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF. The full HDF copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the files COPYING and Copyright.html. COPYING can be found at the root * * of the source code distribution tree; Copyright.html can be found at * * http://hdfgroup.org/products/hdf4/doc/Copyright.html. If you do not have * * access to either file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /**************************************************************************** * tncunlim.c - tests reading/writing variables with unlimited dimension using * nc API. The tests here are added to test the behavior of the * library when dealing with unlimited dimensions with nc API. The * tests show that the data is correctly written when: * + data added immediately after last record * + data added skipping one or more records * + data overridden existing data * + data read pass the end of that variable but not the max in * all the variables in the file (on going) * * Structure of the file: * test_ncunlim - test driver * test_1dimsinglevar - tests on a single variable with only 1 dimension * test_1dimmultivars - tests on multiple variables with only 1 dimension * test_multi_dimvars - tests on multiple variables with multiple dimensions * BMR - Dec 22, 2008 ****************************************************************************/ #include "mfhdf.h" #include "/mnt/hdf/bmribler/srcdir/hdf4/mfhdf/libsrc/hdftest.h" /******************************************************************** Name: test_1dimsinglevar() - tests on a single variable with only 1 dimension Description: The main contents include: - write 4 elements starting at index 0 - append 2 elements starting at index 6, that is indices 4 and 5 will be written with fill value - append 3 elements immediately at the end of the data - overwrite indices 0 and 1 Return value: The number of errors occurred in this routine. BMR - Dec 22, 2008 *********************************************************************/ #define DIM0 20 #define FILENAME "onedimonly.nc" static int test_1dimsinglevar() { int ncid; /* file id */ int varid; /* variable id */ int time_dim; /* unlimited dimension */ int dims[1]; /* variable shapes */ long dimsize = 0; /* dimension size buffer */ short outdata[DIM0]; /* data read back */ char varname[10]; /* variable name */ nc_type rh_type; /* variable type */ int rh_ndims; /* number of dims */ int rh_dims[MAX_VAR_DIMS]; /* variable shape */ int rh_natts; /* number of attributes */ int ii; short fillval = 99; /* fill value for the variable */ intn status = 0; /* returned by called functions */ intn num_errs = 0; /* number of errors so far */ /* result data to compare against read data; the first two elements will be changed to "1,2" later for the last test. */ short result[] = {320,301,301,302,99,99,30,31,801,802,803}; /* enter define mode */ ncid = nccreate(FILENAME, NC_CLOBBER); CHECK(ncid, -1, "nccreate"); /* variables will be filled with fill values when data is missing */ status = ncsetfill(ncid, NC_FILL); CHECK(status, -1, "ncsetfill"); /* define the dimension */ time_dim = ncdimdef(ncid, "time", NC_UNLIMITED); CHECK(status, -1, "ncdimdef"); /* define the variable */ dims[0] = time_dim; varid = ncvardef (ncid, "Variable 1", NC_SHORT, 1, dims); CHECK(varid, -1, "ncvardef"); /* write the fill value attribute */ status = ncattput(ncid, varid, "_FillValue", NC_SHORT, 1, &fillval ); CHECK(status, -1, "ncattput"); /* leave define mode */ status = ncendef (ncid); CHECK(status, -1, "ncendef"); { /* write data the first time */ long rh_start[] = {0}; /* starting writing at beginning, index 0 */ long rh_edges[] = {4}; /* four elements */ short data[] = { 320,301,301,302}; /* write 4 elements starting at index 0 */ status = ncvarput(ncid, varid, rh_start, rh_edges, (void *)data); CHECK(status, -1, "ncvarput"); } /* get variable information and size of the unlimited dimension */ status = ncvarinq (ncid, varid, varname, &rh_type, &rh_ndims, rh_dims, &rh_natts); CHECK(status, -1, "ncvarinq"); status = ncdiminq(ncid, rh_dims[0], 0, &dimsize); CHECK(status, -1, "ncdiminq"); VERIFY(dimsize, 4, "ncdiminq"); /* close file */ status = ncclose (ncid); CHECK(status, -1, "ncclose"); /* open file for reading and writing */ ncid = ncopen(FILENAME, NC_RDWR); CHECK(ncid, -1, "ncopen"); /* get access to the variable */ varid = ncvarid(ncid, "Variable 1"); CHECK(varid, -1, "ncvarid"); /* get and verify variable info and size of the unlimited dimension again */ status = ncvarinq (ncid, varid, varname, &rh_type, &rh_ndims, rh_dims, &rh_natts); CHECK(status, -1, "ncvarinq"); status = ncdiminq(ncid, rh_dims[0], 0, &dimsize); CHECK(status, -1, "ncdiminq"); VERIFY(dimsize, 4, "ncdiminq"); { /* read and verify data of the variable */ long start[] = {0}; long edges[1]; edges[0] = dimsize; HDmemset(outdata, 0, DIM0); status = ncvarget(ncid, varid, start, edges, outdata); CHECK(status, -1, "ncvarget"); /* verify data, should be "320,301,301,302" */ for (ii = 0; ii < dimsize; ii++) { if (outdata[ii] != result[ii]) fprintf(stderr,"Read data %d doesn't match input %d at index %d\n", outdata[ii], result[ii], ii); } } /* end read data */ { /* append data to variable pass the end */ long rh_start[] = {6}; /* the end is 3 */ long rh_edges[] = {2}; /* two elements */ short data[] = { 30,31}; /* write 2 values starting at index 6 */ status = ncvarput(ncid, varid, rh_start, rh_edges, (void *)data); CHECK(status, -1, "ncvarput"); } /* get and verify variable info and size of the unlimited dimension again */ status = ncvarinq (ncid, varid, varname, &rh_type, &rh_ndims, rh_dims, &rh_natts); CHECK(status, -1, "ncvarinq"); status = ncdiminq(ncid, rh_dims[0], 0, &dimsize); CHECK(status, -1, "ncdiminq"); VERIFY(dimsize, 8, "ncdiminq"); { /* read variable after appending with gap */ long start[] = {0}; long edges[1]; edges[0] = dimsize; HDmemset(outdata, 0, DIM0); status = ncvarget(ncid, varid, start, edges, outdata); CHECK(status, -1, "ncvarget"); /* verify data, should be "320,301,301,302,99,99,30,31" where 99 is fillvalue */ for (ii = 0; ii < edges[0]; ii++) { if (outdata[ii] != result[ii]) fprintf(stderr,"Read data %d doesn't match input %d at index %d\n", outdata[ii], result[ii], ii); } } /* end read data */ { /* write variable immediately pass the end */ long rh_start[] = {0}; long rh_edges[] = {3}; short data[] = { 801,802,803}; rh_start[0] = dimsize; /* starting immediatly pass dimension size */ /* write 3 elements to the variable starting at 'dimsize' */ status = ncvarput(ncid, varid, rh_start, rh_edges, (void *)data); CHECK(status, -1, "ncvarput"); } /* get and verify variable info and size of the unlimited dimension */ status = ncvarinq (ncid, varid, varname, &rh_type, &rh_ndims, rh_dims, &rh_natts); CHECK(status, -1, "ncvarinq"); status = ncdiminq(ncid, rh_dims[0], 0, &dimsize); CHECK(status, -1, "ncdiminq"); VERIFY(dimsize, 11, "ncdiminq"); { /* read variable */ long start[] = {0}; long edges[1]; edges[0] = dimsize; HDmemset(outdata, 0, DIM0+2); status = ncvarget(ncid, varid, start, edges, outdata); CHECK(status, -1, "ncvarget"); /* verify data, should be "320,301,301,302,99,99,30,31,801,802,803" where 99 is fill value */ for (ii = 0; ii < edges[0]; ii++) { if (outdata[ii] != result[ii]) fprintf(stderr,"Read data %d doesn't match input %d at index %d\n", outdata[ii], result[ii], ii); } } /* end read data */ { /* write variable to override current values */ long rh_start[] = {0}; /* starting at the beginning */ long rh_edges[] = {2}; /* two values */ short data[] = { 1,2}; /* write 2 elements overriding the first two values */ status = ncvarput(ncid, varid, rh_start, rh_edges, (void *)data); CHECK(status, -1, "ncvarput"); /* change expected data too */ result[0] = 1; result[1] = 2; } /* get and verify variable info and size of the unlimited dimension */ status = ncvarinq (ncid, varid, varname, &rh_type, &rh_ndims, rh_dims, &rh_natts); CHECK(status, -1, "ncvarinq"); status = ncdiminq(ncid, rh_dims[0], 0, &dimsize); CHECK(status, -1, "ncdiminq"); VERIFY(dimsize, 11, "ncdiminq"); { /* read and verify data */ long start[] = {0}; long edges[1]; edges[0] = dimsize; HDmemset(outdata, 0, DIM0+2); status = ncvarget(ncid, varid, start, edges, outdata); CHECK(status, -1, "ncvarget"); /* verify data, should be "1,2,301,302,99,99,30,31,801,802,803" where 99 is fill value, and first and second values are new */ for (ii = 0; ii < edges[0]; ii++) { if (outdata[ii] != result[ii]) fprintf(stderr,"Read data %d doesn't match input %d at index %d\n", outdata[ii], result[ii], ii); } } /* end read data */ status = ncclose(ncid); CHECK(status, -1, "ncclose"); return 0; } /* Test driver for testing reading/writing variables with unlimited dimension using nc API. */ extern int test_ncunlim() { int num_errs = 0; /* Test single variable with 1 unlimited dimension */ num_errs = num_errs + test_1dimsinglevar(); /* Test multiple variables with 1 unlimited dimension */ /* num_errs = num_errs + test_1dimmultivars(); */ /* Test multiple variables with multiple dimensions */ /* num_errs = num_errs + test_multi_dimvars(); */ return num_errs; }