NetCDF  4.9.3
dfile.c
Go to the documentation of this file.
1 
13 #include "config.h"
14 #include <stdlib.h>
15 #ifdef HAVE_STRING_H
16 #include <string.h>
17 #endif
18 #ifdef HAVE_SYS_RESOURCE_H
19 #include <sys/resource.h>
20 #endif
21 #ifdef HAVE_SYS_TYPES_H
22 #include <sys/types.h>
23 #endif
24 #ifdef HAVE_SYS_STAT_H
25 #include <sys/stat.h>
26 #endif
27 
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h> /* lseek() */
30 #endif
31 
32 #ifdef HAVE_STDIO_H
33 #include <stdio.h>
34 #endif
35 
36 #include "ncdispatch.h"
37 #include "netcdf_mem.h"
38 #include "ncpathmgr.h"
39 #include "fbits.h"
40 
41 #undef DEBUG
42 
43 #ifndef nulldup
44  #define nulldup(s) ((s)?strdup(s):NULL)
45 #endif
46 
47 
48 /* User-defined formats. */
49 NC_Dispatch *UDF0_dispatch_table = NULL;
50 char UDF0_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
51 NC_Dispatch *UDF1_dispatch_table = NULL;
52 char UDF1_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
53 
54 /**************************************************/
55 
56 
122 int
123 nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
124 {
125  /* Check inputs. */
126  if (!dispatch_table)
127  return NC_EINVAL;
128  if (magic_number && strlen(magic_number) > NC_MAX_MAGIC_NUMBER_LEN)
129  return NC_EINVAL;
130 
131  /* Check the version of the dispatch table provided. */
132  if (dispatch_table->dispatch_version != NC_DISPATCH_VERSION)
133  return NC_EINVAL;
134  /* user defined magic numbers not allowed with netcdf3 modes */
135  if (magic_number && (fIsSet(mode_flag, NC_64BIT_OFFSET) ||
136  fIsSet(mode_flag, NC_64BIT_DATA) ||
137  (fIsSet(mode_flag, NC_CLASSIC_MODEL) &&
138  !fIsSet(mode_flag, NC_NETCDF4))))
139  return NC_EINVAL;
140  /* Retain a pointer to the dispatch_table and a copy of the magic
141  * number, if one was provided. */
142  if (fIsSet(mode_flag,NC_UDF0))
143  {
144  UDF0_dispatch_table = dispatch_table;
145  if (magic_number)
146  strncpy(UDF0_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
147  }
148  else if(fIsSet(mode_flag, NC_UDF1))
149  {
150  UDF1_dispatch_table = dispatch_table;
151  if (magic_number)
152  strncpy(UDF1_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
153  }
154  else
155  {
156  return NC_EINVAL;
157  }
158 
159  return NC_NOERR;
160 }
161 
178 int
179 nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
180 {
181  /* Check inputs. */
182  if (fIsSet(mode_flag,NC_UDF0))
183  {
184  if (dispatch_table)
185  *dispatch_table = UDF0_dispatch_table;
186  if (magic_number)
187  strncpy(magic_number, UDF0_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
188  }
189  else if(fIsSet(mode_flag,NC_UDF1))
190  {
191  if (dispatch_table)
192  *dispatch_table = UDF1_dispatch_table;
193  if (magic_number)
194  strncpy(magic_number, UDF1_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
195  }
196  else
197  {
198  return NC_EINVAL;
199  }
200 
201  return NC_NOERR;
202 }
203 
397 int
398 nc_create(const char *path, int cmode, int *ncidp)
399 {
400  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
401 }
402 
469 int
470 nc__create(const char *path, int cmode, size_t initialsz,
471  size_t *chunksizehintp, int *ncidp)
472 {
473  return NC_create(path, cmode, initialsz, 0,
474  chunksizehintp, 0, NULL, ncidp);
475 }
476 
515 int
516 nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
517 {
518  if(mode & NC_MMAP) return NC_EINVAL;
519  mode |= NC_INMEMORY; /* Specifically, do not set NC_DISKLESS */
520  return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
521 }
522 
542 int
543 nc__create_mp(const char *path, int cmode, size_t initialsz,
544  int basepe, size_t *chunksizehintp, int *ncidp)
545 {
546  return NC_create(path, cmode, initialsz, basepe,
547  chunksizehintp, 0, NULL, ncidp);
548 }
549 
663 int
664 nc_open(const char *path, int omode, int *ncidp)
665 {
666  return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
667 }
668 
720 int
721 nc__open(const char *path, int omode,
722  size_t *chunksizehintp, int *ncidp)
723 {
724  /* this API is for non-parallel access.
725  * Note nc_open_par() also calls NC_open().
726  */
727  return NC_open(path, omode, 0, chunksizehintp, 0, NULL, ncidp);
728 }
729 
775 int
776 nc_open_mem(const char* path, int omode, size_t size, void* memory, int* ncidp)
777 {
778  NC_memio meminfo;
779 
780  /* Sanity checks */
781  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
782  return NC_EINVAL;
783  if(omode & (NC_WRITE|NC_MMAP))
784  return NC_EINVAL;
785  omode |= (NC_INMEMORY); /* Note: NC_INMEMORY and NC_DISKLESS are mutually exclusive*/
786  meminfo.size = size;
787  meminfo.memory = memory;
788  meminfo.flags = NC_MEMIO_LOCKED;
789  return NC_open(path, omode, 0, NULL, 0, &meminfo, ncidp);
790 }
791 
840 int
841 nc_open_memio(const char* path, int omode, NC_memio* params, int* ncidp)
842 {
843  /* Sanity checks */
844  if(path == NULL || params == NULL)
845  return NC_EINVAL;
846  if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
847  return NC_EINVAL;
848 
849  if(omode & NC_MMAP)
850  return NC_EINVAL;
851  omode |= (NC_INMEMORY);
852  return NC_open(path, omode, 0, NULL, 0, params, ncidp);
853 }
854 
873 int
874 nc__open_mp(const char *path, int omode, int basepe,
875  size_t *chunksizehintp, int *ncidp)
876 {
877  return NC_open(path, omode, basepe, chunksizehintp, 0, NULL, ncidp);
878 }
879 
897 int
898 nc_inq_path(int ncid, size_t *pathlen, char *path)
899 {
900  NC* ncp;
901  int stat = NC_NOERR;
902  if ((stat = NC_check_id(ncid, &ncp)))
903  return stat;
904  if(ncp->path == NULL) {
905  if(pathlen) *pathlen = 0;
906  if(path) path[0] = '\0';
907  } else {
908  if (pathlen) *pathlen = strlen(ncp->path);
909  if (path) strcpy(path, ncp->path);
910  }
911  return stat;
912 }
913 
962 int
963 nc_redef(int ncid)
964 {
965  NC* ncp;
966  int stat = NC_check_id(ncid, &ncp);
967  if(stat != NC_NOERR) return stat;
968  return ncp->dispatch->redef(ncid);
969 }
970 
1026 int
1027 nc_enddef(int ncid)
1028 {
1029  int status = NC_NOERR;
1030  NC *ncp;
1031  status = NC_check_id(ncid, &ncp);
1032  if(status != NC_NOERR) return status;
1033  return ncp->dispatch->_enddef(ncid,0,1,0,1);
1034 }
1035 
1117 int
1118 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1119  size_t r_align)
1120 {
1121  NC* ncp;
1122  int stat = NC_check_id(ncid, &ncp);
1123  if(stat != NC_NOERR) return stat;
1124  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1125 }
1126 
1194 int
1195 nc_sync(int ncid)
1196 {
1197  NC* ncp;
1198  int stat = NC_check_id(ncid, &ncp);
1199  if(stat != NC_NOERR) return stat;
1200  return ncp->dispatch->sync(ncid);
1201 }
1202 
1246 int
1247 nc_abort(int ncid)
1248 {
1249  NC* ncp;
1250  int stat = NC_check_id(ncid, &ncp);
1251  if(stat != NC_NOERR) return stat;
1252 
1253  stat = ncp->dispatch->abort(ncid);
1254  del_from_NCList(ncp);
1255  free_NC(ncp);
1256  return stat;
1257 }
1258 
1299 int
1300 nc_close(int ncid)
1301 {
1302  NC* ncp;
1303  int stat = NC_check_id(ncid, &ncp);
1304  if(stat != NC_NOERR) return stat;
1305 
1306  stat = ncp->dispatch->close(ncid,NULL);
1307  /* Remove from the nc list */
1308  if (!stat)
1309  {
1310  del_from_NCList(ncp);
1311  free_NC(ncp);
1312  }
1313  return stat;
1314 }
1315 
1358 int
1359 nc_close_memio(int ncid, NC_memio* memio)
1360 {
1361  NC* ncp;
1362  int stat = NC_check_id(ncid, &ncp);
1363  if(stat != NC_NOERR) return stat;
1364 
1365  stat = ncp->dispatch->close(ncid,memio);
1366  /* Remove from the nc list */
1367  if (!stat)
1368  {
1369  del_from_NCList(ncp);
1370  free_NC(ncp);
1371  }
1372  return stat;
1373 }
1374 
1473 int
1474 nc_set_fill(int ncid, int fillmode, int *old_modep)
1475 {
1476  NC* ncp;
1477  int stat = NC_check_id(ncid, &ncp);
1478  if(stat != NC_NOERR) return stat;
1479  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1480 }
1481 
1496 int
1497 nc_inq_base_pe(int ncid, int *pe)
1498 {
1499  NC* ncp;
1500  int stat = NC_check_id(ncid, &ncp);
1501  if(stat != NC_NOERR) return stat;
1502  if (pe) *pe = 0;
1503  return NC_NOERR;
1504 }
1505 
1520 int
1521 nc_set_base_pe(int ncid, int pe)
1522 {
1523  NC* ncp;
1524  int stat = NC_check_id(ncid, &ncp);
1525  if(stat != NC_NOERR) return stat;
1526  return NC_NOERR;
1527 }
1528 
1546 int
1547 nc_inq_format(int ncid, int *formatp)
1548 {
1549  NC* ncp;
1550  int stat = NC_check_id(ncid, &ncp);
1551  if(stat != NC_NOERR) return stat;
1552  return ncp->dispatch->inq_format(ncid,formatp);
1553 }
1554 
1581 int
1582 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1583 {
1584  NC* ncp;
1585  int stat = NC_check_id(ncid, &ncp);
1586  if(stat != NC_NOERR) return stat;
1587  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1588 }
1589 
1634 int
1635 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1636 {
1637  NC* ncp;
1638  int stat = NC_check_id(ncid, &ncp);
1639  if(stat != NC_NOERR) return stat;
1640  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1641 }
1642 
1653 int
1654 nc_inq_nvars(int ncid, int *nvarsp)
1655 {
1656  NC* ncp;
1657  int stat = NC_check_id(ncid, &ncp);
1658  if(stat != NC_NOERR) return stat;
1659  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1660 }
1661 
1727 int
1728 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1729 {
1730  NC* ncp;
1731  int stat;
1732 
1733  /* Do a quick triage on xtype */
1734  if(xtype <= NC_NAT) return NC_EBADTYPE;
1735  /* For compatibility, we need to allow inq about
1736  atomic types, even if ncid is ill-defined */
1737  if(xtype <= ATOMICTYPEMAX4) {
1738  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1739  if(size) *size = NC_atomictypelen(xtype);
1740  return NC_NOERR;
1741  }
1742  /* Apparently asking about a user defined type, so we need
1743  a valid ncid */
1744  stat = NC_check_id(ncid, &ncp);
1745  if(stat != NC_NOERR) /* bad ncid */
1746  return NC_EBADTYPE;
1747  /* have good ncid */
1748  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1749 }
1750 
1774 static int
1776 {
1777  int mode_format;
1778  int use_mmap = 0;
1779  int inmemory = 0;
1780  int diskless = 0;
1781 
1782  /* This is a clever check to see if more than one format bit is
1783  * set. */
1784  mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
1785  (mode & NC_CDF5);
1786  if (mode_format && (mode_format & (mode_format - 1)))
1787  return NC_EINVAL;
1788 
1789  use_mmap = ((mode & NC_MMAP) == NC_MMAP);
1790  inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
1791  diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
1792 
1793  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1794  if(diskless && inmemory) return NC_EDISKLESS;
1795  if(diskless && use_mmap) return NC_EDISKLESS;
1796  if(inmemory && use_mmap) return NC_EINMEMORY;
1797 
1798  /* mmap is not allowed for netcdf-4 */
1799  if(use_mmap && (mode & NC_NETCDF4)) return NC_EINVAL;
1800 
1801 #ifndef USE_NETCDF4
1802  /* If the user asks for a netCDF-4 file, and the library was built
1803  * without netCDF-4, then return an error.*/
1804  if (mode & NC_NETCDF4)
1805  return NC_ENOTBUILT;
1806 #endif /* USE_NETCDF4 undefined */
1807 
1808  /* Well I guess there is some sanity in the world after all. */
1809  return NC_NOERR;
1810 }
1811 
1839 int
1840 NC_create(const char *path0, int cmode, size_t initialsz,
1841  int basepe, size_t *chunksizehintp, int useparallel,
1842  void* parameters, int *ncidp)
1843 {
1844  int stat = NC_NOERR;
1845  NC* ncp = NULL;
1846  const NC_Dispatch* dispatcher = NULL;
1847  char* path = NULL;
1848  NCmodel model;
1849  char* newpath = NULL;
1850 
1851  TRACE(nc_create);
1852  if(path0 == NULL)
1853  {stat = NC_EINVAL; goto done;}
1854 
1855  /* Check mode flag for sanity. */
1856  if ((stat = check_create_mode(cmode))) goto done;
1857 
1858  /* Initialize the library. The available dispatch tables
1859  * will depend on how netCDF was built
1860  * (with/without netCDF-4, DAP, CDMREMOTE). */
1861  if(!NC_initialized) {
1862  if ((stat = nc_initialize())) goto done;
1863  }
1864 
1865  {
1866  /* Skip past any leading whitespace in path */
1867  const unsigned char* p;
1868  for(p=(const unsigned char*)path0;*p;p++) {if(*p > ' ') break;}
1869  path = nulldup((const char*)p);
1870  }
1871 
1872  memset(&model,0,sizeof(model));
1873  newpath = NULL;
1874  if((stat = NC_infermodel(path,&cmode,1,useparallel,NULL,&model,&newpath))) goto done;
1875  if(newpath) {
1876  nullfree(path);
1877  path = newpath;
1878  newpath = NULL;
1879  }
1880 
1881  assert(model.format != 0 && model.impl != 0);
1882 
1883  /* Now, check for NC_ENOTBUILT cases limited to create (so e.g. HDF4 is not listed) */
1884 #ifndef USE_HDF5
1885  if (model.impl == NC_FORMATX_NC4)
1886  {stat = NC_ENOTBUILT; goto done;}
1887 #endif
1888 #ifndef USE_PNETCDF
1889  if (model.impl == NC_FORMATX_PNETCDF)
1890  {stat = NC_ENOTBUILT; goto done;}
1891 #endif
1892 #ifndef NETCDF_ENABLE_CDF5
1893  if (model.impl == NC_FORMATX_NC3 && (cmode & NC_64BIT_DATA))
1894  {stat = NC_ENOTBUILT; goto done;}
1895 #endif
1896 
1897  /* Figure out what dispatcher to use */
1898  switch (model.impl) {
1899 #ifdef USE_HDF5
1900  case NC_FORMATX_NC4:
1901  dispatcher = HDF5_dispatch_table;
1902  break;
1903 #endif
1904 #ifdef USE_PNETCDF
1905  case NC_FORMATX_PNETCDF:
1906  dispatcher = NCP_dispatch_table;
1907  break;
1908 #endif
1909 #ifdef USE_NETCDF4
1910  case NC_FORMATX_UDF0:
1911  dispatcher = UDF0_dispatch_table;
1912  break;
1913  case NC_FORMATX_UDF1:
1914  dispatcher = UDF1_dispatch_table;
1915  break;
1916 #endif /* USE_NETCDF4 */
1917 #ifdef NETCDF_ENABLE_NCZARR
1918  case NC_FORMATX_NCZARR:
1919  dispatcher = NCZ_dispatch_table;
1920  break;
1921 #endif
1922  case NC_FORMATX_NC3:
1923  dispatcher = NC3_dispatch_table;
1924  break;
1925  default:
1926  {stat = NC_ENOTNC; goto done;}
1927  }
1928 
1929  /* Create the NC* instance and insert its dispatcher and model */
1930  if((stat = new_NC(dispatcher,path,cmode,&ncp))) goto done;
1931 
1932  /* Add to list of known open files and define ext_ncid */
1933  add_to_NCList(ncp);
1934 
1935  /* Assume create will fill in remaining ncp fields */
1936  if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp,
1937  parameters, dispatcher, ncp->ext_ncid))) {
1938  del_from_NCList(ncp); /* oh well */
1939  free_NC(ncp);
1940  } else {
1941  if(ncidp)*ncidp = ncp->ext_ncid;
1942  }
1943 done:
1944  nullfree(path);
1945  nullfree(newpath);
1946  return stat;
1947 }
1948 
1972 int
1973 NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
1974  int useparallel, void* parameters, int *ncidp)
1975 {
1976  int stat = NC_NOERR;
1977  NC* ncp = NULL;
1978  const NC_Dispatch* dispatcher = NULL;
1979  int inmemory = 0;
1980  int diskless = 0;
1981  int use_mmap = 0;
1982  char* path = NULL;
1983  NCmodel model;
1984  char* newpath = NULL;
1985 
1986  TRACE(nc_open);
1987  if(!NC_initialized) {
1988  stat = nc_initialize();
1989  if(stat) goto done;
1990  }
1991 
1992  /* Check inputs. */
1993  if (!path0)
1994  {stat = NC_EINVAL; goto done;}
1995 
1996  /* Capture the inmemory related flags */
1997  use_mmap = ((omode & NC_MMAP) == NC_MMAP);
1998  diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
1999  inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
2000 
2001  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
2002  if(diskless && inmemory) {stat = NC_EDISKLESS; goto done;}
2003  if(diskless && use_mmap) {stat = NC_EDISKLESS; goto done;}
2004  if(inmemory && use_mmap) {stat = NC_EINMEMORY; goto done;}
2005 
2006  /* mmap is not allowed for netcdf-4 */
2007  if(use_mmap && (omode & NC_NETCDF4)) {stat = NC_EINVAL; goto done;}
2008 
2009  /* Attempt to do file path conversion: note that this will do
2010  nothing if path is a 'file:...' url, so it will need to be
2011  repeated in protocol code (e.g. libdap2, libdap4, etc).
2012  */
2013 
2014  {
2015  /* Skip past any leading whitespace in path */
2016  const char* p;
2017  for(p=(const char*)path0;*p;p++) {if(*p < 0 || *p > ' ') break;}
2018  path = nulldup(p);
2019  }
2020 
2021  memset(&model,0,sizeof(model));
2022  /* Infer model implementation and format, possibly by reading the file */
2023  if((stat = NC_infermodel(path,&omode,0,useparallel,parameters,&model,&newpath)))
2024  goto done;
2025  if(newpath) {
2026  nullfree(path);
2027  path = newpath;
2028  newpath = NULL;
2029  }
2030 
2031  /* Still no implementation, give up */
2032  if(model.impl == 0) {
2033 #ifdef DEBUG
2034  fprintf(stderr,"implementation == 0\n");
2035 #endif
2036  {stat = NC_ENOTNC; goto done;}
2037  }
2038 
2039  /* Suppress unsupported formats */
2040 #if 0
2041  /* (should be more compact, table-driven, way to do this) */
2042  {
2043  int hdf5built = 0;
2044  int hdf4built = 0;
2045  int cdf5built = 0;
2046  int udf0built = 0;
2047  int udf1built = 0;
2048  int nczarrbuilt = 0;
2049 #ifdef USE_NETCDF4
2050  hdf5built = 1;
2051 #endif
2052 #ifdef USE_HDF4
2053  hdf4built = 1;
2054 #endif
2055 #ifdef NETCDF_ENABLE_CDF5
2056  cdf5built = 1;
2057 #endif
2058 #ifdef NETCDF_ENABLE_NCZARR
2059  nczarrbuilt = 1;
2060 #endif
2061  if(UDF0_dispatch_table != NULL)
2062  udf0built = 1;
2063  if(UDF1_dispatch_table != NULL)
2064  udf1built = 1;
2065 
2066  if(!hdf5built && model.impl == NC_FORMATX_NC4)
2067  {stat = NC_ENOTBUILT; goto done;}
2068  if(!hdf4built && model.impl == NC_FORMATX_NC_HDF4)
2069  {stat = NC_ENOTBUILT; goto done;}
2070  if(!cdf5built && model.impl == NC_FORMATX_NC3 && model.format == NC_FORMAT_CDF5)
2071  {stat = NC_ENOTBUILT; goto done;}
2072  if(!nczarrbuilt && model.impl == NC_FORMATX_NCZARR)
2073  {stat = NC_ENOTBUILT; goto done;}
2074  if(!udf0built && model.impl == NC_FORMATX_UDF0)
2075  {stat = NC_ENOTBUILT; goto done;}
2076  if(!udf1built && model.impl == NC_FORMATX_UDF1)
2077  {stat = NC_ENOTBUILT; goto done;}
2078  }
2079 #else
2080  {
2081  unsigned built = 0 /* leave off the trailing semicolon so we can build constant */
2082  | (1<<NC_FORMATX_NC3) /* NC3 always supported */
2083 #ifdef USE_HDF5
2084  | (1<<NC_FORMATX_NC_HDF5)
2085 #endif
2086 #ifdef USE_HDF4
2087  | (1<<NC_FORMATX_NC_HDF4)
2088 #endif
2089 #ifdef NETCDF_ENABLE_NCZARR
2090  | (1<<NC_FORMATX_NCZARR)
2091 #endif
2092 #ifdef NETCDF_ENABLE_DAP
2093  | (1<<NC_FORMATX_DAP2)
2094 #endif
2095 #ifdef NETCDF_ENABLE_DAP4
2096  | (1<<NC_FORMATX_DAP4)
2097 #endif
2098 #ifdef USE_PNETCDF
2099  | (1<<NC_FORMATX_PNETCDF)
2100 #endif
2101  ; /* end of the built flags */
2102  if(UDF0_dispatch_table != NULL)
2103  built |= (1<<NC_FORMATX_UDF0);
2104  if(UDF1_dispatch_table != NULL)
2105  built |= (1<<NC_FORMATX_UDF1);
2106  /* Verify */
2107  if((built & (1 << model.impl)) == 0)
2108  {stat = NC_ENOTBUILT; goto done;}
2109 #ifndef NETCDF_ENABLE_CDF5
2110  /* Special case because there is no separate CDF5 dispatcher */
2111  if(model.impl == NC_FORMATX_NC3 && (omode & NC_64BIT_DATA))
2112  {stat = NC_ENOTBUILT; goto done;}
2113 #endif
2114  }
2115 #endif
2116  /* Figure out what dispatcher to use */
2117  if (!dispatcher) {
2118  switch (model.impl) {
2119 #ifdef NETCDF_ENABLE_DAP
2120  case NC_FORMATX_DAP2:
2121  dispatcher = NCD2_dispatch_table;
2122  break;
2123 #endif
2124 #ifdef NETCDF_ENABLE_DAP4
2125  case NC_FORMATX_DAP4:
2126  dispatcher = NCD4_dispatch_table;
2127  break;
2128 #endif
2129 #ifdef NETCDF_ENABLE_NCZARR
2130  case NC_FORMATX_NCZARR:
2131  dispatcher = NCZ_dispatch_table;
2132  break;
2133 #endif
2134 #ifdef USE_PNETCDF
2135  case NC_FORMATX_PNETCDF:
2136  dispatcher = NCP_dispatch_table;
2137  break;
2138 #endif
2139 #ifdef USE_HDF5
2140  case NC_FORMATX_NC4:
2141  dispatcher = HDF5_dispatch_table;
2142  break;
2143 #endif
2144 #ifdef USE_HDF4
2145  case NC_FORMATX_NC_HDF4:
2146  dispatcher = HDF4_dispatch_table;
2147  break;
2148 #endif
2149 #ifdef USE_NETCDF4
2150  case NC_FORMATX_UDF0:
2151  dispatcher = UDF0_dispatch_table;
2152  break;
2153  case NC_FORMATX_UDF1:
2154  dispatcher = UDF1_dispatch_table;
2155  break;
2156 #endif /* USE_NETCDF4 */
2157  case NC_FORMATX_NC3:
2158  dispatcher = NC3_dispatch_table;
2159  break;
2160  default:
2161  stat = NC_ENOTNC;
2162  goto done;
2163  }
2164  }
2165 
2166 
2167  /* If we can't figure out what dispatch table to use, give up. */
2168  if (!dispatcher) {stat = NC_ENOTNC; goto done;}
2169 
2170  /* Create the NC* instance and insert its dispatcher */
2171  if((stat = new_NC(dispatcher,path,omode,&ncp))) goto done;
2172 
2173  /* Add to list of known open files. This assigns an ext_ncid. */
2174  add_to_NCList(ncp);
2175 
2176  /* Assume open will fill in remaining ncp fields */
2177  stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2178  parameters, dispatcher, ncp->ext_ncid);
2179  if(stat == NC_NOERR) {
2180  if(ncidp) *ncidp = ncp->ext_ncid;
2181  } else {
2182  del_from_NCList(ncp);
2183  free_NC(ncp);
2184  }
2185 
2186 done:
2187  nullfree(path);
2188  nullfree(newpath);
2189  return stat;
2190 }
2191 
2192 /*Provide an internal function for generating pseudo file descriptors
2193  for systems that are not file based (e.g. dap, memio).
2194 */
2195 
2197 static int pseudofd = 0;
2198 
2206 int
2207 nc__pseudofd(void)
2208 {
2209  if(pseudofd == 0) {
2210 #ifdef HAVE_GETRLIMIT
2211  int maxfd = 32767; /* default */
2212  struct rlimit rl;
2213  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2214  if(rl.rlim_max != RLIM_INFINITY)
2215  maxfd = (int)rl.rlim_max;
2216  if(rl.rlim_cur != RLIM_INFINITY)
2217  maxfd = (int)rl.rlim_cur;
2218  }
2219  pseudofd = maxfd+1;
2220 #endif
2221  }
2222  return pseudofd++;
2223 }
#define NC_MAX_MAGIC_NUMBER_LEN
Max len of user-defined format magic number.
Definition: netcdf.h:178
int nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
Add handling of user-defined format.
Definition: dfile.c:123
int nc_close_memio(int ncid, NC_memio *memio)
Do a normal close (see nc_close()) on an in-memory dataset, then return a copy of the final memory co...
Definition: dfile.c:1359
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:227
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition: netcdf.h:149
Main header file for in-memory (diskless) functionality.
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:963
int nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align)
Leave define mode with performance tuning.
Definition: dfile.c:1118
#define NC_UDF1
User-defined format 1.
Definition: netcdf.h:147
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:172
static int check_create_mode(int mode)
Check the create mode parameter for sanity.
Definition: dfile.c:1775
int nc_open_memio(const char *path, int omode, NC_memio *params, int *ncidp)
Open a netCDF file with the contents taken from a block of memory.
Definition: dfile.c:841
int nc_inq_format(int ncid, int *formatp)
Inquire about the binary format of a netCDF file as presented by the API.
Definition: dfile.c:1547
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1635
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:25
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
Definition: netcdf.h:150
int nc__open(const char *path, int omode, size_t *chunksizehintp, int *ncidp)
Open a netCDF file with extra performance parameters for the classic library.
Definition: dfile.c:721
#define NC_UDF0
User-defined format 0.
Definition: netcdf.h:146
int nc_inq_format_extended(int ncid, int *formatp, int *modep)
Obtain more detailed (vis-a-vis nc_inq_format) format information about an open dataset.
Definition: dfile.c:1582
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:434
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:200
#define NC_64BIT_DATA
CDF-5 format: classic model but 64 bit dimensions and sizes.
Definition: netcdf.h:143
#define NC_ENOTBUILT
Attempt to use feature that was not turned on when netCDF was built.
Definition: netcdf.h:518
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1300
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:519
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1247
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:420
int nc_open_mem(const char *path, int omode, size_t size, void *memory, int *ncidp)
Open a netCDF file with the contents taken from a block of memory.
Definition: dfile.c:776
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:255
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:388
#define NC_EINMEMORY
In-memory file error.
Definition: netcdf.h:526
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1474
#define NC_FORMATX_UDF0
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:232
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:291
#define NC_NAT
Not A Type.
Definition: netcdf.h:34
int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Inquire about a type.
Definition: dfile.c:1728
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:230
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:225
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition: netcdf.h:162
int nc__create(const char *path, int cmode, size_t initialsz, size_t *chunksizehintp, int *ncidp)
Create a netCDF file with some extra parameters controlling classic file caching. ...
Definition: dfile.c:470
#define NC_FORMATX_NC_HDF4
netCDF-4 subset of HDF4
Definition: netcdf.h:228
int nc_open(const char *path, int omode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:664
#define NC_FORMATX_UDF1
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:233
#define NC_FORMATX_NC_HDF5
netCDF-4 subset of HDF5
Definition: netcdf.h:226
#define NC_CDF5
Alias NC_CDF5 to NC_64BIT_DATA.
Definition: netcdf.h:144
#define NC_WRITE
Set read-write access for nc_open().
Definition: netcdf.h:136
int nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
Inquire about user-defined format.
Definition: dfile.c:179
int nc_create_mem(const char *path, int mode, size_t initialsize, int *ncidp)
Create a netCDF file with the contents stored in memory.
Definition: dfile.c:516
#define NC_FORMATX_NCZARR
Added in version 4.8.0.
Definition: netcdf.h:234
int nc_inq_path(int ncid, size_t *pathlen, char *path)
Get the file pathname (or the opendap URL) which was used to open/create the ncid's file...
Definition: dfile.c:898
#define NC_NOERR
No Error.
Definition: netcdf.h:378
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition: dfile.c:1654
#define NC_DISKLESS
Use diskless file.
Definition: netcdf.h:140
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:231
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:1027
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:229
#define NC_MMAP
Definition: netcdf.h:141
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
Definition: dfile.c:1195
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:398