NetCDF  4.7.0
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 "ncwinpath.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 
90 #ifdef USE_NETCDF4
91 
104 int
105 nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
106 {
107  /* Check inputs. */
108  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
109  return NC_EINVAL;
110  if (!dispatch_table)
111  return NC_EINVAL;
112  if (magic_number && strlen(magic_number) > NC_MAX_MAGIC_NUMBER_LEN)
113  return NC_EINVAL;
114 
115  /* Retain a pointer to the dispatch_table and a copy of the magic
116  * number, if one was provided. */
117  switch(mode_flag)
118  {
119  case NC_UDF0:
120  UDF0_dispatch_table = dispatch_table;
121  if (magic_number)
122  strncpy(UDF0_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
123  break;
124  case NC_UDF1:
125  UDF1_dispatch_table = dispatch_table;
126  if (magic_number)
127  strncpy(UDF1_magic_number, magic_number, NC_MAX_MAGIC_NUMBER_LEN);
128  break;
129  }
130 
131  return NC_NOERR;
132 }
133 
150 int
151 nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
152 {
153  /* Check inputs. */
154  if (mode_flag != NC_UDF0 && mode_flag != NC_UDF1)
155  return NC_EINVAL;
156 
157  switch(mode_flag)
158  {
159  case NC_UDF0:
160  if (dispatch_table)
161  *dispatch_table = UDF0_dispatch_table;
162  if (magic_number)
163  strncpy(magic_number, UDF0_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
164  break;
165  case NC_UDF1:
166  if (dispatch_table)
167  *dispatch_table = UDF1_dispatch_table;
168  if (magic_number)
169  strncpy(magic_number, UDF1_magic_number, NC_MAX_MAGIC_NUMBER_LEN);
170  break;
171  }
172 
173  return NC_NOERR;
174 }
175 #endif /* USE_NETCDF4 */
176 
370 int
371 nc_create(const char *path, int cmode, int *ncidp)
372 {
373  return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
374 }
375 
442 int
443 nc__create(const char *path, int cmode, size_t initialsz,
444  size_t *chunksizehintp, int *ncidp)
445 {
446  return NC_create(path, cmode, initialsz, 0,
447  chunksizehintp, 0, NULL, ncidp);
448 }
449 
488 int
489 nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
490 {
491  if(mode & NC_MMAP) return NC_EINVAL;
492  mode |= NC_INMEMORY; /* Specifically, do not set NC_DISKLESS */
493  return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
494 }
495 
515 int
516 nc__create_mp(const char *path, int cmode, size_t initialsz,
517  int basepe, size_t *chunksizehintp, int *ncidp)
518 {
519  return NC_create(path, cmode, initialsz, basepe,
520  chunksizehintp, 0, NULL, ncidp);
521 }
522 
636 int
637 nc_open(const char *path, int omode, int *ncidp)
638 {
639  return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
640 }
641 
693 int
694 nc__open(const char *path, int omode,
695  size_t *chunksizehintp, int *ncidp)
696 {
697  /* this API is for non-parallel access.
698  * Note nc_open_par() also calls NC_open().
699  */
700  return NC_open(path, omode, 0, chunksizehintp, 0, NULL, ncidp);
701 }
702 
748 int
749 nc_open_mem(const char* path, int omode, size_t size, void* memory, int* ncidp)
750 {
751  NC_memio meminfo;
752 
753  /* Sanity checks */
754  if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
755  return NC_EINVAL;
756  if(omode & (NC_WRITE|NC_MMAP))
757  return NC_EINVAL;
758  omode |= (NC_INMEMORY); /* Note: NC_INMEMORY and NC_DISKLESS are mutually exclusive*/
759  meminfo.size = size;
760  meminfo.memory = memory;
761  meminfo.flags = NC_MEMIO_LOCKED;
762  return NC_open(path, omode, 0, NULL, 0, &meminfo, ncidp);
763 }
764 
813 int
814 nc_open_memio(const char* path, int omode, NC_memio* params, int* ncidp)
815 {
816  /* Sanity checks */
817  if(path == NULL || params == NULL)
818  return NC_EINVAL;
819  if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
820  return NC_EINVAL;
821 
822  if(omode & NC_MMAP)
823  return NC_EINVAL;
824  omode |= (NC_INMEMORY);
825  return NC_open(path, omode, 0, NULL, 0, params, ncidp);
826 }
827 
846 int
847 nc__open_mp(const char *path, int omode, int basepe,
848  size_t *chunksizehintp, int *ncidp)
849 {
850  return NC_open(path, omode, basepe, chunksizehintp, 0, NULL, ncidp);
851 }
852 
870 int
871 nc_inq_path(int ncid, size_t *pathlen, char *path)
872 {
873  NC* ncp;
874  int stat = NC_NOERR;
875  if ((stat = NC_check_id(ncid, &ncp)))
876  return stat;
877  if(ncp->path == NULL) {
878  if(pathlen) *pathlen = 0;
879  if(path) path[0] = '\0';
880  } else {
881  if (pathlen) *pathlen = strlen(ncp->path);
882  if (path) strcpy(path, ncp->path);
883  }
884  return stat;
885 }
886 
935 int
936 nc_redef(int ncid)
937 {
938  NC* ncp;
939  int stat = NC_check_id(ncid, &ncp);
940  if(stat != NC_NOERR) return stat;
941  return ncp->dispatch->redef(ncid);
942 }
943 
999 int
1000 nc_enddef(int ncid)
1001 {
1002  int status = NC_NOERR;
1003  NC *ncp;
1004  status = NC_check_id(ncid, &ncp);
1005  if(status != NC_NOERR) return status;
1006  return ncp->dispatch->_enddef(ncid,0,1,0,1);
1007 }
1008 
1090 int
1091 nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree,
1092  size_t r_align)
1093 {
1094  NC* ncp;
1095  int stat = NC_check_id(ncid, &ncp);
1096  if(stat != NC_NOERR) return stat;
1097  return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
1098 }
1099 
1167 int
1168 nc_sync(int ncid)
1169 {
1170  NC* ncp;
1171  int stat = NC_check_id(ncid, &ncp);
1172  if(stat != NC_NOERR) return stat;
1173  return ncp->dispatch->sync(ncid);
1174 }
1175 
1219 int
1220 nc_abort(int ncid)
1221 {
1222  NC* ncp;
1223  int stat = NC_check_id(ncid, &ncp);
1224  if(stat != NC_NOERR) return stat;
1225 
1226 #ifdef USE_REFCOUNT
1227  /* What to do if refcount > 0? */
1228  /* currently, forcibly abort */
1229  ncp->refcount = 0;
1230 #endif
1231 
1232  stat = ncp->dispatch->abort(ncid);
1233  del_from_NCList(ncp);
1234  free_NC(ncp);
1235  return stat;
1236 }
1237 
1278 int
1279 nc_close(int ncid)
1280 {
1281  NC* ncp;
1282  int stat = NC_check_id(ncid, &ncp);
1283  if(stat != NC_NOERR) return stat;
1284 
1285 #ifdef USE_REFCOUNT
1286  ncp->refcount--;
1287  if(ncp->refcount <= 0)
1288 #endif
1289  {
1290  stat = ncp->dispatch->close(ncid,NULL);
1291  /* Remove from the nc list */
1292  if (!stat)
1293  {
1294  del_from_NCList(ncp);
1295  free_NC(ncp);
1296  }
1297  }
1298  return stat;
1299 }
1300 
1343 int
1344 nc_close_memio(int ncid, NC_memio* memio)
1345 {
1346  NC* ncp;
1347  int stat = NC_check_id(ncid, &ncp);
1348  if(stat != NC_NOERR) return stat;
1349 
1350 #ifdef USE_REFCOUNT
1351  ncp->refcount--;
1352  if(ncp->refcount <= 0)
1353 #endif
1354  {
1355  stat = ncp->dispatch->close(ncid,memio);
1356  /* Remove from the nc list */
1357  if (!stat)
1358  {
1359  del_from_NCList(ncp);
1360  free_NC(ncp);
1361  }
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  return ncp->dispatch->inq_base_pe(ncid,pe);
1494 }
1495 
1510 int
1511 nc_set_base_pe(int ncid, int pe)
1512 {
1513  NC* ncp;
1514  int stat = NC_check_id(ncid, &ncp);
1515  if(stat != NC_NOERR) return stat;
1516  return ncp->dispatch->set_base_pe(ncid,pe);
1517 }
1518 
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  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 char* p;
1855  for(p=(char*)path0;*p;p++) {if(*p > ' ') break;}
1856 #ifdef WINPATH
1857  /* Need to do path conversion */
1858  path = NCpathcvt(p);
1859 #else
1860  path = nulldup(p);
1861 #endif
1862  }
1863 
1864 #ifdef USE_REFCOUNT
1865  /* If this path is already open, then fail */
1866  ncp = find_in_NCList_by_name(path);
1867  if(ncp != NULL) {
1868  nullfree(path);
1869  return NC_ENFILE;
1870  }
1871 #endif
1872 
1873  memset(&model,0,sizeof(model));
1874  if((stat = NC_infermodel(path,&cmode,1,useparallel,NULL,&model,&newpath)))
1875  goto done;
1876  if(newpath) {
1877  nullfree(path);
1878  path = newpath;
1879  newpath = NULL;
1880  }
1881 
1882  assert(model.format != 0 && model.impl != 0);
1883 
1884  /* Now, check for NC_ENOTBUILT cases limited to create (so e.g. HDF4 is not listed) */
1885 #ifndef USE_HDF5
1886  if (model.impl == NC_FORMATX_NC4)
1887  {stat = NC_ENOTBUILT; goto done;}
1888 #endif
1889 #ifndef USE_PNETCDF
1890  if (model.impl == NC_FORMATX_PNETCDF)
1891  {stat = NC_ENOTBUILT; goto done;}
1892 #endif
1893 #ifndef ENABLE_CDF5
1894  if (model.impl == NC_FORMATX_NC3 && (cmode & NC_64BIT_DATA))
1895  {stat = NC_ENOTBUILT; goto done;}
1896 #endif
1897 
1898  /* Figure out what dispatcher to use */
1899  switch (model.impl) {
1900 #ifdef USE_HDF5
1901  case NC_FORMATX_NC4:
1902  dispatcher = HDF5_dispatch_table;
1903  break;
1904 #endif
1905 #ifdef USE_PNETCDF
1906  case NC_FORMATX_PNETCDF:
1907  dispatcher = NCP_dispatch_table;
1908  break;
1909 #endif
1910  case NC_FORMATX_NC3:
1911  dispatcher = NC3_dispatch_table;
1912  break;
1913  default:
1914  return NC_ENOTNC;
1915  }
1916 
1917  /* Create the NC* instance and insert its dispatcher and model */
1918  if((stat = new_NC(dispatcher,path,cmode,&model,&ncp))) goto done;
1919 
1920  /* Add to list of known open files and define ext_ncid */
1921  add_to_NCList(ncp);
1922 
1923 #ifdef USE_REFCOUNT
1924  /* bump the refcount */
1925  ncp->refcount++;
1926 #endif
1927 
1928  /* Assume create will fill in remaining ncp fields */
1929  if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp,
1930  parameters, dispatcher, ncp))) {
1931  del_from_NCList(ncp); /* oh well */
1932  free_NC(ncp);
1933  } else {
1934  if(ncidp)*ncidp = ncp->ext_ncid;
1935  }
1936 done:
1937  nullfree(path);
1938  return stat;
1939 }
1940 
1964 int
1965 NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
1966  int useparallel, void* parameters, int *ncidp)
1967 {
1968  int stat = NC_NOERR;
1969  NC* ncp = NULL;
1970  NC_Dispatch* dispatcher = NULL;
1971  int inmemory = 0;
1972  int diskless = 0;
1973  int mmap = 0;
1974  char* path = NULL;
1975  NCmodel model;
1976  char* newpath = NULL;
1977 
1978  TRACE(nc_open);
1979  if(!NC_initialized) {
1980  stat = nc_initialize();
1981  if(stat) return stat;
1982  }
1983 
1984  /* Capture the inmemory related flags */
1985  mmap = ((omode & NC_MMAP) == NC_MMAP);
1986  diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
1987  inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
1988 
1989  /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1990  if(diskless && inmemory) {stat = NC_EDISKLESS; goto done;}
1991  if(diskless && mmap) {stat = NC_EDISKLESS; goto done;}
1992  if(inmemory && mmap) {stat = NC_EINMEMORY; goto done;}
1993 
1994  /* mmap is not allowed for netcdf-4 */
1995  if(mmap && (omode & NC_NETCDF4)) {stat = NC_EINVAL; goto done;}
1996 
1997  /* Attempt to do file path conversion: note that this will do
1998  nothing if path is a 'file:...' url, so it will need to be
1999  repeated in protocol code (e.g. libdap2, libdap4, etc).
2000  */
2001 
2002  {
2003  /* Skip past any leading whitespace in path */
2004  const char* p;
2005  for(p=(char*)path0;*p;p++) {if(*p > ' ') break;}
2006 #ifdef WINPATH
2007  /* Need to do path conversion */
2008  path = NCpathcvt(p);
2009 #else
2010  path = nulldup(p);
2011 #endif
2012  }
2013 
2014 #ifdef USE_REFCOUNT
2015  /* If this path is already open, then bump the refcount and return it */
2016  ncp = find_in_NCList_by_name(path);
2017  if(ncp != NULL) {
2018  nullfree(path);
2019  ncp->refcount++;
2020  if(ncidp) *ncidp = ncp->ext_ncid;
2021  return NC_NOERR;
2022  }
2023 #endif
2024 
2025  memset(&model,0,sizeof(model));
2026  /* Infer model implementation and format, possibly by reading the file */
2027  if((stat = NC_infermodel(path,&omode,0,useparallel,parameters,&model,&newpath)))
2028  goto done;
2029  if(newpath) {
2030  nullfree(path);
2031  path = newpath;
2032  }
2033 
2034  /* Still no implementation, give up */
2035  if(model.impl == 0) {
2036 #ifdef DEBUG
2037  fprintf(stderr,"implementation == 0\n");
2038 #endif
2039  {stat = NC_ENOTNC; goto done;}
2040  }
2041 
2042  /* Suppress unsupported formats */
2043  {
2044  int hdf5built = 0;
2045  int hdf4built = 0;
2046  int cdf5built = 0;
2047  int udf0built = 0;
2048  int udf1built = 0;
2049 #ifdef USE_NETCDF4
2050  hdf5built = 1;
2051 #ifdef USE_HDF4
2052  hdf4built = 1;
2053 #endif
2054 #endif
2055 #ifdef ENABLE_CDF5
2056  cdf5built = 1;
2057 #endif
2058  if(UDF0_dispatch_table != NULL)
2059  udf0built = 1;
2060  if(UDF1_dispatch_table != NULL)
2061  udf1built = 1;
2062 
2063  if(!hdf5built && model.impl == NC_FORMATX_NC4)
2064  {stat = NC_ENOTBUILT; goto done;}
2065  if(!hdf4built && model.impl == NC_FORMATX_NC_HDF4)
2066  {stat = NC_ENOTBUILT; goto done;}
2067  if(!cdf5built && model.impl == NC_FORMATX_NC3 && model.format == NC_FORMAT_CDF5)
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  /* Figure out what dispatcher to use */
2075  if (!dispatcher) {
2076  switch (model.impl) {
2077 #ifdef ENABLE_DAP
2078  case NC_FORMATX_DAP2:
2079  dispatcher = NCD2_dispatch_table;
2080  break;
2081 #endif
2082 #ifdef ENABLE_DAP4
2083  case NC_FORMATX_DAP4:
2084  dispatcher = NCD4_dispatch_table;
2085  break;
2086 #endif
2087 #ifdef USE_PNETCDF
2088  case NC_FORMATX_PNETCDF:
2089  dispatcher = NCP_dispatch_table;
2090  break;
2091 #endif
2092 #ifdef USE_HDF5
2093  case NC_FORMATX_NC4:
2094  dispatcher = HDF5_dispatch_table;
2095  break;
2096 #endif
2097 #ifdef USE_HDF4
2098  case NC_FORMATX_NC_HDF4:
2099  dispatcher = HDF4_dispatch_table;
2100  break;
2101 #endif
2102 #ifdef USE_NETCDF4
2103  case NC_FORMATX_UDF0:
2104  dispatcher = UDF0_dispatch_table;
2105  break;
2106  case NC_FORMATX_UDF1:
2107  dispatcher = UDF1_dispatch_table;
2108  break;
2109 #endif /* USE_NETCDF4 */
2110  case NC_FORMATX_NC3:
2111  dispatcher = NC3_dispatch_table;
2112  break;
2113  default:
2114  nullfree(path);
2115  return NC_ENOTNC;
2116  }
2117  }
2118 
2119 
2120  /* If we can't figure out what dispatch table to use, give up. */
2121  if (!dispatcher) {stat = NC_ENOTNC; goto done;}
2122 
2123  /* Create the NC* instance and insert its dispatcher */
2124  if((stat = new_NC(dispatcher,path,omode,&model,&ncp))) goto done;
2125 
2126  /* Add to list of known open files */
2127  add_to_NCList(ncp);
2128 
2129 #ifdef USE_REFCOUNT
2130  /* bump the refcount */
2131  ncp->refcount++;
2132 #endif
2133 
2134  /* Assume open will fill in remaining ncp fields */
2135  stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2136  parameters, dispatcher, ncp);
2137  if(stat == NC_NOERR) {
2138  if(ncidp) *ncidp = ncp->ext_ncid;
2139  } else {
2140  del_from_NCList(ncp);
2141  free_NC(ncp);
2142  }
2143 
2144 done:
2145  nullfree(path);
2146  return stat;
2147 }
2148 
2149 /*Provide an internal function for generating pseudo file descriptors
2150  for systems that are not file based (e.g. dap, memio).
2151 */
2152 
2154 static int pseudofd = 0;
2155 
2163 int
2164 nc__pseudofd(void)
2165 {
2166  if(pseudofd == 0) {
2167  int maxfd = 32767; /* default */
2168 #ifdef HAVE_GETRLIMIT
2169  struct rlimit rl;
2170  if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2171  if(rl.rlim_max != RLIM_INFINITY)
2172  maxfd = (int)rl.rlim_max;
2173  if(rl.rlim_cur != RLIM_INFINITY)
2174  maxfd = (int)rl.rlim_cur;
2175  }
2176  pseudofd = maxfd+1;
2177 #endif
2178  }
2179  return pseudofd++;
2180 }
#define NC_MAX_MAGIC_NUMBER_LEN
Max len of user-defined format magic number.
Definition: netcdf.h:163
#define NC_ENFILE
Too many netcdfs open.
Definition: netcdf.h:333
int nc_def_user_format(int mode_flag, NC_Dispatch *dispatch_table, char *magic_number)
Add handling of user-defined format.
Definition: dfile.c:105
int NC_initialized
True when dispatch table is initialized.
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:1344
#define NC_FORMATX_NC4
alias
Definition: netcdf.h:212
Main header file for in-memory (diskless) functionality.
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
Definition: dfile.c:936
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:1091
#define NC_UDF1
User-defined format 1.
Definition: netcdf.h:136
#define NC_INMEMORY
Read from memory.
Definition: netcdf.h:161
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:814
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:1538
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1626
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:139
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:694
#define NC_UDF0
User-defined format 0.
Definition: netcdf.h:135
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:1573
#define NC_ENOTNC
Not a netcdf file.
Definition: netcdf.h:381
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition: netcdf.h:185
#define NC_64BIT_DATA
CDF-5 format: classic model but 64 bit dimensions and sizes.
Definition: netcdf.h:132
#define NC_ENOTBUILT
Attempt to use feature that was not turned on when netCDF was built.
Definition: netcdf.h:465
int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1279
#define NC_EDISKLESS
Error in using diskless access.
Definition: netcdf.h:466
int nc_abort(int ncid)
No longer necessary for user to invoke manually.
Definition: dfile.c:1220
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:367
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:749
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition: netcdf.h:239
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:335
#define NC_EINMEMORY
In-memory file error.
Definition: netcdf.h:473
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
Definition: dfile.c:1465
#define NC_FORMATX_UDF0
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:217
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:275
#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:1719
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:215
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:210
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition: netcdf.h:151
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:443
#define NC_FORMATX_NC_HDF4
netCDF-4 subset of HDF4
Definition: netcdf.h:213
int nc_open(const char *path, int omode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:637
#define NC_FORMATX_UDF1
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:218
#define NC_CDF5
Alias NC_CDF5 to NC_64BIT_DATA.
Definition: netcdf.h:133
#define NC_WRITE
Set read-write access for nc_open().
Definition: netcdf.h:124
int nc_inq_user_format(int mode_flag, NC_Dispatch **dispatch_table, char *magic_number)
Inquire about user-defined format.
Definition: dfile.c:151
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:489
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&#39;s file...
Definition: dfile.c:871
#define NC_NOERR
No Error.
Definition: netcdf.h:325
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition: dfile.c:1645
#define NC_DISKLESS
Use diskless file.
Definition: netcdf.h:129
static int check_create_mode(int mode)
Check the create mode parameter for sanity.
Definition: dfile.c:1759
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:216
int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:1000
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
Definition: netcdf.h:214
#define NC_MMAP
Definition: netcdf.h:130
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
Definition: dfile.c:1168
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:371

Return to the Main Unidata NetCDF page.
Generated on Mon Apr 29 2019 10:59:59 for NetCDF. NetCDF is a Unidata library.