1/*
2  Copyright 2008, UCAR/Unidata
3  See COPYRIGHT file for copying and redistribution conditions.
4
5  This program tests the large file bug in netCDF 3.6.2,
6  creating byte and short variables larger than 4 GiB.
7
8  $Id: tst_large.c,v 1.16 2010/05/18 20:20:01 russ Exp $
9*/
10#include <config.h>
11#include <stdio.h>
12#include <string.h>
13#include <stdlib.h>
14#include <nc_tests.h>
15#include "err_macros.h"
16#include <netcdf.h>
17
18/* Test with both classic and 64-bit offset files. If netcdf-4 is
19 * included, test with both netCDF-4 format variants also. */
20#ifdef USE_NETCDF4
21#define NUM_FORMATS (4)
22#else
23#define NUM_FORMATS (2)
24#endif
25
26#define NUMDIMS 2 /* rank of each variable in tests */
27#define DIM1 2048
28#define DIM2 2097153 /* DIM1*DIM2*sizeof(char)   > 2**32 */
29#define DIM3 1024
30#define DIM4 2097153 /* DIM3*DIM4*sizeof(short)  > 2**32  */
31
32/*
33 * In netCDF-3.6.2, a divide by zero occurs on 32-bit platforms when
34 * creating a variable for which the product of dimensions is exactly
35 * 2**32.  Check that this bug has been fixed.
36 */
37static int
38test_big_var(const char *testfile) {
39    int ncidvariddimids[NUMDIMS];
40    int cflag = NC_CLOBBER;
41    nc_type type = NC_BYTE;
42    size_t index[NUMDIMS];
43    signed char nval = 99;
44    int nval_in;
45
46    /* Define the file with one large variable. */
47    if (nc_create(testfilecflag, &ncid)) ERR;
48    if (nc_set_fill(ncidNC_NOFILLNULL)) ERR;
49    if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR;
50    if (nc_def_dim(ncid, "dim2", DIM2 - 1, &dimids[1])) ERR;
51    if (nc_def_var(ncid, "var", typeNUMDIMSdimids, &varid)) ERR;
52    if (nc_enddef(ncid)) ERR;
53
54    /* Write one datum, near the end of the variable. */
55    index[0] = DIM1 - 1;
56    index[1] = DIM2 - 2;
57    if (nc_put_var1_schar(ncidvaridindex, &nval)) ERR;
58    if (nc_close(ncid)) ERR;
59
60    /* Reopen the file and check that datum. */
61    if (nc_open(testfileNC_NOWRITE, &ncid)) ERR;
62    if (nc_inq_varid(ncid, "var", &varid)) ERR;
63    if (nc_get_var1_int(ncidvaridindex, &nval_in)) ERR;
64    if (nval != nval_in)
65 ERR;
66    if (nc_close(ncid)) ERR;
67    return 0;
68}
69
70static int
71test_large_byte_var(const char *testfile) {
72    int ncidvariddimids[NUMDIMS];
73    size_t index[NUMDIMS] = {0, 0};
74    signed char vals[DIM2];
75    signed char char_val_in;
76    size_t start[NUMDIMS], count[NUMDIMS];
77    int j;
78
79    if (nc_create(testfileNC_CLOBBER, &ncid)) ERR;
80    if (nc_set_fill(ncidNC_NOFILLNULL)) ERR;
81    if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR;
82    if (nc_def_dim(ncid, "dim2", DIM2, &dimids[1])) ERR;
83    if (nc_def_var(ncid, "var", NC_BYTENUMDIMSdimids, &varid)) ERR;
84    if (nc_enddef(ncid)) ERR;
85
86    for (j = 0; j < DIM2j++) {
87       vals[j] = 9 * (j + 11); /* note vals[j] is 99 when j==0 */
88    }
89    start[1] = 0;
90    count[0] = 1;
91    count[1] = DIM2;
92    for (start[0] = 0; start[0] < DIM1start[0]++) {
93 if (nc_put_vara_schar(ncidvaridstartcountvals))
94 {
95     ERR;
96     break;
97 }
98    }
99
100    if (nc_close(ncid)) ERR;
101    if (nc_open(testfileNC_NOWRITE, &ncid)) ERR;
102    if (nc_inq_varid(ncid, "var", &varid)) ERR;
103    if (nc_get_var1_schar(ncidvaridindex, &char_val_in)) ERR;
104    if (char_val_in != 99) /* see above, the value written when start[0]==0, j==0 */
105 ERR;
106    if (nc_close(ncid)) ERR;
107    return 0;
108}
109
110static int
111test_large_short_var(const char *testfile) {
112    int ncidvariddimids[NUMDIMS];
113    int int_val_inint_val_out = 99;
114    size_t index[2];
115    int cflag = NC_CLOBBER;
116
117    if (nc_create(testfilecflag, &ncid)) ERR;
118    if (nc_def_dim(ncid, "dim3", DIM3, &dimids[0])) ERR;
119    if (nc_def_dim(ncid, "dim4", DIM4, &dimids[1])) ERR;
120    if (nc_def_var(ncid, "var", NC_SHORTNUMDIMSdimids, &varid)) ERR;
121    if (nc_enddef(ncid)) ERR;
122    index[0] = 0;
123    index[1] = 1;
124    if (nc_put_var1_int(ncidvaridindex, &int_val_out)) ERR;
125    if (nc_close(ncid)) ERR;
126    if (nc_open(testfileNC_NOWRITE, &ncid)) ERR;
127    if (nc_inq_varid(ncid, "var", &varid)) ERR;
128    if (nc_get_var1_int(ncidvaridindex, &int_val_in)) ERR;
129    if (int_val_in != int_val_out)
130 ERR;
131#ifndef NOFILL
132    index[0] = 1;
133    index[1] = 2;
134    if (nc_get_var1_int(ncidvaridindex, &int_val_in)) ERR;
135    if (int_val_in != NC_FILL_SHORT)
136 ERR;
137#endif
138    if (nc_close(ncid)) ERR;
139    return 0;
140}
141
142#define FILE_NAME "tst_large.nc"
143
144int
145main(int argc, char **argv) {
146    int i;
147    char testfile[NC_MAX_NAME + 1];
148
149    sprintf(testfile, "%s/%s", TEMP_LARGEFILE_NAME);
150
151    printf("\n*** Testing fix for 3.6.2 large file bug in %s.\n",
152    testfile);
153   /* Go thru formats and run all tests for each of two (for netCDF-3
154    * only builds), or 4 (for netCDF-4 builds) different formats. */
155    for (i = NC_FORMAT_CLASSICi <= NUM_FORMATSi++)
156    {
157       nc_set_default_format(iNULL);
158
159       printf("*** testing format %d with a variable with 2**32 values...", i);
160       test_big_var(testfile);
161       (void) remove(testfile);
162       SUMMARIZE_ERR;
163
164       printf("*** testing format %d with a byte variable with > 2**32 values...", i);
165       test_large_byte_var(testfile);
166       (void) remove(testfile);
167       SUMMARIZE_ERR;
168
169       printf("*** testing format %d with a short variable with > 2**32 values...", i);
170       test_large_short_var(testfile);
171       (void) remove(testfile);
172       SUMMARIZE_ERR;
173    }
174
175    FINAL_RESULTS;
176}


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed