[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[netCDF #YZD-296984]: Read a vlen array in Fortran



I fixed the f90tst_vars_vlen.f90 test program.
I uncommented the code and ran it and it failed.
But the reason it failed is that it was using the wrong
size for the size of an instance of nc_vlen_t. It was using
16 and on my machine, it is 8.
I am attaching my version. See if it works for you. It might
report that you need to change the value of VLENSIZE.

=Dennis Heimbigner
  Unidata


Ticket Details
===================
Ticket ID: YZD-296984
Department: Support netCDF
Priority: Normal
Status: Closed
===================
NOTE: All email exchanges with Unidata User Support are recorded in the Unidata 
inquiry tracking system and then made publicly available through the web.  If 
you do not want to have your interactions made available in this way, you must 
let us know in each email you send to us.
/* This is part of the netCDF package. */
/* Copyright 2009 University Corporation for Atmospheric Research/Unidata. */
/* See COPYRIGHT file for conditions of use. */

/* This program tests netCDF-4 vlen variable functions from fortran 90. */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "netcdf.h"

extern int nc_put_vlen_element(int, int, void*, size_t, const void*);
extern int nc_get_vlen_element(int, int, const void*, size_t*, void*);


/*     This subroutine handles errors by printing an error message and */
/*     exiting with a non-zero status. */
static void
handle_err(int errcode)
{
     if(errcode != NC_NOERR) {
        printf("Error: %s\n", nc_strerror(errcode));
        abort();
     }
}

int
main()
{
   /* This is the name of the data file we will create. */
   char* FILE_NAME = "f90tst_vars_vlen.nc";

   /* NetCDF IDs. */
   int ncid, vlen_typeid;

#define max_types 1

   /* Need these to read type information. */
   int num_types, typeids[max_types];
   int base_type;
   size_t base_size;
   char type_name[NC_MAX_NAME];
   size_t type_size, nfields;
   int clas;

   /* Information for the vlen type we will define. */
   char* vlen_type_name = "vlen_type";

   /* Some data about and for the vlen. */
   size_t vlen_len_in;
#define vlen_len 5
   int data1[vlen_len], data1_in[vlen_len];

   /* These must be big enough to hold the stuct nc_vlen in netcdf.h. */
   int vlen[sizeof(nc_vlen_t)], vlen_in[sizeof(nc_vlen_t)];

   /* Loop indexes, and error handling. */
   int x, retval;

   printf("\n");
   printf("*** Testing VLEN types.\n");

   for(x=0;x<vlen_len;x++) {
      data1[x] = x;
   }

   /* Create the netCDF file. */
   retval = nc_create(FILE_NAME, NC_NETCDF4, &ncid);
   if(retval != NC_NOERR) handle_err(retval);

   /* Create the vlen type. */
   retval = nc_def_vlen(ncid, vlen_type_name, NC_INT, &vlen_typeid);
   if(retval != NC_NOERR) handle_err(retval);

   /* Set up the vlen with this helper function, since F77 can"t deal */
   /* with pointers. */
   retval = nc_put_vlen_element(ncid, vlen_typeid, vlen, vlen_len, data1);
   if(retval != NC_NOERR) handle_err(retval);

   /* Write the vlen attribute. */
   retval = nc_put_att(ncid, NC_GLOBAL, "att1", vlen_typeid, 1, vlen);
   if(retval != NC_NOERR) handle_err(retval);

   /* Close the file. */
   retval = nc_close(ncid);
   if(retval != NC_NOERR) handle_err(retval);

   /* Reopen the file. */
   retval = nc_open(FILE_NAME, NC_NOWRITE, &ncid);
   if(retval != NC_NOERR) handle_err(retval);

   /* Get the typeids of all user defined types. */
   retval = nc_inq_typeids(ncid, &num_types, typeids);
   if(retval != NC_NOERR) handle_err(retval);
   if (num_types != max_types)
        abort();

   /* Use nf_inq_user_type to confirm this is an vlen type, with vlen */
   /* size 16, base type NF_INT. */
   retval = nc_inq_user_type(ncid, typeids[0], type_name, &type_size,
        &base_type, &nfields, &clas);
   if(retval != NC_NOERR) handle_err(retval);
   if (strcmp(type_name,vlen_type_name) != 0
       || type_size != sizeof(nc_vlen_t)
       || base_type !=  NC_INT
       || nfields != 0
       || clas != NC_VLEN)
        abort();

   /* Use nf_inq_vlen and make sure we get the same answers as we did */
   /* with nf_inq_user_type. */
   retval = nc_inq_vlen(ncid, typeids[0], type_name, &base_size, &base_type);
   if(retval != NC_NOERR) handle_err(retval);
   if (strcmp(type_name,vlen_type_name) != 0
       || base_type != NC_INT
       || base_size != sizeof(nc_vlen_t))
        abort();

   /* Read the vlen attribute. */
   retval = nc_get_att(ncid, NC_GLOBAL, "att1", &vlen_in);
   if(retval != NC_NOERR) handle_err(retval);

   /* Get the data from the vlen we just read. */
   retval = nc_get_vlen_element(ncid, vlen_typeid, vlen_in, &vlen_len_in, 
data1_in);
   if(retval != NC_NOERR) handle_err(retval);
   if (vlen_len_in != vlen_len)
        abort();

   /* Check the data */
   for(x=0;x<vlen_len;x++) {
      if(data1[x] != data1_in[x])
        abort();
   }

   /* Close the file. */
   retval = nc_close(ncid);
   if(retval != NC_NOERR) handle_err(retval);

   printf("*** SUCCESS\n");
   return 0;
}