/src/netcdf-c/libnczarr/zopen.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright 2003-2018, University Corporation for Atmospheric |
2 | | * Research. See COPYRIGHT file for copying and redistribution |
3 | | * conditions. */ |
4 | | /** |
5 | | * @file |
6 | | * @internal This file contains functions that are used in file |
7 | | * opens. |
8 | | * |
9 | | * @author Dennis Heimbigner, Ed Hartnett |
10 | | */ |
11 | | |
12 | | #include "zincludes.h" |
13 | | #include "ncmodel.h" |
14 | | |
15 | | #define NUM_TYPES 12 /**< Number of netCDF atomic types. */ |
16 | | #define CD_NELEMS_ZLIB 1 /**< Number of parameters needed for filter. */ |
17 | | |
18 | | /** @internal These flags may not be set for open mode. */ |
19 | | static const int ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_DISKLESS|NC_64BIT_OFFSET|NC_CDF5); |
20 | | |
21 | | /* Forward */ |
22 | | |
23 | | /** |
24 | | * @internal Check for the attribute that indicates that netcdf |
25 | | * classic model is in use. |
26 | | * |
27 | | * @param root_grp pointer to the group info for the root group of the |
28 | | * @param is_classic store 1 if this is a classic file. |
29 | | * file. |
30 | | * |
31 | | * @return NC_NOERR No error. |
32 | | * @author Dennis Heimbigner, Ed Hartnett |
33 | | */ |
34 | | static int |
35 | | check_for_classic_model(NC_GRP_INFO_T *root_grp, int *is_classic) |
36 | 0 | { |
37 | 0 | int attr_exists = 0; |
38 | | /* Check inputs. */ |
39 | 0 | assert(root_grp && root_grp->format_grp_info && !root_grp->parent |
40 | 0 | && is_classic); |
41 | | |
42 | 0 | *is_classic = attr_exists ? 1 : 0; |
43 | |
|
44 | 0 | return NC_NOERR; |
45 | 0 | } |
46 | | |
47 | | /** |
48 | | * @internal Open a netcdf-4 file. Things have already been kicked off |
49 | | * in ncfunc.c in nc_open, but here the netCDF-4 part of opening a |
50 | | * file is handled. |
51 | | * |
52 | | * @param path The file name of the new file. |
53 | | * @param mode The open mode flag. |
54 | | * @param fraglist uri fragment list in envv form |
55 | | * @param nc Pointer to NC file info. |
56 | | * |
57 | | * @return ::NC_NOERR No error. |
58 | | * @return ::NC_ENOMEM Out of memory. |
59 | | * @return ::NC_EINTERNAL Internal list error. |
60 | | * @return ::NC_EHDFERR HDF error. |
61 | | * @return ::NC_EMPI MPI error for parallel. |
62 | | * @return ::NC_EPARINIT Parallel I/O initialization error. |
63 | | * @return ::NC_EINMEMMORY Memory file error. |
64 | | * @author Dennis Heimbigner, Ed Hartnett |
65 | | */ |
66 | | static int |
67 | | ncz_open_file(const char *path, int mode, const char** controls, int ncid) |
68 | 0 | { |
69 | 0 | int stat = NC_NOERR; |
70 | 0 | NC_FILE_INFO_T *h5 = NULL; |
71 | 0 | int is_classic; |
72 | 0 | NC* nc = NULL; |
73 | |
|
74 | 0 | LOG((3, "%s: path %s mode %d", __func__, path, mode)); |
75 | 0 | assert(path); |
76 | | |
77 | 0 | ZTRACE(2,"path=%s,mode=%d,ncid=%d,controls=%s)",path,mode,ncid,(controls?nczprint_envv(controls):"null")); |
78 | | |
79 | | /* Convert ncid to an NC* structure pointer */ |
80 | 0 | if((stat = NC_check_id(ncid,&nc))) goto exit; |
81 | | |
82 | | /* Add necessary structs to hold netcdf-4 file data; |
83 | | will define the NC_FILE_INFO_T for the file |
84 | | and the NC_GRP_INFO_T for the root group. */ |
85 | 0 | if ((stat = nc4_nc4f_list_add(nc, path, mode))) |
86 | 0 | goto exit; |
87 | 0 | h5 = (NC_FILE_INFO_T*)nc->dispatchdata; |
88 | 0 | assert(h5 && h5->root_grp); |
89 | | |
90 | 0 | h5->mem.inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY); |
91 | 0 | h5->mem.diskless = ((mode & NC_DISKLESS) == NC_DISKLESS); |
92 | 0 | h5->mem.persist = ((mode & NC_PERSIST) == NC_PERSIST); |
93 | | |
94 | | /* Does the mode specify that this file is read-only? */ |
95 | 0 | if ((mode & NC_WRITE) == 0) |
96 | 0 | h5->no_write = NC_TRUE; |
97 | | |
98 | | /* Setup zarr state */ |
99 | 0 | if((stat = ncz_open_dataset(h5,controls))) |
100 | 0 | goto exit; |
101 | | |
102 | | /* Now read in all the metadata. Some types |
103 | | * information may be difficult to resolve here, if, for example, a |
104 | | * dataset of user-defined type is encountered before the |
105 | | * definition of that type. */ |
106 | 0 | if((stat = ncz_read_file(h5))) |
107 | 0 | goto exit; |
108 | | |
109 | | /* We must read in the attributes of the root group to get |
110 | | e.g. provenance and classic model attribute */ |
111 | 0 | if((stat = ncz_read_atts(h5,(NC_OBJ*)h5->root_grp))) goto exit; |
112 | | |
113 | | /* Check for classic model attribute. */ |
114 | 0 | if ((stat = check_for_classic_model(h5->root_grp, &is_classic))) |
115 | 0 | goto exit; |
116 | 0 | if (is_classic) |
117 | 0 | h5->cmode |= NC_CLASSIC_MODEL; |
118 | |
|
119 | | #ifdef LOGGING |
120 | | /* This will print out the names, types, lens, etc of the vars and |
121 | | atts in the file, if the logging level is 2 or greater. */ |
122 | | log_metadata_nc(h5); |
123 | | #endif |
124 | |
|
125 | 0 | exit: |
126 | 0 | if (stat && h5) |
127 | 0 | ncz_closeorabort(h5, NULL, 1); /* treat like abort*/ |
128 | 0 | return ZUNTRACE(stat); |
129 | 0 | } |
130 | | |
131 | | /** |
132 | | * @internal Open a netCDF-4 file. |
133 | | * |
134 | | * @param path The file name of the new file. |
135 | | * @param mode The open mode flag. |
136 | | * @param basepe Ignored by this function. |
137 | | * @param chunksizehintp Ignored by this function. |
138 | | * @param parameters pointer to struct holding extra data (e.g. for parallel I/O) |
139 | | * layer. Ignored if NULL. |
140 | | * @param dispatch Pointer to the dispatch table for this file. |
141 | | * @param nc_file Pointer to an instance of NC. |
142 | | * |
143 | | * @return ::NC_NOERR No error. |
144 | | * @return ::NC_EINVAL Invalid inputs. |
145 | | * @author Dennis Heimbigner, Ed Hartnett |
146 | | */ |
147 | | int |
148 | | NCZ_open(const char *path, int mode, int basepe, size_t *chunksizehintp, |
149 | | void *parameters, const NC_Dispatch *dispatch, int ncid) |
150 | 0 | { |
151 | 0 | int stat = NC_NOERR; |
152 | 0 | NCURI* uri = NULL; |
153 | |
|
154 | 0 | ZTRACE(0,"path=%s,mode=%d,ncid=%d)",path,mode,ncid); |
155 | |
|
156 | 0 | NC_UNUSED(parameters); |
157 | |
|
158 | 0 | assert(path && dispatch); |
159 | | |
160 | 0 | LOG((1, "%s: path %s mode %d ", |
161 | 0 | __func__, path, mode)); |
162 | | |
163 | | /* Check the mode for validity */ |
164 | 0 | if (mode & ILLEGAL_OPEN_FLAGS) |
165 | 0 | {stat = NC_EINVAL; goto done;} |
166 | | |
167 | 0 | if((mode & NC_DISKLESS) && (mode & NC_INMEMORY)) |
168 | 0 | {stat = NC_EINVAL; goto done;} |
169 | | |
170 | | /* If this is our first file, initialize NCZ. */ |
171 | 0 | if (!ncz_initialized) NCZ_initialize(); |
172 | |
|
173 | | #ifdef LOGGING |
174 | | /* If nc logging level has changed, see if we need to turn on |
175 | | * NCZ's error messages. */ |
176 | | NCZ_set_log_level(); |
177 | | #endif /* LOGGING */ |
178 | | |
179 | | /* Get the controls */ |
180 | 0 | ncuriparse(path,&uri); |
181 | 0 | if(uri == NULL) goto done; |
182 | | |
183 | | /* Open the file. */ |
184 | 0 | if((stat = ncz_open_file(path, mode, ncurifragmentparams(uri), ncid))) |
185 | 0 | goto done; |
186 | | |
187 | 0 | done: |
188 | 0 | ncurifree(uri); |
189 | 0 | return ZUNTRACE(stat); |
190 | 0 | } |
191 | | |