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