NetCDF 4.9.2
Loading...
Searching...
No Matches
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
48extern int NC_initialized;
50/* User-defined formats. */
51NC_Dispatch *UDF0_dispatch_table = NULL;
52char UDF0_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
53NC_Dispatch *UDF1_dispatch_table = NULL;
54char UDF1_magic_number[NC_MAX_MAGIC_NUMBER_LEN + 1] = "";
55
56/**************************************************/
57
58
124int
125nc_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
180int
181nc_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
399int
400nc_create(const char *path, int cmode, int *ncidp)
401{
402 return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp);
403}
404
471int
472nc__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
517int
518nc_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
544int
545nc__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
665int
666nc_open(const char *path, int omode, int *ncidp)
667{
668 return NC_open(path, omode, 0, NULL, 0, NULL, ncidp);
669}
670
722int
723nc__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
777int
778nc_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
842int
843nc_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
875int
876nc__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
899int
900nc_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
964int
965nc_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
1028int
1029nc_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
1119int
1120nc__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
1196int
1197nc_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
1248int
1249nc_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
1301int
1302nc_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
1360int
1361nc_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
1475int
1476nc_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
1498int
1499nc_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
1522int
1523nc_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
1548int
1549nc_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
1583int
1584nc_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
1636int
1637nc_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
1655int
1656nc_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
1729int
1730nc_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
1769static 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
1834int
1835NC_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 }
1938done:
1939 nullfree(path);
1940 nullfree(newpath);
1941 return stat;
1942}
1943
1967int
1968NC_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
2181done:
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
2192static int pseudofd = 0;
2193
2201int
2202nc__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.