NetCDF 4.9.3-rc1
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
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
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
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
1767static int
1769{
1770 int mode_format;
1771 int use_mmap = 0;
1772 int inmemory = 0;
1773 int diskless = 0;
1774
1775 /* This is a clever check to see if more than one format bit is
1776 * set. */
1777 mode_format = (mode & NC_NETCDF4) | (mode & NC_64BIT_OFFSET) |
1778 (mode & NC_CDF5);
1779 if (mode_format && (mode_format & (mode_format - 1)))
1780 return NC_EINVAL;
1781
1782 use_mmap = ((mode & NC_MMAP) == NC_MMAP);
1783 inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
1784 diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
1785
1786 /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1787 if(diskless && inmemory) return NC_EDISKLESS;
1788 if(diskless && use_mmap) return NC_EDISKLESS;
1789 if(inmemory && use_mmap) return NC_EINMEMORY;
1790
1791 /* mmap is not allowed for netcdf-4 */
1792 if(use_mmap && (mode & NC_NETCDF4)) return NC_EINVAL;
1793
1794#ifndef USE_NETCDF4
1795 /* If the user asks for a netCDF-4 file, and the library was built
1796 * without netCDF-4, then return an error.*/
1797 if (mode & NC_NETCDF4)
1798 return NC_ENOTBUILT;
1799#endif /* USE_NETCDF4 undefined */
1800
1801 /* Well I guess there is some sanity in the world after all. */
1802 return NC_NOERR;
1803}
1804
1832int
1833NC_create(const char *path0, int cmode, size_t initialsz,
1834 int basepe, size_t *chunksizehintp, int useparallel,
1835 void* parameters, int *ncidp)
1836{
1837 int stat = NC_NOERR;
1838 NC* ncp = NULL;
1839 const NC_Dispatch* dispatcher = NULL;
1840 char* path = NULL;
1841 NCmodel model;
1842 char* newpath = NULL;
1843
1844 TRACE(nc_create);
1845 if(path0 == NULL)
1846 {stat = NC_EINVAL; goto done;}
1847
1848 /* Check mode flag for sanity. */
1849 if ((stat = check_create_mode(cmode))) goto done;
1850
1851 /* Initialize the library. The available dispatch tables
1852 * will depend on how netCDF was built
1853 * (with/without netCDF-4, DAP, CDMREMOTE). */
1854 if(!NC_initialized) {
1855 if ((stat = nc_initialize())) goto done;
1856 }
1857
1858 {
1859 /* Skip past any leading whitespace in path */
1860 const unsigned char* p;
1861 for(p=(const unsigned char*)path0;*p;p++) {if(*p > ' ') break;}
1862 path = nulldup((const char*)p);
1863 }
1864
1865 memset(&model,0,sizeof(model));
1866 newpath = NULL;
1867 if((stat = NC_infermodel(path,&cmode,1,useparallel,NULL,&model,&newpath))) goto done;
1868 if(newpath) {
1869 nullfree(path);
1870 path = newpath;
1871 newpath = NULL;
1872 }
1873
1874 assert(model.format != 0 && model.impl != 0);
1875
1876 /* Now, check for NC_ENOTBUILT cases limited to create (so e.g. HDF4 is not listed) */
1877#ifndef USE_HDF5
1878 if (model.impl == NC_FORMATX_NC4)
1879 {stat = NC_ENOTBUILT; goto done;}
1880#endif
1881#ifndef USE_PNETCDF
1882 if (model.impl == NC_FORMATX_PNETCDF)
1883 {stat = NC_ENOTBUILT; goto done;}
1884#endif
1885#ifndef NETCDF_ENABLE_CDF5
1886 if (model.impl == NC_FORMATX_NC3 && (cmode & NC_64BIT_DATA))
1887 {stat = NC_ENOTBUILT; goto done;}
1888#endif
1889
1890 /* Figure out what dispatcher to use */
1891 switch (model.impl) {
1892#ifdef USE_HDF5
1893 case NC_FORMATX_NC4:
1894 dispatcher = HDF5_dispatch_table;
1895 break;
1896#endif
1897#ifdef USE_PNETCDF
1898 case NC_FORMATX_PNETCDF:
1899 dispatcher = NCP_dispatch_table;
1900 break;
1901#endif
1902#ifdef USE_NETCDF4
1903 case NC_FORMATX_UDF0:
1904 dispatcher = UDF0_dispatch_table;
1905 break;
1906 case NC_FORMATX_UDF1:
1907 dispatcher = UDF1_dispatch_table;
1908 break;
1909#endif /* USE_NETCDF4 */
1910#ifdef NETCDF_ENABLE_NCZARR
1911 case NC_FORMATX_NCZARR:
1912 dispatcher = NCZ_dispatch_table;
1913 break;
1914#endif
1915 case NC_FORMATX_NC3:
1916 dispatcher = NC3_dispatch_table;
1917 break;
1918 default:
1919 {stat = NC_ENOTNC; goto done;}
1920 }
1921
1922 /* Create the NC* instance and insert its dispatcher and model */
1923 if((stat = new_NC(dispatcher,path,cmode,&ncp))) goto done;
1924
1925 /* Add to list of known open files and define ext_ncid */
1926 add_to_NCList(ncp);
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->ext_ncid))) {
1931 del_from_NCList(ncp); /* oh well */
1932 free_NC(ncp);
1933 } else {
1934 if(ncidp)*ncidp = ncp->ext_ncid;
1935 }
1936done:
1937 nullfree(path);
1938 nullfree(newpath);
1939 return stat;
1940}
1941
1965int
1966NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp,
1967 int useparallel, void* parameters, int *ncidp)
1968{
1969 int stat = NC_NOERR;
1970 NC* ncp = NULL;
1971 const NC_Dispatch* dispatcher = NULL;
1972 int inmemory = 0;
1973 int diskless = 0;
1974 int use_mmap = 0;
1975 char* path = NULL;
1976 NCmodel model;
1977 char* newpath = NULL;
1978
1979 TRACE(nc_open);
1980 if(!NC_initialized) {
1981 stat = nc_initialize();
1982 if(stat) goto done;
1983 }
1984
1985 /* Check inputs. */
1986 if (!path0)
1987 {stat = NC_EINVAL; goto done;}
1988
1989 /* Capture the inmemory related flags */
1990 use_mmap = ((omode & NC_MMAP) == NC_MMAP);
1991 diskless = ((omode & NC_DISKLESS) == NC_DISKLESS);
1992 inmemory = ((omode & NC_INMEMORY) == NC_INMEMORY);
1993
1994 /* NC_INMEMORY and NC_DISKLESS and NC_MMAP are all mutually exclusive */
1995 if(diskless && inmemory) {stat = NC_EDISKLESS; goto done;}
1996 if(diskless && use_mmap) {stat = NC_EDISKLESS; goto done;}
1997 if(inmemory && use_mmap) {stat = NC_EINMEMORY; goto done;}
1998
1999 /* mmap is not allowed for netcdf-4 */
2000 if(use_mmap && (omode & NC_NETCDF4)) {stat = NC_EINVAL; goto done;}
2001
2002 /* Attempt to do file path conversion: note that this will do
2003 nothing if path is a 'file:...' url, so it will need to be
2004 repeated in protocol code (e.g. libdap2, libdap4, etc).
2005 */
2006
2007 {
2008 /* Skip past any leading whitespace in path */
2009 const char* p;
2010 for(p=(const char*)path0;*p;p++) {if(*p < 0 || *p > ' ') break;}
2011 path = nulldup(p);
2012 }
2013
2014 memset(&model,0,sizeof(model));
2015 /* Infer model implementation and format, possibly by reading the file */
2016 if((stat = NC_infermodel(path,&omode,0,useparallel,parameters,&model,&newpath)))
2017 goto done;
2018 if(newpath) {
2019 nullfree(path);
2020 path = newpath;
2021 newpath = NULL;
2022 }
2023
2024 /* Still no implementation, give up */
2025 if(model.impl == 0) {
2026#ifdef DEBUG
2027 fprintf(stderr,"implementation == 0\n");
2028#endif
2029 {stat = NC_ENOTNC; goto done;}
2030 }
2031
2032 /* Suppress unsupported formats */
2033#if 0
2034 /* (should be more compact, table-driven, way to do this) */
2035 {
2036 int hdf5built = 0;
2037 int hdf4built = 0;
2038 int cdf5built = 0;
2039 int udf0built = 0;
2040 int udf1built = 0;
2041 int nczarrbuilt = 0;
2042#ifdef USE_NETCDF4
2043 hdf5built = 1;
2044#endif
2045#ifdef USE_HDF4
2046 hdf4built = 1;
2047#endif
2048#ifdef NETCDF_ENABLE_CDF5
2049 cdf5built = 1;
2050#endif
2051#ifdef NETCDF_ENABLE_NCZARR
2052 nczarrbuilt = 1;
2053#endif
2054 if(UDF0_dispatch_table != NULL)
2055 udf0built = 1;
2056 if(UDF1_dispatch_table != NULL)
2057 udf1built = 1;
2058
2059 if(!hdf5built && model.impl == NC_FORMATX_NC4)
2060 {stat = NC_ENOTBUILT; goto done;}
2061 if(!hdf4built && model.impl == NC_FORMATX_NC_HDF4)
2062 {stat = NC_ENOTBUILT; goto done;}
2063 if(!cdf5built && model.impl == NC_FORMATX_NC3 && model.format == NC_FORMAT_CDF5)
2064 {stat = NC_ENOTBUILT; goto done;}
2065 if(!nczarrbuilt && model.impl == NC_FORMATX_NCZARR)
2066 {stat = NC_ENOTBUILT; goto done;}
2067 if(!udf0built && model.impl == NC_FORMATX_UDF0)
2068 {stat = NC_ENOTBUILT; goto done;}
2069 if(!udf1built && model.impl == NC_FORMATX_UDF1)
2070 {stat = NC_ENOTBUILT; goto done;}
2071 }
2072#else
2073 {
2074 unsigned built = 0 /* leave off the trailing semicolon so we can build constant */
2075 | (1<<NC_FORMATX_NC3) /* NC3 always supported */
2076#ifdef USE_HDF5
2077 | (1<<NC_FORMATX_NC_HDF5)
2078#endif
2079#ifdef USE_HDF4
2080 | (1<<NC_FORMATX_NC_HDF4)
2081#endif
2082#ifdef NETCDF_ENABLE_NCZARR
2083 | (1<<NC_FORMATX_NCZARR)
2084#endif
2085#ifdef NETCDF_ENABLE_DAP
2086 | (1<<NC_FORMATX_DAP2)
2087#endif
2088#ifdef NETCDF_ENABLE_DAP4
2089 | (1<<NC_FORMATX_DAP4)
2090#endif
2091#ifdef USE_PNETCDF
2092 | (1<<NC_FORMATX_PNETCDF)
2093#endif
2094 ; /* end of the built flags */
2095 if(UDF0_dispatch_table != NULL)
2096 built |= (1<<NC_FORMATX_UDF0);
2097 if(UDF1_dispatch_table != NULL)
2098 built |= (1<<NC_FORMATX_UDF1);
2099 /* Verify */
2100 if((built & (1 << model.impl)) == 0)
2101 {stat = NC_ENOTBUILT; goto done;}
2102#ifndef NETCDF_ENABLE_CDF5
2103 /* Special case because there is no separate CDF5 dispatcher */
2104 if(model.impl == NC_FORMATX_NC3 && (omode & NC_64BIT_DATA))
2105 {stat = NC_ENOTBUILT; goto done;}
2106#endif
2107 }
2108#endif
2109 /* Figure out what dispatcher to use */
2110 if (!dispatcher) {
2111 switch (model.impl) {
2112#ifdef NETCDF_ENABLE_DAP
2113 case NC_FORMATX_DAP2:
2114 dispatcher = NCD2_dispatch_table;
2115 break;
2116#endif
2117#ifdef NETCDF_ENABLE_DAP4
2118 case NC_FORMATX_DAP4:
2119 dispatcher = NCD4_dispatch_table;
2120 break;
2121#endif
2122#ifdef NETCDF_ENABLE_NCZARR
2123 case NC_FORMATX_NCZARR:
2124 dispatcher = NCZ_dispatch_table;
2125 break;
2126#endif
2127#ifdef USE_PNETCDF
2128 case NC_FORMATX_PNETCDF:
2129 dispatcher = NCP_dispatch_table;
2130 break;
2131#endif
2132#ifdef USE_HDF5
2133 case NC_FORMATX_NC4:
2134 dispatcher = HDF5_dispatch_table;
2135 break;
2136#endif
2137#ifdef USE_HDF4
2138 case NC_FORMATX_NC_HDF4:
2139 dispatcher = HDF4_dispatch_table;
2140 break;
2141#endif
2142#ifdef USE_NETCDF4
2143 case NC_FORMATX_UDF0:
2144 dispatcher = UDF0_dispatch_table;
2145 break;
2146 case NC_FORMATX_UDF1:
2147 dispatcher = UDF1_dispatch_table;
2148 break;
2149#endif /* USE_NETCDF4 */
2150 case NC_FORMATX_NC3:
2151 dispatcher = NC3_dispatch_table;
2152 break;
2153 default:
2154 stat = NC_ENOTNC;
2155 goto done;
2156 }
2157 }
2158
2159
2160 /* If we can't figure out what dispatch table to use, give up. */
2161 if (!dispatcher) {stat = NC_ENOTNC; goto done;}
2162
2163 /* Create the NC* instance and insert its dispatcher */
2164 if((stat = new_NC(dispatcher,path,omode,&ncp))) goto done;
2165
2166 /* Add to list of known open files. This assigns an ext_ncid. */
2167 add_to_NCList(ncp);
2168
2169 /* Assume open will fill in remaining ncp fields */
2170 stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp,
2171 parameters, dispatcher, ncp->ext_ncid);
2172 if(stat == NC_NOERR) {
2173 if(ncidp) *ncidp = ncp->ext_ncid;
2174 } else {
2175 del_from_NCList(ncp);
2176 free_NC(ncp);
2177 }
2178
2179done:
2180 nullfree(path);
2181 nullfree(newpath);
2182 return stat;
2183}
2184
2185/*Provide an internal function for generating pseudo file descriptors
2186 for systems that are not file based (e.g. dap, memio).
2187*/
2188
2190static int pseudofd = 0;
2191
2199int
2200nc__pseudofd(void)
2201{
2202 if(pseudofd == 0) {
2203#ifdef HAVE_GETRLIMIT
2204 int maxfd = 32767; /* default */
2205 struct rlimit rl;
2206 if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
2207 if(rl.rlim_max != RLIM_INFINITY)
2208 maxfd = (int)rl.rlim_max;
2209 if(rl.rlim_cur != RLIM_INFINITY)
2210 maxfd = (int)rl.rlim_cur;
2211 }
2212 pseudofd = maxfd+1;
2213#endif
2214 }
2215 return pseudofd++;
2216}
int nc_inq_nvars(int ncid, int *nvarsp)
Learn the number of variables in a file or group.
Definition dfile.c:1654
static int check_create_mode(int mode)
Check the create mode parameter for sanity.
Definition dfile.c:1768
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
#define NC_MAX_MAGIC_NUMBER_LEN
Max len of user-defined format magic number.
Definition netcdf.h:170
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
Definition netcdf.h:154
#define NC_UDF0
User-defined format 0.
Definition netcdf.h:138
#define NC_EDISKLESS
Error in using diskless access.
Definition netcdf.h:510
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
Definition netcdf.h:246
#define NC_EBADTYPE
Not a netcdf data type.
Definition netcdf.h:411
#define NC_MMAP
Definition netcdf.h:133
#define NC_INMEMORY
Read from memory.
Definition netcdf.h:164
#define NC_CDF5
Alias NC_CDF5 to NC_64BIT_DATA.
Definition netcdf.h:136
#define NC_FORMATX_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition netcdf.h:217
#define NC_FORMATX_NCZARR
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition netcdf.h:226
#define NC_ENOTNC
Not a netcdf file.
Definition netcdf.h:425
#define NC_NAT
Not A Type.
Definition netcdf.h:34
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
Definition netcdf.h:142
#define NC_EINMEMORY
In-memory file error.
Definition netcdf.h:517
#define NC_FORMATX_UDF1
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition netcdf.h:225
#define NC_FORMATX_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition netcdf.h:221
#define NC_FORMAT_CDF5
Format specifier for nc_set_default_format() and returned by nc_inq_format.
Definition netcdf.h:192
#define NC_FORMATX_NC_HDF4
netCDF-4 subset of HDF4
Definition netcdf.h:220
#define NC_WRITE
Set read-write access for nc_open().
Definition netcdf.h:128
#define NC_FORMATX_NC_HDF5
netCDF-4 subset of HDF5
Definition netcdf.h:218
#define NC_FORMATX_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition netcdf.h:223
#define NC_FORMATX_UDF0
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition netcdf.h:224
#define NC_DISKLESS
Use diskless file.
Definition netcdf.h:132
#define NC_FORMATX_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4....
Definition netcdf.h:222
#define NC_EINVAL
Invalid Argument.
Definition netcdf.h:379
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
Definition netcdf.h:141
#define NC_MAX_NAME
Maximum for classic library.
Definition netcdf.h:282
#define NC_NOERR
No Error.
Definition netcdf.h:369
#define NC_64BIT_DATA
CDF-5 format: classic model but 64 bit dimensions and sizes.
Definition netcdf.h:135
#define NC_ENOTBUILT
Attempt to use feature that was not turned on when netCDF was built.
Definition netcdf.h:509
#define NC_UDF1
User-defined format 1.
Definition netcdf.h:139
int nc_type
The nc_type type is just an int.
Definition netcdf.h:25
#define NC_FORMATX_NC4
alias
Definition netcdf.h:219
Main header file for in-memory (diskless) functionality.