NetCDF-Fortran  4.4.2
fort-lib.c
1 /*
2 This file is part of the netCDF Fortran 77 API.
3 
4 This file handles the the conversion of vecors from fortran to C.
5 
6 Copyright 2006, University Corporation for Atmospheric Research. See
7 the COPYRIGHT file for copying and redistribution conditions.
8 */
9 
10 #include <config.h>
11 #include <stddef.h> /* for NULL */
12 #include <errno.h>
13 
14 #include "netcdf.h"
15 #include "ncfortran.h"
16 #include "fort-lib.h"
17 
18 /*
19  * Convert a C dimension-ID vector into a FORTRAN dimension-ID vector.
20  */
21 EXTERNL NF_INTEGER *
22 c2f_dimids(int ncid, int varid, const int* cdimids, NF_INTEGER* fdimids)
23 {
24  int i;
25  int ndims;
26 
27  if (nc_inq_varndims(ncid, varid, &ndims) != 0)
28  return NULL;
29 
30  for (i = 0; i < ndims; ++i)
31  fdimids[ndims - 1 - i] = cdimids[i] + 1;
32 
33  return fdimids;
34 }
35 
36 /*
37  * Convert a FORTRAN dimension-ID vector into a C dimension-ID vector.
38  */
39 EXTERNL int *
40 f2c_dimids(int ndims, const NF_INTEGER* fdimids, int* cdimids)
41 {
42  int i;
43 
44  for (i = 0; i < ndims; ++i)
45  cdimids[i] = fdimids[ndims - 1 - i] - 1;
46 
47  return cdimids;
48 }
49 
50 /* Convert a C dimension-ID vector into a FORTRAN dimension-ID vector. */
51 EXTERNL NF_INTEGER *
52 c2f_chunksizes(int ncid, int varid, const int *cchunksizes, NF_INTEGER *fchunksizes)
53 {
54  int i;
55  int ndims;
56 
57  if (nc_inq_varndims(ncid, varid, &ndims))
58  return NULL;
59 
60  for (i = 0; i < ndims; ++i)
61  fchunksizes[ndims - 1 - i] = cchunksizes[i];
62 
63  return fchunksizes;
64 }
65 
66 /* Convert a FORTRAN dimension-ID vector into a C dimension-ID vector. */
67 EXTERNL int *
68 f2c_chunksizes(int ncid, int varid, const NF_INTEGER *fchunksizes, int *cchunksizes)
69 {
70  int i;
71  int ndims;
72 
73  if (nc_inq_varndims(ncid, varid, &ndims))
74  return NULL;
75 
76  for (i = 0; i < ndims; ++i)
77  cchunksizes[i] = fchunksizes[ndims - 1 - i];
78 
79  return cchunksizes;
80 }
81 
82 /*
83  * Convert FORTRAN co-ordinates into C co-ordinates.
84  */
85 EXTERNL size_t *
86 f2c_coords(int ncid, int varid, const NF_INTEGER* fcoords,
87  size_t *ccoords)
88 {
89  int i;
90  int ndims;
91 
92  if (nc_inq_varndims(ncid, varid, &ndims) != 0)
93  return NULL;
94 
95  for (i = 0; i < ndims; ++i)
96  ccoords[i] = fcoords[ndims - 1 - i] - 1;
97 
98  return ccoords;
99 }
100 
101 
102 /*
103  * Convert FORTRAN counts into C counts.
104  */
105 EXTERNL size_t *
106 f2c_counts(int ncid, int varid, const NF_INTEGER* fcounts,
107  size_t* ccounts)
108 {
109  int i;
110  int ndims;
111 
112  if (nc_inq_varndims(ncid, varid, &ndims) != 0)
113  return NULL;
114 
115  for (i = 0; i < ndims; ++i)
116  ccounts[i] = fcounts[ndims - 1 - i];
117 
118  return ccounts;
119 }
120 
121 
122 /*
123  * Convert FORTRAN strides into C strides.
124  *
125  * Helper function.
126  */
127 EXTERNL ptrdiff_t *
128 f2c_strides(int ncid, int varid, const NF_INTEGER* fstrides,
129  ptrdiff_t* cstrides)
130 {
131  int i;
132  int ndims;
133 
134  if (nc_inq_varndims(ncid, varid, &ndims) != 0)
135  return NULL;
136 
137  for (i = 0; i < ndims; ++i)
138  cstrides[i] = fstrides[ndims - 1 - i];
139 
140  return cstrides;
141 }
142 
143 
144 /*
145  * Convert a FORTRAN mapping vector into a C mapping vector.
146  */
147 EXTERNL ptrdiff_t *
148 f2c_maps(int ncid, int varid, const NF_INTEGER* fmaps, ptrdiff_t* cmaps)
149 {
150  return f2c_strides(ncid, varid, fmaps, cmaps);
151 }
152 
153 #ifdef USE_NETCDF4
154 /* These appear to only be defined in netcdf-4*/
155 
156 /* Get the varids for a fortran function (i.e. add 1 to each
157  * varid.) */
158 EXTERNL int
159 nc_inq_varids_f(int ncid, int *nvars, int *fvarids)
160 {
161  int *varids, nvars1;
162  int i, ret = NC_NOERR;
163 
164  /* Get the information from the C library. */
165  if ((ret = nc_inq_varids(ncid, &nvars1, NULL)))
166  return ret;
167  if (!(varids = malloc(nvars1 * sizeof(int))))
168  return NC_ENOMEM;
169  if ((ret = nc_inq_varids(ncid, NULL, varids)))
170  goto exit;
171 
172  /* Add one to each, for fortran. */
173  for (i = 0; i < nvars1; i++)
174  fvarids[i] = varids[i] + 1;
175 
176  /* Tell the user how many there are. */
177  if (nvars)
178  *nvars = nvars1;
179 
180  exit:
181  free(varids);
182  return ret;
183 }
184 
185 /* Get the dimids for a fortran function (i.e. add 1 to each
186  * dimid.) */
187 EXTERNL int
188 nc_inq_dimids_f(int ncid, int *ndims, int *fdimids, int parent)
189 {
190  int *dimids, ndims1;
191  int i, ret = NC_NOERR;
192 
193  /* Get the information from the C library. */
194  if ((ret = nc_inq_dimids(ncid, &ndims1, NULL, parent)))
195  return ret;
196  if (!(dimids = malloc(ndims1 * sizeof(int))))
197  return NC_ENOMEM;
198  if ((ret = nc_inq_dimids(ncid, NULL, dimids, parent)))
199  goto exit;
200 
201  /* Add one to each, for fortran. */
202  for (i = 0; i < ndims1; i++)
203  fdimids[i] = dimids[i] + 1;
204 
205  /* Tell the user how many there are. */
206  if (ndims)
207  *ndims = ndims1;
208 
209  exit:
210  free(dimids);
211  return ret;
212 }
213 
214 /* Swap the dim sizes for fortran. */
215 EXTERNL int
216 nc_insert_array_compound_f(int ncid, int typeid, char *name,
217  size_t offset, nc_type field_typeid,
218  int ndims, int *dim_sizesp)
219 {
220  int *dim_sizes_f;
221  int i, ret;
222 
223  if (ndims <= 0)
224  return NC_EINVAL;
225 
226  /* Allocate some storage to hold ids. */
227  if (!(dim_sizes_f = malloc(ndims * sizeof(int))))
228  return NC_ENOMEM;
229 
230  /* Create a backwards list of dimension sizes. */
231  for (i = 0; i < ndims; i++)
232  dim_sizes_f[i] = dim_sizesp[ndims - i - 1];
233 
234  /* Call with backwards list. */
235  ret = nc_insert_array_compound(ncid, typeid, name, offset, field_typeid,
236  ndims, dim_sizes_f);
237 
238  /* Clean up. */
239  free(dim_sizes_f);
240  return ret;
241 }
242 
243 EXTERNL int
244 nc_inq_compound_field_f(int ncid, nc_type xtype, int fieldid, char *name,
245  size_t *offsetp, nc_type *field_typeidp, int *ndimsp,
246  int *dim_sizesp)
247 {
248  int ndims;
249  int ret;
250 
251  /* Find out how many dims. */
252  if ((ret = nc_inq_compound_field(ncid, xtype, fieldid, NULL, NULL,
253  NULL, &ndims, NULL)))
254  return ret;
255 
256  /* Call the function. */
257  if ((ret = nc_inq_compound_field(ncid, xtype, fieldid, name, offsetp,
258  field_typeidp, ndimsp, dim_sizesp)))
259  return ret;
260 
261  /* Swap the order of the dimsizes. */
262  if (ndims)
263  {
264  int *f, *b, temp;
265  for (f = dim_sizesp, b = &dim_sizesp[ndims - 1]; f < b; f++, b--)
266  {
267  temp = *f;
268  *f = *b;
269  *b = temp;
270  }
271  }
272 
273  return NC_NOERR;
274 }
275 
276 #endif /*USE_NETCDF4*/

Return to the Main Unidata NetCDF page.
Generated on Wed Aug 19 2015 17:51:09 for NetCDF-Fortran. NetCDF is a Unidata library.