NetCDF  4.8.1
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 extern int NC_initialized;
45 /* User-defined formats. */
46 NC_Dispatch *UDF0_dispatch_table = NULL;
47 char UDF0_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
48 NC_Dispatch *UDF1_dispatch_table = NULL;
49 char UDF1_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
50 
51 /**************************************************/
52 
53 
119 int
120 nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
121 {
122  /* Check inputs. */
123  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
124  return NC_EINVAL;
125  if (!dispatch_table)
126  return NC_EINVAL;
127  if (magic_number && strlen(magic_number) > NC_MAX_MAGIC_NUMBER_LEN)
128  return NC_EINVAL;
129 
130  /* Check the version of the dispatch table provided. */
131  if (dispatch_table->dispatch_version != NC_DISPATCH_VERSION)
132  return NC_EINVAL;
133 
134  /* Retain a pointer to the dispatch_table and a copy of the magic
135  * number, if one was provided. */
136  switch(mode_flag)
137  {
138  case NC_UDF0:
139  UDF0_dispatch_table = dispatch_table;
140  if (magic_number)
141  strncpy(UDF0_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
142  break;
143  case NC_UDF1:
144  UDF1_dispatch_table = dispatch_table;
145  if (magic_number)
146  strncpy(UDF1_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
147  break;
148  }
149 
150  return NC_NOERR;
151 }
152 
169 int
170 nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
171 {
172  /* Check inputs. */
173  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
174  return NC_EINVAL;
175 
176  switch(mode_flag)
177  {
178  case NC_UDF0:
179  if (dispatch_table)
180  *dispatch_table = UDF0_dispatch_table;
181  if (magic_number)
182  strncpy(magic_number, UDF0_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
183  break;
184  case NC_UDF1:
185  if (dispatch_table)
186  *dispatch_table = UDF1_dispatch_table;
187  if (magic_number)
188  strncpy(magic_number, UDF1_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
189  break;
190  }
191 
192  return NC_NOERR;
193 }
194 
388 int
389 nc_create(const char *path, int cmode, int *ncidp)
390 {
391  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
392 }
393 
460 int
461 nc__create(const char *path, int cmode, size_t initialsz,
462  size_t *chunksizehintp, int *ncidp)
463 {
464  return NC_create(path, cmode, initialsz, 0,
465  chunksizehintp, 0, NULL, ncidp);
466 }
467 
506 int
507 nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
508 {
509  if(mode & NC_MMAP) return NC_EINVAL;
510  mode |= NC_INMEMORY; /* Specifically, do not set NC_DISKLESS */
511  return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
512 }
513 
533 int
534 nc__create_mp(const char *path, int cmode, size_t initialsz,
535  int basepe, size_t *chunksizehintp, int *ncidp)
536 {
537  return NC_create(path, cmode, initialsz, basepe,
538  chunksizehintp, 0, NULL, ncidp);
539 }
540 
654 int
655 nc_open(const char *path, int omode, int *ncidp)
656 {
657  return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
658 }
659 
711 int
712 nc__open(const char *path, int omode,
713  size_t *chunksizehintp, int *ncidp)
714 {
715  /* this API is for non-parallel access.
716  * Note nc_open_par() also calls NC_open().
717  */
718  return NC_open(path, omode, 0, chunksizehintp, 0, NULL, ncidp);
719 }
720 
766 int
767 nc_open_mem(const char* path, int omode, size_t size, void* memory, int* ncidp)
768 {
769  NC_memio meminfo;
770 
771  /* Sanity checks */
772  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
773  return NC_EINVAL;
774  if(omode & (NC_WRITE|NC_MMAP))
775  return NC_EINVAL;
776  omode |= (NC_INMEMORY); /* Note: NC_INMEMORY and NC_DISKLESS are mutually exclusive*/
777  meminfo.size = size;
778  meminfo.memory = memory;
779  meminfo.flags = NC_MEMIO_LOCKED;
780  return NC_open(path, omode, 0, NULL, 0, &meminfo, ncidp);
781 }
782 
831 int
832 nc_open_memio(const char* path, int omode, NC_memio* params, int* ncidp)
833 {
834  /* Sanity checks */
835  if(path == NULL || params == NULL)
836  return NC_EINVAL;
837  if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
838  return NC_EINVAL;
839 
840  if(omode & NC_MMAP)
841  return NC_EINVAL;
842  omode |= (NC_INMEMORY);
843  return NC_open(path, omode, 0, NULL, 0, params, ncidp);
844 }
845 
864 int
865 nc__open_mp(const char *path, int omode, int basepe,
866  size_t *chunksizehintp, int *ncidp)
867 {
868  return NC_open(path, omode, basepe, chunksizehintp, 0, NULL, ncidp);
869 }
870 
888 int
889 nc_inq_path(int ncid, size_t *pathlen, char *path)
890 {
891  NC* ncp;
892  int stat = NC_NOERR;
893  if ((stat = NC_check_id(ncid, &ncp)))
894  return stat;
895  if(ncp->path == NULL) {
896  if(pathlen) *pathlen = 0;
897  if(path) path[0] = '\0';
898  } else {
899  if (pathlen) *pathlen = strlen(ncp->path);
900  if (path) strcpy(path, ncp->path);
901  }
902  return stat;
903 }
904 
953 int
954 nc_redef(int ncid)
955 {
956  NC* ncp;
957  int stat = NC_check_id(ncid, &ncp);
958  if(stat != NC_NOERR) return stat;
959  return ncp->dispatch->redef(ncid);
960 }
961 
1017 int
1018 nc_enddef(int ncid)
1019 {
1020  int status = NC_NOERR;
1021  NC *ncp;
1022  status = NC_check_id(ncid, &ncp);
1023  if(status != NC_NOERR) return status;
1024  return ncp->dispatch->_enddef(ncid,0,1,0,1);
1025 }
1026 
1108 int
1109 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1110  size_t r_align)
1111 {
1112  NC* ncp;
1113  int stat = NC_check_id(ncid, &ncp);
1114  if(stat != NC_NOERR) return stat;
1115  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1116 }
1117 
1185 int
1186 nc_sync(int ncid)
1187 {
1188  NC* ncp;
1189  int stat = NC_check_id(ncid, &ncp);
1190  if(stat != NC_NOERR) return stat;
1191  return ncp->dispatch->sync(ncid);
1192 }
1193 
1237 int
1238 nc_abort(int ncid)
1239 {
1240  NC* ncp;
1241  int stat = NC_check_id(ncid, &ncp);
1242  if(stat != NC_NOERR) return stat;
1243 
1244  stat = ncp->dispatch->abort(ncid);
1245  del_from_NCList(ncp);
1246  free_NC(ncp);
1247  return stat;
1248 }
1249 
1290 int
1291 nc_close(int ncid)
1292 {
1293  NC* ncp;
1294  int stat = NC_check_id(ncid, &ncp);
1295  if(stat != NC_NOERR) return stat;
1296 
1297  stat = ncp->dispatch->close(ncid,NULL);
1298  /* Remove from the nc list */
1299  if (!stat)
1300  {
1301  del_from_NCList(ncp);
1302  free_NC(ncp);
1303  }
1304  return stat;
1305 }
1306 
1349 int
1350 nc_close_memio(int ncid, NC_memio* memio)
1351 {
1352  NC* ncp;
1353  int stat = NC_check_id(ncid, &ncp);
1354  if(stat != NC_NOERR) return stat;
1355 
1356  stat = ncp->dispatch->close(ncid,memio);
1357  /* Remove from the nc list */
1358  if (!stat)
1359  {
1360  del_from_NCList(ncp);
1361  free_NC(ncp);
1362  }
1363  return stat;
1364 }
1365 
1464 int
1465 nc_set_fill(int ncid, int fillmode, int *old_modep)
1466 {
1467  NC* ncp;
1468  int stat = NC_check_id(ncid, &ncp);
1469  if(stat != NC_NOERR) return stat;
1470  return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1471 }
1472 
1487 int
1488 nc_inq_base_pe(int ncid, int *pe)
1489 {
1490  NC* ncp;
1491  int stat = NC_check_id(ncid, &ncp);
1492  if(stat != NC_NOERR) return stat;
1493  if (pe) *pe = 0;
1494  return NC_NOERR;
1495 }
1496 
1511 int
1512 nc_set_base_pe(int ncid, int pe)
1513 {
1514  NC* ncp;
1515  int stat = NC_check_id(ncid, &ncp);
1516  if(stat != NC_NOERR) return stat;
1517  return NC_NOERR;
1518 }
1519 
1537 int
1538 nc_inq_format(int ncid, int *formatp)
1539 {
1540  NC* ncp;
1541  int stat = NC_check_id(ncid, &ncp);
1542  if(stat != NC_NOERR) return stat;
1543  return ncp->dispatch->inq_format(ncid,formatp);
1544 }
1545 
1572 int
1573 nc_inq_format_extended(int ncid, int *formatp, int *modep)
1574 {
1575  NC* ncp;
1576  int stat = NC_check_id(ncid, &ncp);
1577  if(stat != NC_NOERR) return stat;
1578  return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1579 }
1580 
1625 int
1626 nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
1627 {
1628  NC* ncp;
1629  int stat = NC_check_id(ncid, &ncp);
1630  if(stat != NC_NOERR) return stat;
1631  return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1632 }
1633 
1644 int
1645 nc_inq_nvars(int ncid, int *nvarsp)
1646 {
1647  NC* ncp;
1648  int stat = NC_check_id(ncid, &ncp);
1649  if(stat != NC_NOERR) return stat;
1650  return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1651 }
1652 
1718 int
1719 nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
1720 {
1721  NC* ncp;
1722  int stat;
1723 
1724  /* Do a quick triage on xtype */
1725  if(xtype <= NC_NAT) return NC_EBADTYPE;
1726  /* For compatibility, we need to allow inq about
1727  atomic types, even if ncid is ill-defined */
1728  if(xtype <= ATOMICTYPEMAX4) {
1729  if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME);
1730  if(size) *size = NC_atomictypelen(xtype);
1731  return NC_NOERR;
1732  }
1733  /* Apparently asking about a user defined type, so we need
1734  a valid ncid */
1735  stat = NC_check_id(ncid, &ncp);
1736  if(stat != NC_NOERR) /* bad ncid */
1737  return NC_EBADTYPE;
1738  /* have good ncid */
1739  return ncp->dispatch->inq_type(ncid,xtype,name,size);
1740 }
1741 
1758 static int
1760 {
1761  int mode_format;
1762  int mmap = 0;
1763  int inmemory = 0;
1764  int diskless = 0;
1765 
1766  /* This is a clever check to see if more than one format bit is
1767  * set. */
1768  mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
1769  (mode & NC_CDF5);
1770  if (mode_format && (mode_format & (mode_format - 1)))
1771  return NC_EINVAL;
1772 
1773  mmap = ((mode & NC_MMAP) == NC_MMAP);
1774  inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
1775  diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
1776 
1777  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1778  if(diskless && inmemory) return NC_EDISKLESS;
1779  if(diskless && mmap) return NC_EDISKLESS;
1780  if(inmemory && mmap) return NC_EINMEMORY;
1781 
1782  /* mmap is not allowed for netcdf-4 */
1783  if(mmap && (mode & NC_NETCDF4)) return NC_EINVAL;
1784 
1785 #ifndef USE_NETCDF4
1786  /* If the user asks for a netCDF-4 file, and the library was built
1787  * without netCDF-4, then return an error.*/
1788  if (mode & NC_NETCDF4)
1789  return NC_ENOTBUILT;
1790 #endif /* USE_NETCDF4 undefined */
1791 
1792  /* Well I guess there is some sanity in the world after all. */
1793  return NC_NOERR;
1794 }
1795 
1823 int
1824 NC_create(const char *path0, int cmode, size_t initialsz,
1825  int basepe, size_t *chunksizehintp, int useparallel,
1826  void* parameters, int *ncidp)
1827 {
1828  int stat = NC_NOERR;
1829  NC* ncp = NULL;
1830  const NC_Dispatch* dispatcher = NULL;
1831  char* path = NULL;
1832  NCmodel model;
1833  char* newpath = NULL;
1834 
1835  TRACE(nc_create);
1836  if(path0 == NULL)
1837  return NC_EINVAL;
1838 
1839  /* Check mode flag for sanity. */
1840  if ((stat = check_create_mode(cmode)))
1841  return stat;
1842 
1843  /* Initialize the library. The available dispatch tables
1844  * will depend on how netCDF was built
1845  * (with/without netCDF-4, DAP, CDMREMOTE). */
1846  if(!NC_initialized)
1847  {
1848  if ((stat = nc_initialize()))
1849  return stat;
1850  }
1851 
1852  {
1853  /* Skip past any leading whitespace in path */
1854  const unsigned char* p;
1855  for(p=(const unsigned char*)path0;*p;p++) {if(*p > ' ') break;}
1856  path = nulldup((const char*)p);
1857  }
1858 
1859  memset(&model,0,sizeof(model));
1860  newpath = NULL;
1861  if((stat = NC_infermodel(path,&cmode,1,useparallel,NULL,&model,&newpath))) {
1862  nullfree(newpath);
1863  goto done;
1864  }
1865  if(newpath) {
1866  nullfree(path);
1867  path = newpath;
1868  newpath = NULL;
1869  }
1870 
1871  assert(model.format != 0 && model.impl != 0);
1872 
1873  /* Now, check for NC_ENOTBUILT cases limited to create (so e.g. HDF4 is not listed) */
1874 #ifndef USE_HDF5
1875  if (model.impl == NC_FORMATX_NC4)
1876  {stat = NC_ENOTBUILT; goto done;}
1877 #endif
1878 #ifndef USE_PNETCDF
1879  if (model.impl == NC_FORMATX_PNETCDF)
1880  {stat = NC_ENOTBUILT; goto done;}
1881 #endif
1882 #ifndef ENABLE_CDF5
1883  if (model.impl == NC_FORMATX_NC3 && (cmode & NC_64BIT_DATA))
1884  {stat = NC_ENOTBUILT; goto done;}
1885 #endif
1886 
1887  /* Figure out what dispatcher to use */
1888  switch (model.impl) {
1889 #ifdef USE_HDF5
1890  case NC_FORMATX_NC4:
1891  dispatcher = HDF5_dispatch_table;
1892  break;
1893 #endif
1894 #ifdef USE_PNETCDF
1895  case NC_FORMATX_PNETCDF:
1896  dispatcher = NCP_dispatch_table;
1897  break;
1898 #endif
1899 #ifdef USE_NETCDF4
1900  case NC_FORMATX_UDF0:
1901  dispatcher = UDF0_dispatch_table;
1902  break;
1903  case NC_FORMATX_UDF1:
1904  dispatcher = UDF1_dispatch_table;
1905  break;
1906 #endif /* USE_NETCDF4 */
1907 #ifdef ENABLE_NCZARR
1908  case NC_FORMATX_NCZARR:
1909  dispatcher = NCZ_dispatch_table;
1910  break;
1911 #endif
1912  case NC_FORMATX_NC3:
1913  dispatcher = NC3_dispatch_table;
1914  break;
1915  default:
1916  return NC_ENOTNC;
1917  }
1918 
1919  /* Create the NC* instance and insert its dispatcher and model */
1920  if((stat = new_NC(dispatcher,path,cmode,&ncp))) goto done;
1921 
1922  /* Add to list of known open files and define ext_ncid */
1923  add_to_NCList(ncp);
1924 
1925  /* Assume create will fill in remaining ncp fields */
1926  if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp,
1927  parameters, dispatcher, ncp->ext_ncid))) {
1928  del_from_NCList(ncp); /* oh well */
1929  free_NC(ncp);
1930  } else {
1931  if(ncidp)*ncidp = ncp->ext_ncid;
1932  }
1933 done:
1934  nullfree(path);
1935  return stat;
1936 }
1937 
1961 int
1962 NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
1963  int useparallel, void* parameters, int *ncidp)
1964 {
1965  int stat = NC_NOERR;
1966  NC* ncp = NULL;
1967  const NC_Dispatch* dispatcher = NULL;
1968  int inmemory = 0;
1969  int diskless = 0;
1970  int mmap = 0;
1971  char* path = NULL;
1972  NCmodel model;
1973  char* newpath = NULL;
1974 
1975  TRACE(nc_open);
1976  if(!NC_initialized) {
1977  stat = nc_initialize();
1978  if(stat) return stat;
1979  }
1980 
1981  /* Check inputs. */
1982  if (!path0)
1983  return NC_EINVAL;
1984 
1985  /* Capture the inmemory related flags */
1986  mmap = ((omode & NC_MMAP) == NC_MMAP);
1987  diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
1988  inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
1989 
1990  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1991  if(diskless && inmemory) {stat = NC_EDISKLESS; goto done;}
1992  if(diskless && mmap) {stat = NC_EDISKLESS; goto done;}
1993  if(inmemory && mmap) {stat = NC_EINMEMORY; goto done;}
1994 
1995  /* mmap is not allowed for netcdf-4 */
1996  if(mmap && (omode & NC_NETCDF4)) {stat = NC_EINVAL; goto done;}
1997 
1998  /* Attempt to do file path conversion: note that this will do
1999  nothing if path is a 'file:...' url, so it will need to be
2000  repeated in protocol code (e.g. libdap2, libdap4, etc).
2001  */
2002 
2003  {
2004  /* Skip past any leading whitespace in path */
2005  const char* p;
2006  for(p=(const char*)path0;*p;p++) {if(*p < 0 || *p > ' ') break;}
2007  path = nulldup(p);
2008  }
2009 
2010  memset(&model,0,sizeof(model));
2011  /* Infer model implementation and format, possibly by reading the file */
2012  if((stat = NC_infermodel(path,&omode,0,useparallel,parameters,&model,&newpath)))
2013  goto done;
2014  if(newpath) {
2015  nullfree(path);
2016  path = newpath;
2017  newpath = NULL;
2018  }
2019 
2020  /* Still no implementation, give up */
2021  if(model.impl == 0) {
2022 #ifdef DEBUG
2023  fprintf(stderr,"implementation == 0\n");
2024 #endif
2025  {stat = NC_ENOTNC; goto done;}
2026  }
2027 
2028  /* Suppress unsupported formats */
2029  /* (should be more compact, table-driven, way to do this) */
2030  {
2031  int hdf5built = 0;
2032  int hdf4built = 0;
2033  int cdf5built = 0;
2034  int udf0built = 0;
2035  int udf1built = 0;
2036  int nczarrbuilt = 0;
2037 #ifdef USE_NETCDF4
2038  hdf5built = 1;
2039 #ifdef USE_HDF4
2040  hdf4built = 1;
2041 #endif
2042 #endif
2043 #ifdef ENABLE_CDF5
2044  cdf5built = 1;
2045 #endif
2046 #ifdef ENABLE_NCZARR
2047  nczarrbuilt = 1;
2048 #endif
2049  if(UDF0_dispatch_table != NULL)
2050  udf0built = 1;
2051  if(UDF1_dispatch_table != NULL)
2052  udf1built = 1;
2053 
2054  if(!hdf5built && model.impl == NC_FORMATX_NC4)
2055  {stat = NC_ENOTBUILT; goto done;}
2056  if(!hdf4built && model.impl == NC_FORMATX_NC_HDF4)
2057  {stat = NC_ENOTBUILT; goto done;}
2058  if(!cdf5built && model.impl == NC_FORMATX_NC3 && model.format == NC_FORMAT_CDF5)
2059  {stat = NC_ENOTBUILT; goto done;}
2060  if(!nczarrbuilt && model.impl == NC_FORMATX_NCZARR)
2061  {stat = NC_ENOTBUILT; goto done;}
2062  if(!udf0built && model.impl == NC_FORMATX_UDF0)
2063  {stat = NC_ENOTBUILT; goto done;}
2064  if(!udf1built && model.impl == NC_FORMATX_UDF1)
2065  {stat = NC_ENOTBUILT; goto done;}
2066  }
2067  /* Figure out what dispatcher to use */
2068  if (!dispatcher) {
2069  switch (model.impl) {
2070 #ifdef ENABLE_DAP
2071  case NC_FORMATX_DAP2:
2072  dispatcher = NCD2_dispatch_table;
2073  break;
2074 #endif
2075 #ifdef ENABLE_DAP4
2076  case NC_FORMATX_DAP4:
2077  dispatcher = NCD4_dispatch_table;
2078  break;
2079 #endif
2080 #ifdef ENABLE_NCZARR
2081  case NC_FORMATX_NCZARR:
2082  dispatcher = NCZ_dispatch_table;
2083  break;
2084 #endif
2085 #ifdef USE_PNETCDF
2086  case NC_FORMATX_PNETCDF:
2087  dispatcher = NCP_dispatch_table;
2088  break;
2089 #endif
2090 #ifdef USE_HDF5
2091  case NC_FORMATX_NC4:
2092  dispatcher = HDF5_dispatch_table;
2093  break;
2094 #endif
2095 #ifdef USE_HDF4
2096  case NC_FORMATX_NC_HDF4:
2097  dispatcher = HDF4_dispatch_table;
2098  break;
2099 #endif
2100 #ifdef USE_NETCDF4
2101  case NC_FORMATX_UDF0:
2102  dispatcher = UDF0_dispatch_table;
2103  break;
2104  case NC_FORMATX_UDF1:
2105  dispatcher = UDF1_dispatch_table;
2106  break;
2107 #endif /* USE_NETCDF4 */
2108  case NC_FORMATX_NC3:
2109  dispatcher = NC3_dispatch_table;
2110  break;
2111  default:
2112  stat = NC_ENOTNC;
2113  goto done;
2114  }
2115  }
2116 
2117 
2118  /* If we can't figure out what dispatch table to use, give up. */
2119  if (!dispatcher) {stat = NC_ENOTNC; goto done;}
2120 
2121  /* Create the NC* instance and insert its dispatcher */
2122  if((stat = new_NC(dispatcher,path,omode,&ncp))) goto done;
2123 
2124  /* Add to list of known open files. This assigns an ext_ncid. */
2125  add_to_NCList(ncp);
2126 
2127  /* Assume open will fill in remaining ncp fields */
2128  stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2129  parameters, dispatcher, ncp->ext_ncid);
2130  if(stat == NC_NOERR) {
2131  if(ncidp) *ncidp = ncp->ext_ncid;
2132  } else {
2133  del_from_NCList(ncp);
2134  free_NC(ncp);
2135  }
2136 
2137 done:
2138  nullfree(path);
2139  nullfree(newpath);
2140  return stat;
2141 }
2142 
2143 /*Provide an internal function for generating pseudo file descriptors
2144  for systems that are not file based (e.g. dap, memio).
2145 */
2146 
2148 static int pseudofd = 0;
2149 
2157 int
2158 nc__pseudofd(void)
2159 {
2160  if(pseudofd == 0) {
2161  int maxfd = 32767; /* default */
2162 #ifdef HAVE_GETRLIMIT
2163  struct rlimit rl;
2164  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2165  if(rl.rlim_max != RLIM_INFINITY)
2166  maxfd = (int)rl.rlim_max;
2167  if(rl.rlim_cur != RLIM_INFINITY)
2168  maxfd = (int)rl.rlim_cur;
2169  }
2170  pseudofd = maxfd+1;
2171 #endif
2172  }
2173  return pseudofd++;
2174 }
NC_NOERR
#define NC_NOERR
No Error.
Definition: netcdf.h:333
NC_EINVAL
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:343
NC_FORMATX_NC3
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:211
nc_def_user_format
int nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
Add handling of user-defined format.
Definition: dfile.c:120
NC_DISKLESS
#define NC_DISKLESS
Use diskless file.
Definition: netcdf.h:130
NC_FORMAT_CDF5
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:186
nc_close_memio
int nc_close_memio(int ncid, NC_memio *memio)
Definition: dfile.c:1350
NC_FORMATX_UDF0
#define NC_FORMATX_UDF0
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:218
netcdf_mem.h
nc_redef
int nc_redef(int ncid)
Definition: dfile.c:954
NC_FORMATX_UDF1
#define NC_FORMATX_UDF1
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:219
NC_FORMATX_DAP2
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:216
nc__enddef
int nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align)
Definition: dfile.c:1109
NC_FORMATX_PNETCDF
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:215
nc_inq_format
int nc_inq_format(int ncid, int *formatp)
Definition: dfile.c:1538
NC_FORMATX_NC_HDF4
#define NC_FORMATX_NC_HDF4
netCDF-4 subset of HDF4
Definition: netcdf.h:214
NC_SIZEHINT_DEFAULT
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:240
nc_inq_format_extended
int nc_inq_format_extended(int ncid, int *formatp, int *modep)
Definition: dfile.c:1573
NC_WRITE
#define NC_WRITE
Set read-write access for nc_open().
Definition: netcdf.h:126
NC_MAX_NAME
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:276
nc_open_memio
int nc_open_memio(const char *path, int omode, NC_memio *params, int *ncidp)
Definition: dfile.c:832
NC_FORMATX_NC4
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:213
NC_MMAP
#define NC_MMAP
Definition: netcdf.h:131
nc_inq
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Definition: dfile.c:1626
nc__open
int nc__open(const char *path, int omode, size_t *chunksizehintp, int *ncidp)
Definition: dfile.c:712
NC_EINMEMORY
#define NC_EINMEMORY
In-memory file error.
Definition: netcdf.h:481
NC_memio
Definition: netcdf_mem.h:22
nc_close
int nc_close(int ncid)
Definition: dfile.c:1291
NC_64BIT_OFFSET
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
Definition: netcdf.h:140
nc_abort
int nc_abort(int ncid)
Definition: dfile.c:1238
NC_UDF0
#define NC_UDF0
User-defined format 0.
Definition: netcdf.h:136
nc_inq_type
int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Definition: dfile.c:1719
nc_open_mem
int nc_open_mem(const char *path, int omode, size_t size, void *memory, int *ncidp)
Definition: dfile.c:767
NC_UDF1
#define NC_UDF1
User-defined format 1.
Definition: netcdf.h:137
nc_set_fill
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Definition: dfile.c:1465
NC_EDISKLESS
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:474
nc_open
int nc_open(const char *path, int omode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:655
NC_ENOTBUILT
#define NC_ENOTBUILT
Attempt to use feature that was not turned on when netCDF was built.
Definition: netcdf.h:473
nc_type
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:25
NC_FORMATX_NCZARR
#define NC_FORMATX_NCZARR
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:220
NC_EBADTYPE
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:375
NC_FORMATX_DAP4
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition: netcdf.h:217
nc__create
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:461
nc_inq_user_format
int nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
Inquire about user-defined format.
Definition: dfile.c:170
NC_ENOTNC
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:389
nc_create_mem
int nc_create_mem(const char *path, int mode, size_t initialsize, int *ncidp)
Definition: dfile.c:507
NC_NAT
#define NC_NAT
Not A Type.
Definition: netcdf.h:34
nc_inq_nvars
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition: dfile.c:1645
NC_MAX_MAGIC_NUMBER_LEN
#define NC_MAX_MAGIC_NUMBER_LEN
Max len of user-defined format magic number.
Definition: netcdf.h:164
check_create_mode
static int check_create_mode(int mode)
Check the create mode parameter for sanity.
Definition: dfile.c:1759
nc_inq_path
int nc_inq_path(int ncid, size_t *pathlen, char *path)
Definition: dfile.c:889
NC_initialized
int NC_initialized
True when dispatch table is initialized.
NC_INMEMORY
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:162
NC_NETCDF4
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition: netcdf.h:152
nc_enddef
int nc_enddef(int ncid)
Definition: dfile.c:1018
nc_create
int nc_create(const char *path, int cmode, int *ncidp)
Definition: dfile.c:389
nc_sync
int nc_sync(int ncid)
Definition: dfile.c:1186
NC_CDF5
#define NC_CDF5
Alias NC_CDF5 to NC_64BIT_DATA.
Definition: netcdf.h:134
NC_64BIT_DATA
#define NC_64BIT_DATA
CDF-5 format: classic model but 64 bit dimensions and sizes.
Definition: netcdf.h:133