NetCDF  4.9.1-rc1
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 (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
129  return NC_EINVAL;
130  if (!dispatch_table)
131  return NC_EINVAL;
132  if (magic_number && strlen(magic_number) > NC_MAX_MAGIC_NUMBER_LEN)
133  return NC_EINVAL;
134 
135  /* Check the version of the dispatch table provided. */
136  if (dispatch_table->dispatch_version != NC_DISPATCH_VERSION)
137  return NC_EINVAL;
138 
139  /* Retain a pointer to the dispatch_table and a copy of the magic
140  * number, if one was provided. */
141  switch(mode_flag)
142  {
143  case NC_UDF0:
144  UDF0_dispatch_table = dispatch_table;
145  if (magic_number)
146  strncpy(UDF0_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
147  break;
148  case NC_UDF1:
149  UDF1_dispatch_table = dispatch_table;
150  if (magic_number)
151  strncpy(UDF1_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
152  break;
153  }
154 
155  return NC_NOERR;
156 }
157 
174 int
175 nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
176 {
177  /* Check inputs. */
178  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
179  return NC_EINVAL;
180 
181  switch(mode_flag)
182  {
183  case NC_UDF0:
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  break;
189  case NC_UDF1:
190  if (dispatch_table)
191  *dispatch_table = UDF1_dispatch_table;
192  if (magic_number)
193  strncpy(magic_number, UDF1_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
194  break;
195  }
196 
197  return NC_NOERR;
198 }
199 
393 int
394 nc_create(const char *path, int cmode, int *ncidp)
395 {
396  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
397 }
398 
465 int
466 nc__create(const char *path, int cmode, size_t initialsz,
467  size_t *chunksizehintp, int *ncidp)
468 {
469  return NC_create(path, cmode, initialsz, 0,
470  chunksizehintp, 0, NULL, ncidp);
471 }
472 
511 int
512 nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
513 {
514  if(mode & NC_MMAP) return NC_EINVAL;
515  mode |= NC_INMEMORY; /* Specifically, do not set NC_DISKLESS */
516  return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
517 }
518 
538 int
539 nc__create_mp(const char *path, int cmode, size_t initialsz,
540  int basepe, size_t *chunksizehintp, int *ncidp)
541 {
542  return NC_create(path, cmode, initialsz, basepe,
543  chunksizehintp, 0, NULL, ncidp);
544 }
545 
659 int
660 nc_open(const char *path, int omode, int *ncidp)
661 {
662  return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
663 }
664 
716 int
717 nc__open(const char *path, int omode,
718  size_t *chunksizehintp, int *ncidp)
719 {
720  /* this API is for non-parallel access.
721  * Note nc_open_par() also calls NC_open().
722  */
723  return NC_open(path, omode, 0, chunksizehintp, 0, NULL, ncidp);
724 }
725 
771 int
772 nc_open_mem(const char* path, int omode, size_t size, void* memory, int* ncidp)
773 {
774  NC_memio meminfo;
775 
776  /* Sanity checks */
777  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
778  return NC_EINVAL;
779  if(omode & (NC_WRITE|NC_MMAP))
780  return NC_EINVAL;
781  omode |= (NC_INMEMORY); /* Note: NC_INMEMORY and NC_DISKLESS are mutually exclusive*/
782  meminfo.size = size;
783  meminfo.memory = memory;
784  meminfo.flags = NC_MEMIO_LOCKED;
785  return NC_open(path, omode, 0, NULL, 0, &meminfo, ncidp);
786 }
787 
836 int
837 nc_open_memio(const char* path, int omode, NC_memio* params, int* ncidp)
838 {
839  /* Sanity checks */
840  if(path == NULL || params == NULL)
841  return NC_EINVAL;
842  if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
843  return NC_EINVAL;
844 
845  if(omode & NC_MMAP)
846  return NC_EINVAL;
847  omode |= (NC_INMEMORY);
848  return NC_open(path, omode, 0, NULL, 0, params, ncidp);
849 }
850 
869 int
870 nc__open_mp(const char *path, int omode, int basepe,
871  size_t *chunksizehintp, int *ncidp)
872 {
873  return NC_open(path, omode, basepe, chunksizehintp, 0, NULL, ncidp);
874 }
875 
893 int
894 nc_inq_path(int ncid, size_t *pathlen, char *path)
895 {
896  NC* ncp;
897  int stat = NC_NOERR;
898  if ((stat = NC_check_id(ncid, &ncp)))
899  return stat;
900  if(ncp->path == NULL) {
901  if(pathlen) *pathlen = 0;
902  if(path) path[0] = '\0';
903  } else {
904  if (pathlen) *pathlen = strlen(ncp->path);
905  if (path) strcpy(path, ncp->path);
906  }
907  return stat;
908 }
909 
958 int
959 nc_redef(int ncid)
960 {
961  NC* ncp;
962  int stat = NC_check_id(ncid, &ncp);
963  if(stat != NC_NOERR) return stat;
964  return ncp->dispatch->redef(ncid);
965 }
966 
1022 int
1023 nc_enddef(int ncid)
1024 {
1025  int status = NC_NOERR;
1026  NC *ncp;
1027  status = NC_check_id(ncid, &ncp);
1028  if(status != NC_NOERR) return status;
1029  return ncp->dispatch->_enddef(ncid,0,1,0,1);
1030 }
1031 
1113 int
1114 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1115  size_t r_align)
1116 {
1117  NC* ncp;
1118  int stat = NC_check_id(ncid, &ncp);
1119  if(stat != NC_NOERR) return stat;
1120  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1121 }
1122 
1190 int
1191 nc_sync(int ncid)
1192 {
1193  NC* ncp;
1194  int stat = NC_check_id(ncid, &ncp);
1195  if(stat != NC_NOERR) return stat;
1196  return ncp->dispatch->sync(ncid);
1197 }
1198 
1242 int
1243 nc_abort(int ncid)
1244 {
1245  NC* ncp;
1246  int stat = NC_check_id(ncid, &ncp);
1247  if(stat != NC_NOERR) return stat;
1248 
1249  stat = ncp->dispatch->abort(ncid);
1250  del_from_NCList(ncp);
1251  free_NC(ncp);
1252  return stat;
1253 }
1254 
1295 int
1296 nc_close(int ncid)
1297 {
1298  NC* ncp;
1299  int stat = NC_check_id(ncid, &ncp);
1300  if(stat != NC_NOERR) return stat;
1301 
1302  stat = ncp->dispatch->close(ncid,NULL);
1303  /* Remove from the nc list */
1304  if (!stat)
1305  {
1306  del_from_NCList(ncp);
1307  free_NC(ncp);
1308  }
1309  return stat;
1310 }
1311 
1354 int
1355 nc_close_memio(int ncid, NC_memio* memio)
1356 {
1357  NC* ncp;
1358  int stat = NC_check_id(ncid, &ncp);
1359  if(stat != NC_NOERR) return stat;
1360 
1361  stat = ncp->dispatch->close(ncid,memio);
1362  /* Remove from the nc list */
1363  if (!stat)
1364  {
1365  del_from_NCList(ncp);
1366  free_NC(ncp);
1367  }
1368  return stat;
1369 }
1370 
1469 int
1470 nc_set_fill(int ncid, int fillmode, int *old_modep)
1471 {
1472  NC* ncp;
1473  int stat = NC_check_id(ncid, &ncp);
1474  if(stat != NC_NOERR) return stat;
1475  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1476 }
1477 
1492 int
1493 nc_inq_base_pe(int ncid, int *pe)
1494 {
1495  NC* ncp;
1496  int stat = NC_check_id(ncid, &ncp);
1497  if(stat != NC_NOERR) return stat;
1498  if (pe) *pe = 0;
1499  return NC_NOERR;
1500 }
1501 
1516 int
1517 nc_set_base_pe(int ncid, int pe)
1518 {
1519  NC* ncp;
1520  int stat = NC_check_id(ncid, &ncp);
1521  if(stat != NC_NOERR) return stat;
1522  return NC_NOERR;
1523 }
1524 
1542 int
1543 nc_inq_format(int ncid, int *formatp)
1544 {
1545  NC* ncp;
1546  int stat = NC_check_id(ncid, &ncp);
1547  if(stat != NC_NOERR) return stat;
1548  return ncp->dispatch->inq_format(ncid,formatp);
1549 }
1550 
1577 int
1578 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1579 {
1580  NC* ncp;
1581  int stat = NC_check_id(ncid, &ncp);
1582  if(stat != NC_NOERR) return stat;
1583  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1584 }
1585 
1630 int
1631 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1632 {
1633  NC* ncp;
1634  int stat = NC_check_id(ncid, &ncp);
1635  if(stat != NC_NOERR) return stat;
1636  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1637 }
1638 
1649 int
1650 nc_inq_nvars(int ncid, int *nvarsp)
1651 {
1652  NC* ncp;
1653  int stat = NC_check_id(ncid, &ncp);
1654  if(stat != NC_NOERR) return stat;
1655  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1656 }
1657 
1723 int
1724 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1725 {
1726  NC* ncp;
1727  int stat;
1728 
1729  /* Do a quick triage on xtype */
1730  if(xtype <= NC_NAT) return NC_EBADTYPE;
1731  /* For compatibility, we need to allow inq about
1732  atomic types, even if ncid is ill-defined */
1733  if(xtype <= ATOMICTYPEMAX4) {
1734  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1735  if(size) *size = NC_atomictypelen(xtype);
1736  return NC_NOERR;
1737  }
1738  /* Apparently asking about a user defined type, so we need
1739  a valid ncid */
1740  stat = NC_check_id(ncid, &ncp);
1741  if(stat != NC_NOERR) /* bad ncid */
1742  return NC_EBADTYPE;
1743  /* have good ncid */
1744  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1745 }
1746 
1763 static int
1765 {
1766  int mode_format;
1767  int mmap = 0;
1768  int inmemory = 0;
1769  int diskless = 0;
1770 
1771  /* This is a clever check to see if more than one format bit is
1772  * set. */
1773  mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
1774  (mode & NC_CDF5);
1775  if (mode_format && (mode_format & (mode_format - 1)))
1776  return NC_EINVAL;
1777 
1778  mmap = ((mode & NC_MMAP) == NC_MMAP);
1779  inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
1780  diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
1781 
1782  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1783  if(diskless && inmemory) return NC_EDISKLESS;
1784  if(diskless && mmap) return NC_EDISKLESS;
1785  if(inmemory && mmap) return NC_EINMEMORY;
1786 
1787  /* mmap is not allowed for netcdf-4 */
1788  if(mmap && (mode & NC_NETCDF4)) return NC_EINVAL;
1789 
1790 #ifndef USE_NETCDF4
1791  /* If the user asks for a netCDF-4 file, and the library was built
1792  * without netCDF-4, then return an error.*/
1793  if (mode & NC_NETCDF4)
1794  return NC_ENOTBUILT;
1795 #endif /* USE_NETCDF4 undefined */
1796 
1797  /* Well I guess there is some sanity in the world after all. */
1798  return NC_NOERR;
1799 }
1800 
1828 int
1829 NC_create(const char *path0, int cmode, size_t initialsz,
1830  int basepe, size_t *chunksizehintp, int useparallel,
1831  void* parameters, int *ncidp)
1832 {
1833  int stat = NC_NOERR;
1834  NC* ncp = NULL;
1835  const NC_Dispatch* dispatcher = NULL;
1836  char* path = NULL;
1837  NCmodel model;
1838  char* newpath = NULL;
1839 
1840  TRACE(nc_create);
1841  if(path0 == NULL)
1842  return NC_EINVAL;
1843 
1844  /* Check mode flag for sanity. */
1845  if ((stat = check_create_mode(cmode)))
1846  return stat;
1847 
1848  /* Initialize the library. The available dispatch tables
1849  * will depend on how netCDF was built
1850  * (with/without netCDF-4, DAP, CDMREMOTE). */
1851  if(!NC_initialized)
1852  {
1853  if ((stat = nc_initialize()))
1854  return stat;
1855  }
1856 
1857  {
1858  /* Skip past any leading whitespace in path */
1859  const unsigned char* p;
1860  for(p=(const unsigned char*)path0;*p;p++) {if(*p > ' ') break;}
1861  path = nulldup((const char*)p);
1862  }
1863 
1864  memset(&model,0,sizeof(model));
1865  newpath = NULL;
1866  if((stat = NC_infermodel(path,&cmode,1,useparallel,NULL,&model,&newpath))) {
1867  nullfree(newpath);
1868  goto done;
1869  }
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  return NC_ENOTNC;
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  return stat;
1941 }
1942 
1966 int
1967 NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
1968  int useparallel, void* parameters, int *ncidp)
1969 {
1970  int stat = NC_NOERR;
1971  NC* ncp = NULL;
1972  const NC_Dispatch* dispatcher = NULL;
1973  int inmemory = 0;
1974  int diskless = 0;
1975  int mmap = 0;
1976  char* path = NULL;
1977  NCmodel model;
1978  char* newpath = NULL;
1979 
1980  TRACE(nc_open);
1981  if(!NC_initialized) {
1982  stat = nc_initialize();
1983  if(stat) return stat;
1984  }
1985 
1986  /* Check inputs. */
1987  if (!path0)
1988  return NC_EINVAL;
1989 
1990  /* Capture the inmemory related flags */
1991  mmap = ((omode & NC_MMAP) == NC_MMAP);
1992  diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
1993  inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
1994 
1995  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1996  if(diskless && inmemory) {stat = NC_EDISKLESS; goto done;}
1997  if(diskless && mmap) {stat = NC_EDISKLESS; goto done;}
1998  if(inmemory && mmap) {stat = NC_EINMEMORY; goto done;}
1999 
2000  /* mmap is not allowed for netcdf-4 */
2001  if(mmap && (omode & NC_NETCDF4)) {stat = NC_EINVAL; goto done;}
2002 
2003  /* Attempt to do file path conversion: note that this will do
2004  nothing if path is a 'file:...' url, so it will need to be
2005  repeated in protocol code (e.g. libdap2, libdap4, etc).
2006  */
2007 
2008  {
2009  /* Skip past any leading whitespace in path */
2010  const char* p;
2011  for(p=(const char*)path0;*p;p++) {if(*p < 0 || *p > ' ') break;}
2012  path = nulldup(p);
2013  }
2014 
2015  memset(&model,0,sizeof(model));
2016  /* Infer model implementation and format, possibly by reading the file */
2017  if((stat = NC_infermodel(path,&omode,0,useparallel,parameters,&model,&newpath)))
2018  goto done;
2019  if(newpath) {
2020  nullfree(path);
2021  path = newpath;
2022  newpath = NULL;
2023  }
2024 
2025  /* Still no implementation, give up */
2026  if(model.impl == 0) {
2027 #ifdef DEBUG
2028  fprintf(stderr,"implementation == 0\n");
2029 #endif
2030  {stat = NC_ENOTNC; goto done;}
2031  }
2032 
2033  /* Suppress unsupported formats */
2034 #if 0
2035  /* (should be more compact, table-driven, way to do this) */
2036  {
2037  int hdf5built = 0;
2038  int hdf4built = 0;
2039  int cdf5built = 0;
2040  int udf0built = 0;
2041  int udf1built = 0;
2042  int nczarrbuilt = 0;
2043 #ifdef USE_NETCDF4
2044  hdf5built = 1;
2045 #endif
2046 #ifdef USE_HDF4
2047  hdf4built = 1;
2048 #endif
2049 #ifdef ENABLE_CDF5
2050  cdf5built = 1;
2051 #endif
2052 #ifdef ENABLE_NCZARR
2053  nczarrbuilt = 1;
2054 #endif
2055  if(UDF0_dispatch_table != NULL)
2056  udf0built = 1;
2057  if(UDF1_dispatch_table != NULL)
2058  udf1built = 1;
2059 
2060  if(!hdf5built && model.impl == NC_FORMATX_NC4)
2061  {stat = NC_ENOTBUILT; goto done;}
2062  if(!hdf4built && model.impl == NC_FORMATX_NC_HDF4)
2063  {stat = NC_ENOTBUILT; goto done;}
2064  if(!cdf5built && model.impl == NC_FORMATX_NC3 && model.format == NC_FORMAT_CDF5)
2065  {stat = NC_ENOTBUILT; goto done;}
2066  if(!nczarrbuilt && model.impl == NC_FORMATX_NCZARR)
2067  {stat = NC_ENOTBUILT; goto done;}
2068  if(!udf0built && model.impl == NC_FORMATX_UDF0)
2069  {stat = NC_ENOTBUILT; goto done;}
2070  if(!udf1built && model.impl == NC_FORMATX_UDF1)
2071  {stat = NC_ENOTBUILT; goto done;}
2072  }
2073 #else
2074  {
2075  unsigned built = 0 /* leave off the trailing semicolon so we can build constant */
2076  | (1<<NC_FORMATX_NC3) /* NC3 always supported */
2077 #ifdef USE_HDF5
2078  | (1<<NC_FORMATX_NC_HDF5)
2079 #endif
2080 #ifdef USE_HDF4
2081  | (1<<NC_FORMATX_NC_HDF4)
2082 #endif
2083 #ifdef ENABLE_NCZARR
2084  | (1<<NC_FORMATX_NCZARR)
2085 #endif
2086 #ifdef ENABLE_DAP
2087  | (1<<NC_FORMATX_DAP2)
2088 #endif
2089 #ifdef ENABLE_DAP4
2090  | (1<<NC_FORMATX_DAP4)
2091 #endif
2092 #ifdef USE_PNETCDF
2093  | (1<<NC_FORMATX_PNETCDF)
2094 #endif
2095  ; /* end of the built flags */
2096  if(UDF0_dispatch_table != NULL)
2097  built |= (1<<NC_FORMATX_UDF0);
2098  if(UDF1_dispatch_table != NULL)
2099  built |= (1<<NC_FORMATX_UDF1);
2100  /* Verify */
2101  if((built & (1 << model.impl)) == 0)
2102  {stat = NC_ENOTBUILT; goto done;}
2103 #ifndef ENABLE_CDF5
2104  /* Special case because there is no separate CDF5 dispatcher */
2105  if(model.impl == NC_FORMATX_NC3 && (omode & NC_64BIT_DATA))
2106  {stat = NC_ENOTBUILT; goto done;}
2107 #endif
2108  }
2109 #endif
2110  /* Figure out what dispatcher to use */
2111  if (!dispatcher) {
2112  switch (model.impl) {
2113 #ifdef ENABLE_DAP
2114  case NC_FORMATX_DAP2:
2115  dispatcher = NCD2_dispatch_table;
2116  break;
2117 #endif
2118 #ifdef ENABLE_DAP4
2119  case NC_FORMATX_DAP4:
2120  dispatcher = NCD4_dispatch_table;
2121  break;
2122 #endif
2123 #ifdef ENABLE_NCZARR
2124  case NC_FORMATX_NCZARR:
2125  dispatcher = NCZ_dispatch_table;
2126  break;
2127 #endif
2128 #ifdef USE_PNETCDF
2129  case NC_FORMATX_PNETCDF:
2130  dispatcher = NCP_dispatch_table;
2131  break;
2132 #endif
2133 #ifdef USE_HDF5
2134  case NC_FORMATX_NC4:
2135  dispatcher = HDF5_dispatch_table;
2136  break;
2137 #endif
2138 #ifdef USE_HDF4
2139  case NC_FORMATX_NC_HDF4:
2140  dispatcher = HDF4_dispatch_table;
2141  break;
2142 #endif
2143 #ifdef USE_NETCDF4
2144  case NC_FORMATX_UDF0:
2145  dispatcher = UDF0_dispatch_table;
2146  break;
2147  case NC_FORMATX_UDF1:
2148  dispatcher = UDF1_dispatch_table;
2149  break;
2150 #endif /* USE_NETCDF4 */
2151  case NC_FORMATX_NC3:
2152  dispatcher = NC3_dispatch_table;
2153  break;
2154  default:
2155  stat = NC_ENOTNC;
2156  goto done;
2157  }
2158  }
2159 
2160 
2161  /* If we can't figure out what dispatch table to use, give up. */
2162  if (!dispatcher) {stat = NC_ENOTNC; goto done;}
2163 
2164  /* Create the NC* instance and insert its dispatcher */
2165  if((stat = new_NC(dispatcher,path,omode,&ncp))) goto done;
2166 
2167  /* Add to list of known open files. This assigns an ext_ncid. */
2168  add_to_NCList(ncp);
2169 
2170  /* Assume open will fill in remaining ncp fields */
2171  stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2172  parameters, dispatcher, ncp->ext_ncid);
2173  if(stat == NC_NOERR) {
2174  if(ncidp) *ncidp = ncp->ext_ncid;
2175  } else {
2176  del_from_NCList(ncp);
2177  free_NC(ncp);
2178  }
2179 
2180 done:
2181  nullfree(path);
2182  nullfree(newpath);
2183  return stat;
2184 }
2185 
2186 /*Provide an internal function for generating pseudo file descriptors
2187  for systems that are not file based (e.g. dap, memio).
2188 */
2189 
2191 static int pseudofd = 0;
2192 
2200 int
2201 nc__pseudofd(void)
2202 {
2203  if(pseudofd == 0) {
2204 #ifdef HAVE_GETRLIMIT
2205  int maxfd = 32767; /* default */
2206  struct rlimit rl;
2207  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2208  if(rl.rlim_max != RLIM_INFINITY)
2209  maxfd = (int)rl.rlim_max;
2210  if(rl.rlim_cur != RLIM_INFINITY)
2211  maxfd = (int)rl.rlim_cur;
2212  }
2213  pseudofd = maxfd+1;
2214 #endif
2215  }
2216  return pseudofd++;
2217 }
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition: dfile.c:1650
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:1764
int nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
Inquire about user-defined format.
Definition: dfile.c:175
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:466
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1296
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1243
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:394
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1631
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:1578
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:1355
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:1114
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1470
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:512
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:717
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:894
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:772
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:1724
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:1023
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:959
int nc_open(const char *path, int omode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:660
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:837
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:1543
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
Definition: dfile.c:1191
#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_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.