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