mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
1. Keep up to date by merging master
2. Factored out the parameter string parsing for ncgen and nccopy int libdispatch/dfilter.c + include/ncfilter.h 3. Allow a parameter string to use constant types other than unsigned int. See docs/filters.md for details. 4. Moved the old content of include/netcdf_filter.h into include/netcdf.h and removed include/netcdf_filter.h as no longer needed. 5. Force the test filter (bzip2) in nc_test4/filter_test to be built using BUILT_SOURCES.
This commit is contained in:
commit
733da154c5
@ -758,16 +758,25 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
|
||||
|
||||
ENDIF(USE_HDF5 OR ENABLE_NETCDF_4)
|
||||
|
||||
# Option to turn on CDF5 support.
|
||||
OPTION(ENABLE_CDF5 "Enable CDF5 Support." OFF)
|
||||
IF(ENABLE_CDF5)
|
||||
SET(USE_CDF5 ON CACHE BOOL "")
|
||||
ENDIF(ENABLE_CDF5)
|
||||
|
||||
# Option to Build DAP2+DAP4 Clients
|
||||
OPTION(ENABLE_DAP "Enable DAP2 and DAP4 Client." ON)
|
||||
IF(ENABLE_DAP)
|
||||
SET(USE_DAP ON)
|
||||
SET(ENABLE_DAP2 ON)
|
||||
SET(ENABLE_DAP4 ON)
|
||||
IF(NOT ENABLE_NETCDF_4)
|
||||
SET(ENABLE_DAP4 OFF)
|
||||
ENDIF()
|
||||
SET(USE_DAP ON CACHE BOOL "")
|
||||
SET(ENABLE_DAP2 ON CACHE BOOL "")
|
||||
|
||||
|
||||
IF(ENABLE_NETCDF_4)
|
||||
SET(ENABLE_DAP4 ON CACHE BOOL "")
|
||||
ELSE(ENABLE_NETCDF_4)
|
||||
SET(ENABLE_DAP4 OFF CACHE BOOL "")
|
||||
ENDIF(ENABLE_NETCDF_4)
|
||||
|
||||
FIND_PACKAGE(CURL)
|
||||
IF(NOT CURL_LIBRARY)
|
||||
MESSAGE(FATAL_ERROR "DAP Support specified, CURL libraries are not found.")
|
||||
@ -806,6 +815,12 @@ IF(ENABLE_DAP)
|
||||
#include <curl/curl.h>
|
||||
int main() {int x = CURLOPT_CHUNK_BGN_FUNCTION;}" HAVE_CURLOPT_CHUNK_BGN_FUNCTION)
|
||||
|
||||
# Check to see if CURLINFO_HTTP_CONNECTCODE is defined.
|
||||
# It showed up in curl 7.10.7.
|
||||
CHECK_C_SOURCE_COMPILES("
|
||||
#include <curl/curl.h>
|
||||
int main() {int x = CURLINFO_HTTP_CONNECTCODE;}" HAVE_CURLINFO_HTTP_CONNECTCODE)
|
||||
|
||||
ELSE()
|
||||
SET(ENABLE_DAP2 OFF)
|
||||
SET(ENABLE_DAP4 OFF)
|
||||
@ -1887,11 +1902,13 @@ is_enabled(STATUS_PNETCDF HAS_PNETCDF)
|
||||
is_enabled(STATUS_PARALLEL HAS_PARALLEL)
|
||||
is_enabled(ENABLE_PARALLEL4 HAS_PARALLEL4)
|
||||
is_enabled(ENABLE_DAP HAS_DAP)
|
||||
is_enabled(ENABLE_DAP HAS_DAP2)
|
||||
is_enabled(ENABLE_DAP4 HAS_DAP4)
|
||||
is_enabled(USE_DISKLESS HAS_DISKLESS)
|
||||
is_enabled(USE_MMAP HAS_MMAP)
|
||||
is_enabled(JNA HAS_JNA)
|
||||
is_enabled(STATUS_RELAX_COORD_BOUND RELAX_COORD_BOUND)
|
||||
is_enabled(USE_CDF5 HAS_CDF5)
|
||||
|
||||
# Generate file from template.
|
||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/libnetcdf.settings.in"
|
||||
|
@ -10,6 +10,13 @@ This file contains a high-level description of this package's evolution. Release
|
||||
reading and writing. See the file docs/filters.md.
|
||||
* [Bug Fix] Corrected an issue with diskless file access, see [Pull Request #400](https://github.com/Unidata/netcdf-c/issues/400) and [Pull Request #403](https://github.com/Unidata/netcdf-c/issues/403) for more information.
|
||||
|
||||
### 4.5.0-rc3 - September 29, 2017
|
||||
|
||||
* [Update] Due to ongoing issues, native CDF5 support has been disabled by **default**. You can use the options mentioned below (`--enable-cdf5` or `-DENABLE_CDF5=TRUE` for `configure` or `cmake`, respectively). Just be aware that for the time being, Reading/Writing CDF5 files on 32-bit platforms may result in unexpected behavior when using extremely large variables. For 32-bit platforms it is best to continue using `NC_FORMAT_64BIT_OFFSET`.
|
||||
* [Bug] Corrected an issue where older versions of curl might fail. See [GitHub #487](https://github.com/Unidata/netcdf-c/issues/487) for more information.
|
||||
* [Enhancement] Added options to enable/disable `CDF5` support at configure time for autotools and cmake-based builds. The options are `--enable/disable-cdf5` and `ENABLE_CDF5`, respectively. See [Github #484](https://github.com/Unidata/netcdf-c/issues/484) for more information.
|
||||
* [Bug Fix] Corrected an issue when subsetting a netcdf3 file via `nccopy -v/-V`. See [Github #425](https://github.com/Unidata/netcdf-c/issues/425) and [Github #463](https://github.com/Unidata/netcdf-c/issues/463) for more information.
|
||||
* [Bug Fix] Corrected `--has-dap` and `--has-dap4` output for cmake-based builds. See [GitHub #473](https://github.com/Unidata/netcdf-c/pull/473) for more information.
|
||||
* [Bug Fix] Corrected an issue where `NC_64BIT_DATA` files were being read incorrectly by ncdump, despite the data having been written correctly. See [GitHub #457](https://github.com/Unidata/netcdf-c/issues/457) for more information.
|
||||
* [Bug Fix] Corrected a potential stack buffer overflow. See [GitHub #450](https://github.com/Unidata/netcdf-c/pull/450) for more information.
|
||||
|
||||
|
12
cf
12
cf
@ -19,11 +19,6 @@ if test "x$PNETCDF" = x1 -o "x$PAR4" = x1 ; then
|
||||
MPIO=1
|
||||
fi
|
||||
|
||||
#RPC=1
|
||||
|
||||
#M32=1
|
||||
#M64=1
|
||||
|
||||
CFLAGS=""
|
||||
#CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wconversion ${CFLAGS}"
|
||||
CFLAGS="-Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-parameter -Wno-char-subscripts -Wno-pointer-sign -Wno-format ${CFLAGS}"
|
||||
@ -48,6 +43,11 @@ if test "x$HDF4" = x1 ; then
|
||||
HDF5=1
|
||||
fi
|
||||
|
||||
# !HDF5=>!SZIP
|
||||
if test "x$HDF5" != x1 ; then
|
||||
SZIP=0
|
||||
fi
|
||||
|
||||
CC=gcc
|
||||
|
||||
MALLOC_CHECK=""
|
||||
@ -105,7 +105,7 @@ FLAGS="$FLAGS --enable-extra-tests"
|
||||
#FLAGS="$FLAGS --disable-testsets"
|
||||
#FLAGS="$FLAGS --disable-dap-remote-tests"
|
||||
#FLAGS="$FLAGS --enable-dap-auth-tests" -- requires a new remotetest server
|
||||
#FLAGS="$FLAGS --enable-doxygen"
|
||||
FLAGS="$FLAGS --enable-doxygen --enable-internal-docs"
|
||||
FLAGS="$FLAGS --enable-logging"
|
||||
#FLAGS="$FLAGS --disable-diskless"
|
||||
#FLAGS="$FLAGS --enable-mmap"
|
||||
|
@ -14,12 +14,12 @@
|
||||
|
||||
*/
|
||||
|
||||
#cmakedefine HAVE_WINSOCK2_H
|
||||
/* #cmakedefine HAVE_WINSOCK2_H
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#define _WINSOCKAPI_
|
||||
#endif
|
||||
|
||||
*/
|
||||
#if _MSC_VER>=1900
|
||||
#define STDC99
|
||||
#endif
|
||||
@ -107,6 +107,10 @@ are set when opening a binary file on Windows. */
|
||||
/* set this only when building a DLL under MinGW */
|
||||
#cmakedefine DLL_NETCDF 1
|
||||
|
||||
/* if true, enable CDF5 Support */
|
||||
#cmakedefine ENABLE_CDF5 1
|
||||
#cmakedefine USE_CDF5 1
|
||||
|
||||
/* if true, build DAP2 and DAP4 Client */
|
||||
#cmakedefine ENABLE_DAP 1
|
||||
|
||||
@ -147,6 +151,9 @@ are set when opening a binary file on Windows. */
|
||||
/* Is CURLINFO_RESPONSE_CODE defined */
|
||||
#cmakedefine HAVE_CURLINFO_RESPONSE_CODE 1
|
||||
|
||||
/* Is CURLINFO_HTTP_CODE defined */
|
||||
#cmakedefine HAVE_CURLINFO_HTTP_CONNECTCODE 1
|
||||
|
||||
/* Is CURLOPT_CHUNK_BGN_FUNCTION defined */
|
||||
#cmakedefine HAVE_CURLOPT_CHUNK_BGN_FUNCTION 1
|
||||
|
||||
|
31
configure.ac
31
configure.ac
@ -441,6 +441,22 @@ AC_MSG_RESULT([$enable_dap_long_tests])
|
||||
|
||||
AM_CONDITIONAL(INTERNAL_OCLIB,[test "x" = "x"])
|
||||
|
||||
# Check whether we want to enable CDF5 support.
|
||||
AC_MSG_CHECKING([whether CDF5 support should be enabled (default off)])
|
||||
AC_ARG_ENABLE([cdf5],
|
||||
[AS_HELP_STRING([--enable-cdf5],
|
||||
[build with CDF5 support.])])
|
||||
test "x$enable_cdf5" = xyes || enable_cdf5=no
|
||||
AC_MSG_RESULT($enable_cdf5)
|
||||
|
||||
if test "x$enable_cdf5" = xyes; then
|
||||
AC_DEFINE([USE_CDF5], [1], [if true, enable CDF5 Support])
|
||||
AC_DEFINE([ENABLE_CDF5], [1], [if true, enable CDF5 Support])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(USE_CDF5, [test x$enable_cdf5 = xyes ])
|
||||
AM_CONDITIONAL(ENABLE_CDF5, [test x$enable_cdf5 = xyes ])
|
||||
|
||||
# Does the user want to do some extra tests?
|
||||
AC_MSG_CHECKING([whether netCDF extra tests should be run (developers only)])
|
||||
AC_ARG_ENABLE([extra-tests],
|
||||
@ -1000,11 +1016,15 @@ if test "x$enable_netcdf_4" = xyes; then
|
||||
fi
|
||||
|
||||
# The user may have built HDF5 with the SZLIB library.
|
||||
enable_szlib=no
|
||||
if test "x$ac_cv_func_H5Z_SZIP" = xyes; then
|
||||
AC_SEARCH_LIBS([SZ_Compress], [szip sz], [], [])
|
||||
enable_szlib=yes
|
||||
AC_SEARCH_LIBS([ SZ_Compress], [szip sz], [], [])
|
||||
AC_DEFINE([USE_SZIP], [1], [if true, compile in szip compression in netCDF-4 variables])
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test "x$ac_cv_func_H5free_memory" = xyes; then
|
||||
AC_DEFINE([HDF5_HAS_H5FREE], [1], [if true, H5free_memory() will be used to free hdf5-allocated memory in nc4file.])
|
||||
fi
|
||||
@ -1249,7 +1269,7 @@ AM_CONDITIONAL(USE_DAP, [test "x$enable_dap" = xyes]) # Alias
|
||||
# Provide protocol specific flags
|
||||
AM_CONDITIONAL(ENABLE_DAP, [test "x$enable_dap" = xyes])
|
||||
AM_CONDITIONAL(ENABLE_DAP4, [test "x$enable_dap4" = xyes])
|
||||
|
||||
AM_CONDITIONAL(ENABLE_CDF5, [test "x$enable_cdf5" = xyes])
|
||||
AM_CONDITIONAL(ENABLE_DAP_REMOTE_TESTS, [test "x$enable_dap_remote_tests" = xyes])
|
||||
AM_CONDITIONAL(ENABLE_DAP_AUTH_TESTS, [test "x$enable_dap_auth_tests" = xyes])
|
||||
AM_CONDITIONAL(ENABLE_DAP_LONG_TESTS, [test "x$enable_dap_long_tests" = xyes])
|
||||
@ -1374,14 +1394,16 @@ AM_CONDITIONAL(ENABLE_FILTER_TEST, [test x$enable_filter_test = xyes])
|
||||
|
||||
AC_SUBST(NC_LIBS,[$NC_LIBS])
|
||||
AC_SUBST(HAS_DAP,[$enable_dap])
|
||||
AC_SUBST(HAS_DAP2,[$enable_dap])
|
||||
AC_SUBST(HAS_DAP4,[$enable_dap4])
|
||||
AC_SUBST(HAS_NC2,[$nc_build_v2])
|
||||
AC_SUBST(HAS_NC4,[$enable_netcdf_4])
|
||||
AC_SUBST(HAS_CDF5,[$enable_cdf5])
|
||||
AC_SUBST(HAS_HDF4,[$enable_hdf4])
|
||||
AC_SUBST(HAS_PNETCDF,[$enable_pnetcdf])
|
||||
AC_SUBST(HAS_HDF5,[$enable_netcdf_4])
|
||||
AC_SUBST(HAS_LOGGING, [$enable_logging])
|
||||
AC_SUBST(HAS_SZLIB,[$ac_cv_func_H4Z_SZIP])
|
||||
AC_SUBST(HAS_SZLIB,[$enable_szlib])
|
||||
AC_SUBST(HAS_PARALLEL,[$enable_parallel])
|
||||
AC_SUBST(HAS_PARALLEL4,[$enable_parallel4])
|
||||
AC_SUBST(HAS_DISKLESS,[$enable_diskless])
|
||||
@ -1445,7 +1467,7 @@ AX_SET_META([NC_HAS_NC4],[$enable_netcdf_4],[yes])
|
||||
AX_SET_META([NC_HAS_HDF4],[$enable_hdf4],[yes])
|
||||
AX_SET_META([NC_HAS_HDF5],[$enable_netcdf_4],[yes])
|
||||
AX_SET_META([NC_HAS_SZIP],[$ac_cv_func_H5Z_SZIP],[yes])
|
||||
AX_SET_META([NC_HAS_DAP],[$enable_dap],[yes])
|
||||
AX_SET_META([NC_HAS_DAP2],[$enable_dap],[yes])
|
||||
AX_SET_META([NC_HAS_DAP4],[$enable_dap4],[yes])
|
||||
AX_SET_META([NC_HAS_DISKLESS],[$enable_diskless],[yes])
|
||||
AX_SET_META([NC_HAS_MMAP],[$enable_mmap],[yes])
|
||||
@ -1453,6 +1475,7 @@ AX_SET_META([NC_HAS_JNA],[$enable_jna],[yes])
|
||||
AX_SET_META([NC_HAS_PNETCDF],[$enable_pnetcdf],[yes])
|
||||
AX_SET_META([NC_HAS_PARALLEL],[$enable_parallel],[yes])
|
||||
AX_SET_META([NC_HAS_PARALLEL4],[$enable_parallel4],[yes])
|
||||
AX_SET_META([NC_HAS_CDF5],[$enable_cdf5],[yes])
|
||||
|
||||
# Automake says that this is always run in top_builddir
|
||||
# and that srcdir is defined (== top_srcdir)
|
||||
|
@ -51,7 +51,7 @@ EXTRA_DIST = test_parse.sh test_meta.sh test_data.sh \
|
||||
test_raw.sh test_remote.sh test_hyrax.sh \
|
||||
d4test_common.sh \
|
||||
daptestfiles dmrtestfiles cdltestfiles nctestfiles \
|
||||
baseline baselineraw baselineremote
|
||||
baseline baselineraw baselineremote CMakeLists.txt
|
||||
|
||||
CLEANFILES = *.exe
|
||||
|
||||
|
@ -74,6 +74,6 @@ IF(ENABLE_DOXYGEN)
|
||||
|
||||
ENDIF(ENABLE_DOXYGEN)
|
||||
|
||||
SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} CMakeLists.txt Makefile.am netcdf.m4 DoxygenLayout.xml Doxyfile.in Doxyfile.guide.in footer.html mainpage.dox tutorial.dox dispatch.dox guide.dox types.dox notes.md cdl.dox architecture.dox internal.dox install-fortran.dox Doxyfile.in.cmake windows-binaries.md building-with-cmake.md install.md)
|
||||
SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST} CMakeLists.txt Makefile.am netcdf.m4 DoxygenLayout.xml Doxyfile.in Doxyfile.guide.in footer.html mainpage.dox tutorial.dox guide.dox types.dox notes.md cdl.dox architecture.dox internal.dox install-fortran.dox Doxyfile.in.cmake windows-binaries.md building-with-cmake.md install.md)
|
||||
|
||||
ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
|
||||
|
@ -748,7 +748,6 @@ INPUT = \
|
||||
@abs_top_srcdir@/RELEASE_NOTES.md \
|
||||
@abs_top_srcdir@/docs/install.md \
|
||||
@abs_top_srcdir@/docs/install-fortran.md \
|
||||
@abs_top_srcdir@/docs/dispatch.dox \
|
||||
@abs_top_srcdir@/docs/types.dox \
|
||||
@abs_top_srcdir@/docs/internal.dox \
|
||||
@abs_top_srcdir@/docs/windows-binaries.md \
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
# These files will be included with the dist.
|
||||
EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html \
|
||||
mainpage.dox tutorial.dox dispatch.dox \
|
||||
mainpage.dox tutorial.dox \
|
||||
guide.dox types.dox cdl.dox \
|
||||
architecture.dox internal.dox windows-binaries.md \
|
||||
building-with-cmake.md CMakeLists.txt \
|
||||
|
@ -25,11 +25,14 @@ It is strongly recommended that applicable conventions be followed unless there
|
||||
|
||||
<p>
|
||||
|
||||
> It is not necessary to define your own _FillValue attribute for a variable if the default fill value for the type of the variable is adequate. However, use of the default fill value for data type byte is not recommended. Note that if you change the value of this attribute, the changed value applies only to subsequent writes; previously written data are not changed.
|
||||
> If _FillValue is undefined, it is assumed that there are no unwritten data-values. Generic applications needing to write a value to represent undefined or missing values may use either `_FillValue` or `missing_value` for this purpose. It is legal (but not recommended) for the fill value to be within the valid range of the data.
|
||||
|
||||
<p>
|
||||
|
||||
> Generic applications often need to write a value to represent undefined or missing values. The fill value provides an appropriate value for this purpose because it is normally outside the valid range and therefore treated as missing when read by generic applications. It is legal (but not recommended) for the fill value to be within the valid range.
|
||||
> Generic applications often need to write a value to represent undefined or missing values. The fill value provides an appropriate value for this purpose because it is normally outside the valid range and therefore treated as missing when read by generic applications. It is legal (but not recommended) for the fill value to be within the valid range.
|
||||
|
||||
> **Note that if you change the value of this attribute, the changed value applies only to subsequent writes; previously written data are not changed.**
|
||||
|
||||
|
||||
`missing_value`
|
||||
|
||||
@ -183,4 +186,3 @@ Using the following API calls will fail.
|
||||
> The type of this attribute is NC_INT.
|
||||
|
||||
> This attribute is computed by using the HDF5 API to walk the file to look for attributes specific to netcdf-4. False negatives are possible for a small subset of netcdf-4 files, especially those not containing dimensions. False positives are only possible by deliberate modifications to an existing HDF5 file thru the HDF5 API. For files with the _NCProperties attribute, this attribute is redundant. For files created prior to the introduction of the _NCProperties attribute, this may be a useful indicator of the provenance of the file.
|
||||
|
||||
|
179
docs/auth.md
179
docs/auth.md
@ -1,5 +1,5 @@
|
||||
netCDF Authorization Support
|
||||
============================
|
||||
======================================
|
||||
<!-- double header is needed to workaround doxygen bug -->
|
||||
|
||||
# netCDF Authorization Support {#Header}
|
||||
@ -37,29 +37,92 @@ directly insert the username and the password into a url in this form.
|
||||
This username and password will be used if the server asks for
|
||||
authentication. Note that only simple password authentication
|
||||
is supported in this format.
|
||||
|
||||
Specifically note that [redirection-based](#REDIR)
|
||||
authorization will not work with this because the username and password
|
||||
will only be used on the initial request, not the redirection
|
||||
authorization may work with this but it is a security risk.
|
||||
This is because the username and password
|
||||
may be sent to each server in the redirection chain.
|
||||
|
||||
Note also that the `user:password` form may contain characters that must be
|
||||
escaped. See the <a href="#USERPWDESCAPE">password escaping</a> section to see
|
||||
how to properly escape the user and password.
|
||||
|
||||
## RC File Authentication {#DODSRC}
|
||||
The netcdf library supports an _rc_ file mechanism to allow the passing
|
||||
of a number of parameters to libnetcdf and libcurl.
|
||||
Locating the _rc_ file is a multi-step process.
|
||||
|
||||
### Search Order
|
||||
|
||||
The file must be called one of the following names:
|
||||
".daprc" or ".dodsrc".
|
||||
If both ".daprc" and ".dodsrc" exist, then
|
||||
the ".daprc" file will take precedence.
|
||||
|
||||
The rc file is searched for first in the current directory
|
||||
and then in the home directory (as defined by the HOME environment
|
||||
variable).
|
||||
It is strongly suggested that you pick one of the two names
|
||||
and use it always. Otherwise you may observe unexpected results
|
||||
when the netcdf-c library finds one that you did not intend.
|
||||
|
||||
The search for an _rc_ file looks in the following places in this order.
|
||||
|
||||
1. Check for the environment variable named _DAPRCFILE_.
|
||||
This will specify the full path for the _rc_ file
|
||||
(not just the containing directory).
|
||||
2. Search the current working directory (`./`) looking
|
||||
for (in order) .daprc or .dodsrc.
|
||||
3. Search the HOME directory (`$HOME`) looking
|
||||
for (in order) .daprc or .dodsrc. The HOME environment
|
||||
variable is used to define the directory in which to search.
|
||||
|
||||
It is strongly suggested that you pick a uniform location
|
||||
and use it always. Otherwise you may observe unexpected results
|
||||
when the netcdf-c library get an rc file you did not expect.
|
||||
|
||||
### RC File Format
|
||||
|
||||
The rc file format is a series of lines of the general form:
|
||||
|
||||
[<host:port>]<key>=<value>
|
||||
|
||||
where the bracket-enclosed host:port is optional and will be discussed
|
||||
subsequently.
|
||||
where the bracket-enclosed host:port is optional.
|
||||
|
||||
### URL Constrained RC File Entries
|
||||
|
||||
Each line of the rc file can begin with
|
||||
a host+port enclosed in square brackets.
|
||||
The form is "host:port".
|
||||
If the port is not specified
|
||||
then the form is just "host".
|
||||
The reason that more of the url is not used is that
|
||||
libcurl's authorization grain is not any finer than host level.
|
||||
|
||||
Examples.
|
||||
|
||||
[remotetest.unidata.ucar.edu]HTTP.VERBOSE=1
|
||||
|
||||
or
|
||||
|
||||
[fake.ucar.edu:9090]HTTP.VERBOSE=0
|
||||
|
||||
If the url request from, say, the _netcdf_open_ method
|
||||
has a host+port matching one of the prefixes in the rc file, then
|
||||
the corresponding entry will be used, otherwise ignored.
|
||||
This means that an entry with a matching host+port will take
|
||||
precedence over an entry without a host+port.
|
||||
|
||||
For example, the URL
|
||||
|
||||
http://remotetest.unidata.ucar.edu/thredds/dodsC/testdata/testData.nc
|
||||
|
||||
will have HTTP.VERBOSE set to 1 because its host matches the example above.
|
||||
|
||||
Similarly,
|
||||
|
||||
http://fake.ucar.edu:9090/dts/test.01
|
||||
|
||||
will have HTTP.VERBOSE set to 0 because its host+port matches the example above.
|
||||
|
||||
## Authorization-Related Keys {#AUTHKEYS}
|
||||
|
||||
The currently defined set of authorization-related keys are as follows.
|
||||
The second column is the affected curl_easy_setopt option(s), if any.
|
||||
@ -71,12 +134,12 @@ The second column is the affected curl_easy_setopt option(s), if any.
|
||||
<tr><td>HTTP.SSL.CERTIFICATE</td><td>CURLOPT_SSLCERT</td>
|
||||
<tr><td>HTTP.SSL.KEY</td><td>CURLOPT_SSLKEY</td>
|
||||
<tr><td>HTTP.SSL.KEYPASSWORD</td><td>CURLOPT_KEYPASSWORD</td>
|
||||
<tr><td>HTTP.SSL.CAINFO</td><td>CURLOPT_SSLCAINFO</td>
|
||||
<tr><td>HTTP.SSL.CAPATH</td><td>CURLOPT_SSLCAPATH</td>
|
||||
<tr><td>HTTP.SSL.CAINFO</td><td>CURLOPT_CAINFO</td>
|
||||
<tr><td>HTTP.SSL.CAPATH</td><td>CURLOPT_CAPATH</td>
|
||||
<tr><td>HTTP.SSL.VERIFYPEER</td><td>CURLOPT_SSL_VERIFYPEER</td>
|
||||
<tr><td>HTTP.SSL.VALIDATE</td><td>CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST</td>
|
||||
<tr><td>HTTP.CREDENTIALS.USERPASSWORD</td><td>CURLOPT_USERPASSWORD</td>
|
||||
<tr><td>HTTP.NETRC</td><td>N.A.</td><td>Specify path of the .netrc file</td>
|
||||
<tr><td>HTTP.NETRC</td><td>CURLOPT_NETRC,CURLOPT_NETRC_FILE</td>
|
||||
</table>
|
||||
|
||||
### Password Authentication
|
||||
@ -86,7 +149,9 @@ HTTP.CREDENTIALS.USERPASSWORD
|
||||
can be used to set the simple password authentication.
|
||||
This is an alternative to setting it in the url.
|
||||
The value must be of the form "username:password".
|
||||
See <a href="#REDIR">redirection authorization</a>
|
||||
See the <a href="#USERPWDESCAPE">password escaping</a> section
|
||||
to see how this value must escape certain characters.
|
||||
Also see <a href="#REDIR">redirection authorization</a>
|
||||
for important additional information.
|
||||
|
||||
### Cookie Jar
|
||||
@ -129,6 +194,29 @@ specifies the absolute path of the .netrc file.
|
||||
See [redirection authorization](#REDIR)
|
||||
for information about using .netrc.
|
||||
|
||||
## Password Escaping {#USERPWDESCAPE}
|
||||
|
||||
With current password rules, it is is not unlikely that the password
|
||||
will contain characters that need to be escaped. Similarly, the user
|
||||
may contain characters such as '@' that need to be escaped. To support this,
|
||||
it is assumed that all occurrences of `user:password` use URL (i.e. %%XX)
|
||||
escaping for at least the characters in the table below.
|
||||
|
||||
The minimum set of characters that must be escaped depends on the location.
|
||||
If the user+pwd is embedded in the URL, then '@' and ':' __must__ be escaped.
|
||||
If the user+pwd is the value for
|
||||
the HTTP.CREDENTIALS.USERPASSWORD key in the _rc_ file, then
|
||||
':' __must__ be escaped.
|
||||
Escaping should __not__ be used in the `.netrc` file.
|
||||
|
||||
The relevant escape codes are as follows.
|
||||
<table>
|
||||
<tr><th>Character</th><th>Escaped Form</th>
|
||||
<tr><td>'@'</td><td>%40</td>
|
||||
<tr><td>':'</td><td>%3a</td>
|
||||
</table>
|
||||
Additional characters can be escaped if desired.
|
||||
|
||||
## Redirection-Based Authentication {#REDIR}
|
||||
|
||||
Some sites provide authentication by using a third party site
|
||||
@ -145,16 +233,18 @@ using the _https_ protocol (note the use of _https_ instead of _http_).
|
||||
4. URS sends a redirect (with authorization information) to send
|
||||
the client back to the SOI to actually obtain the data.
|
||||
|
||||
It turns out that libcurl uses the password in the `.daprc`
|
||||
file (or from the url)
|
||||
only for the initial connection. This causes problems because
|
||||
the redirected connection is the one that actually requires the password.
|
||||
This is where the `.netrc` file comes in. Libcurl will use `.netrc` for
|
||||
the redirected connection. It is possible to cause libcurl to use
|
||||
the `.daprc` password always, but this introduces a security hole
|
||||
because it may send the initial user+pwd to the redirection site.
|
||||
In summary, if you are using redirection, then you must create a `.netrc`
|
||||
file to hold the password for the site to which the redirection is sent.
|
||||
It turns out that libcurl, by default, uses the password in the
|
||||
`.daprc` file (or from the url) for all connections that request
|
||||
a password. This causes problems because only the the specific
|
||||
redirected connection is the one that actually requires the password.
|
||||
This is where the `.netrc` file comes in. Libcurl will use `.netrc`
|
||||
for the redirected connection. It is possible to cause libcurl
|
||||
to use the `.daprc` password always, but this introduces a
|
||||
security hole because it may send the initial user+pwd to every
|
||||
server in the redirection chain.
|
||||
In summary, if you are using redirection, then you are
|
||||
''strongly'' encouraged to create a `.netrc` file to hold the
|
||||
password for the site to which the redirection is sent.
|
||||
|
||||
The format of this `.netrc` file will contain lines that
|
||||
typically look like this.
|
||||
@ -165,52 +255,19 @@ where the machine, mmmmmm, is the hostname of the machine to
|
||||
which the client is redirected for authorization, and the
|
||||
login and password are those needed to authenticate on that machine.
|
||||
|
||||
The `.netrc` file can be specified by
|
||||
The location of the `.netrc` file can be specified by
|
||||
putting the following line in your `.daprc`/`.dodsrc` file.
|
||||
|
||||
HTTP.NETRC=<path to netrc file>
|
||||
|
||||
If not specified, then libcurl will look first in the current
|
||||
directory, and then in the HOME directory.
|
||||
|
||||
One final note. In using this, you MUST
|
||||
to specify a real file in the file system to act as the
|
||||
cookie jar file (HTTP.COOKIEJAR) so that the
|
||||
redirect site can properly pass back authorization information.
|
||||
|
||||
## URL Constrained RC File Entries {#URLCONS}
|
||||
|
||||
Each line of the rc file can begin with
|
||||
a host+port enclosed in square brackets.
|
||||
The form is "host:port".
|
||||
If the port is not specified
|
||||
then the form is just "host".
|
||||
The reason that more of the url is not used is that
|
||||
libcurl's authorization grain is not any finer than host level.
|
||||
|
||||
Examples.
|
||||
|
||||
[remotetest.unidata.ucar.edu]HTTP.VERBOSE=1
|
||||
|
||||
or
|
||||
|
||||
[fake.ucar.edu:9090]HTTP.VERBOSE=0
|
||||
|
||||
If the url request from, say, the _netcdf_open_ method
|
||||
has a host+port matching one of the prefixes in the rc file, then
|
||||
the corresponding entry will be used, otherwise ignored.
|
||||
This means that an entry with a matching host+port will take
|
||||
precedence over an entry without a host+port.
|
||||
|
||||
For example, the URL
|
||||
|
||||
http://remotetest.unidata.ucar.edu/thredds/dodsC/testdata/testData.nc
|
||||
|
||||
will have HTTP.VERBOSE set to 1 because its host matches the example above.
|
||||
|
||||
Similarly,
|
||||
|
||||
http://fake.ucar.edu:9090/dts/test.01
|
||||
|
||||
will have HTTP.VERBOSE set to 0 because its host+port matches the example above.
|
||||
|
||||
## Client-Side Certificates {#CLIENTCERTS}
|
||||
|
||||
Some systems, notably ESG (Earth System Grid), requires
|
||||
@ -244,8 +301,8 @@ the code is definitive.
|
||||
<tr><td>HTTP.SSL.CERTIFICATE</td><td>CUROPT_SSLCERT</td>
|
||||
<tr><td>HTTP.SSL.KEY</td><td>CUROPT_SSLKEY</td>
|
||||
<tr><td>HTTP.SSL.KEYPASSWORD</td><td>CUROPT_KEYPASSWORD</td>
|
||||
<tr><td>HTTP.SSL.CAINFO</td><td>CUROPT_SSLCAINFO</td>
|
||||
<tr><td>HTTP.SSL.CAPATH</td><td>CUROPT_SSLCAPATH</td>
|
||||
<tr><td>HTTP.SSL.CAINFO</td><td>CUROPT_CAINFO</td>
|
||||
<tr><td>HTTP.SSL.CAPATH</td><td>CUROPT_CAPATH</td>
|
||||
<tr><td>HTTP.SSL.VERIFYPEER</td><td>CUROPT_SSL_VERIFYPEER</td>
|
||||
<tr><td>HTTP.CREDENTIALS.USERPASSWORD</td><td>CUROPT_USERPASSWORD</td>
|
||||
<tr><td>HTTP.NETRC</td><td>CURLOPT_NETRC,CURLOPT_NETRC_FILE</td>
|
||||
|
142
docs/filters.md
142
docs/filters.md
@ -66,16 +66,42 @@ using __ncgen__, via an API call, or via command line parameters to __nccopy__.
|
||||
In any case, remember that filtering also requires setting chunking, so the
|
||||
variable must also be marked with chunking information.
|
||||
|
||||
Using The API {#API}
|
||||
-------------
|
||||
The necessary API methods are included in __netcdf.h__ by default.
|
||||
One API method is for setting the filter to be used
|
||||
when writing a variable. The relevant signature is
|
||||
as follows.
|
||||
````
|
||||
int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
|
||||
````
|
||||
This must be invoked after the variable has been created and before
|
||||
__nc_enddef__ is invoked.
|
||||
|
||||
A second API methods makes it possible to query a variable to
|
||||
obtain information about any associated filter using this signature.
|
||||
````
|
||||
int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
|
||||
|
||||
````
|
||||
The filter id wil be returned in the __idp__ argument (if non-NULL),
|
||||
the number of parameters in __nparamsp__ and the actual parameters in
|
||||
__params__. As is usual with the netcdf API, one is expected to call
|
||||
this function twice. The first time to get __nparams__ and the
|
||||
second to get the parameters in client-allocated memory.
|
||||
|
||||
Using ncgen {#NCGEN}
|
||||
-------------
|
||||
|
||||
In a CDL file, compression of a variable can be specified
|
||||
by annotating it with the following attribute:
|
||||
|
||||
1. ''_Filter'' -- a string containing a comma separated list of
|
||||
unsigned integers specifying (1) the filter id to apply, and (2)
|
||||
a vector of unsigned integers representing the
|
||||
* ''_Filter'' -- a string containing a comma separated list of
|
||||
constants specifying (1) the filter id to apply, and (2)
|
||||
a vector of constants representing the
|
||||
parameters for controlling the operation of the specified filter.
|
||||
See the section on the <a href="#Syntax">parameter encoding syntax</a>
|
||||
for the details on the allowable kinds of constants.
|
||||
|
||||
This is a "special" attribute, which means that
|
||||
it will normally be invisible when using
|
||||
@ -97,30 +123,6 @@ data:
|
||||
}
|
||||
````
|
||||
|
||||
Using The API {#API}
|
||||
-------------
|
||||
The include file, __netcdf_filter.h__ defines
|
||||
an API method for setting the filter to be used
|
||||
when writing a variable. The relevant signature is
|
||||
as follows.
|
||||
````
|
||||
int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
|
||||
````
|
||||
This must be invoked after the variable has been created and before
|
||||
__nc_enddef__ is invoked.
|
||||
|
||||
It is also possible to query a variable to obtain information about
|
||||
any associated filter using this signature.
|
||||
````
|
||||
int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
|
||||
|
||||
````
|
||||
The filter id wil be returned in the __idp__ argument (if non-NULL),
|
||||
the number of parameters in __nparamsp__ and the actual parameters in
|
||||
__params__. As is usual with the netcdf API, one is expected to call
|
||||
this function twice. The first time to get __nparams__ and the
|
||||
second to get the parameters in client-allocated memory.
|
||||
|
||||
Using nccopy {#NCCOPY}
|
||||
-------------
|
||||
When copying a netcdf file using __nccopy__ it is possible
|
||||
@ -133,6 +135,8 @@ Assume that __unfiltered.nc__ has a chunked but not bzip2 compressed
|
||||
variable named "var". This command will create that variable in
|
||||
the __filtered.nc__ output file but using filter with id 307
|
||||
(i.e. bzip2) and with parameter(s) 9 indicating the compression level.
|
||||
See the section on the <a href="#Syntax">parameter encoding syntax</a>
|
||||
for the details on the allowable kinds of constants.
|
||||
|
||||
The "-F" option can be used repeatedly as long as the variable name
|
||||
part is different. A different filter id and parameters can be
|
||||
@ -146,7 +150,7 @@ the netcdf-c library.
|
||||
Parameter Encoding {#ParamEncode}
|
||||
==========
|
||||
|
||||
The parameters passed to a filter are encoded in a vector
|
||||
The parameters passed to a filter are encoded internally as a vector
|
||||
of 32-bit unsigned integers. It may be that the parameters
|
||||
required by a filter can naturally be encoded as unsigned integers.
|
||||
The bzip2 compression filter, for example, expects a single
|
||||
@ -210,6 +214,51 @@ byte order (big-endian) so that the filter always assumes it is getting
|
||||
its parameters in network order and will always do swapping as needed.
|
||||
This is irritating, but one needs to be aware of it.
|
||||
|
||||
Filter Specification Syntax {#Syntax}
|
||||
==========
|
||||
|
||||
Both of the utilities
|
||||
<a href="#NCGEN">__ncgen__</a>
|
||||
and
|
||||
<a href="#NCCOPY">__nccopy__</a>
|
||||
allow the specification of filter parameters.
|
||||
These specifications consist of a sequence of comma
|
||||
separated constants. The constants are converted
|
||||
within the utility to a proper set of unsigned int
|
||||
constants (see the <a href="#ParamEncode">parameter encoding section</a>).
|
||||
|
||||
To simplify things, various kinds of constants can be specified
|
||||
rather than just simple unsigned integers. The utilities will encode
|
||||
them properly using the rules specified in
|
||||
the <a href="#ParamEncode">parameter encoding section</a>.
|
||||
|
||||
The currently supported constants are as follows.
|
||||
<table>
|
||||
<tr halign="center"><th>Example<th>Type<th>Format Tag<th>Notes
|
||||
<tr><td>-17b<td>signed 8-bit byte<td>b|B<td>
|
||||
<tr><td>23ub<td>unsigned 8-bit byte<td>u|U b|B<td>
|
||||
<tr><td>-25S<td>signed 16-bit short<td>s|S<td>
|
||||
<tr><td>27US<td>unsigned 16-bit short<td>u|U s|S<td>
|
||||
<tr><td>-77<td>implicit signed 32-bit integer<td>Leading minus sign and no tag<td>
|
||||
<tr><td>77<td>implicit unsigned 32-bit integer<td>No tag<td>
|
||||
<tr><td>93U<td>explicit unsigned 32-bit integer<td>u|U<td>
|
||||
<tr><td>789f<td>32-bit float<td>f|F<td>
|
||||
<tr><td>12345678.12345678d<td>64-bit double<td>d|D<td>Network byte order
|
||||
<tr><td>-9223372036854775807L<td>64-bit signed long long<td>l|L<td>Network byte order
|
||||
<tr><td>18446744073709551615UL<td>64-bit unsigned long long<td>u|U l|L<td>Network byte order
|
||||
</table>
|
||||
Some things to note.
|
||||
|
||||
1. In all cases, except for an untagged positive integer,
|
||||
the format tag is required and determines how the constant
|
||||
is converted to one or two unsigned int values.
|
||||
The positive integer case is for backward compatibility.
|
||||
2. For signed byte and short, the value is sign extended to 32 bits
|
||||
and then treated as an unsigned int value.
|
||||
3. For double, and signed|unsigned long long, they are converted
|
||||
to network byte order and then treated as two unsigned int values.
|
||||
This is consistent with the <a href="#ParamEncode">parameter encoding</a>.
|
||||
|
||||
Dynamic Loading Process {#Process}
|
||||
==========
|
||||
|
||||
@ -297,6 +346,43 @@ non-standard platform.
|
||||
Although it is fragile, this test can serve as a complete example for building
|
||||
plugins for other filters.
|
||||
|
||||
Appendix A. Byte Swap Code {#AppendixA}
|
||||
==========
|
||||
Since in some cases, it is necessary for a filter to
|
||||
byte swap from network byte order to little endian, This appendix
|
||||
provides sample code for doing this. It also provides
|
||||
a code snippet for testing if the machine is big-endian.
|
||||
|
||||
Byte swap an 8-byte chunk of memory
|
||||
-------
|
||||
````
|
||||
static void
|
||||
byteswap8(unsigned char* mem)
|
||||
{
|
||||
unsigned char c;
|
||||
c = mem[0];
|
||||
mem[0] = mem[7];
|
||||
mem[7] = c;
|
||||
c = mem[1];
|
||||
mem[1] = mem[6];
|
||||
mem[6] = c;
|
||||
c = mem[2];
|
||||
mem[2] = mem[5];
|
||||
mem[5] = c;
|
||||
c = mem[3];
|
||||
mem[3] = mem[4];
|
||||
mem[4] = c;
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
Test for Big-Endian Machine
|
||||
-------
|
||||
````
|
||||
static const unsigned char b[4] = {0x0,0x0,0x0,0x1}; /* value 1 in big-endian*/
|
||||
int bigendian = (1 == *(unsigned int*)b);
|
||||
````
|
||||
|
||||
References {#References}
|
||||
==========
|
||||
|
||||
|
@ -6,24 +6,32 @@
|
||||
|
||||
This document describes the architecture and details of the netCDF
|
||||
internal dispatch mechanism. The idea is that when a user opens or
|
||||
creates a netcdf file, a specific dispatch table is
|
||||
chosen. Subsequent netcdf API calls are then channeled through that
|
||||
creates a netcdf file, a specific dispatch table is chosen.
|
||||
A dispatch table is a struct containing an entry for every function
|
||||
in the netcdf-c API.
|
||||
Subsequent netcdf API calls are then channeled through that
|
||||
dispatch table to the appropriate function for implementing that API
|
||||
call.
|
||||
call. The functions in the dispatch table are not quite the same
|
||||
as those defined in netcdf.h. For simplicity and compactness,
|
||||
some netcdf.h API calls are
|
||||
mapped to the same dispatch table function. In addition to
|
||||
the functions, the first entry in the table defines the model
|
||||
that this dispatch table implements. It will be one of the
|
||||
NC_FORMATX_XXX values.
|
||||
|
||||
At least the following dispatch tables are supported.
|
||||
The list of supported dispatch tables will grow over time.
|
||||
To date, at least the following dispatch tables are supported.
|
||||
- netcdf classic files (netcdf-3)
|
||||
- netcdf enhanced files (netcdf-4)
|
||||
- OPeNDAP to netcdf-3
|
||||
- OPeNDAP to netcdf-4
|
||||
- DAP2 to netcdf-3
|
||||
- DAP4 to netcdf-4
|
||||
- pnetcdf (parallel cdf5)
|
||||
|
||||
Internal Dispatch Tables
|
||||
- \subpage adding_dispatch
|
||||
- \subpage dispatch_notes
|
||||
- \subpage put_vara_dispatch
|
||||
- \subpage put_attr_dispatch
|
||||
|
||||
|
||||
The dispatch table represents a distillation of the netcdf API down to
|
||||
a minimal set of internal operations. The format of the dispatch table
|
||||
is defined in the file libdispatch/ncdispatch.h. Every new dispatch
|
||||
@ -36,12 +44,15 @@ table must define this minimal set of operations.
|
||||
In order to make this process concrete, let us assume we plan to add
|
||||
an in-memory implementation of netcdf-3.
|
||||
|
||||
\section dispatch_step1 Step 1.
|
||||
\section dispatch_configure_ac Defining configure.ac flags
|
||||
|
||||
Define a –enable flag and an AM_CONFIGURE flag in configure.ac. We
|
||||
will use the flags –enable-netcdfm and USE_NETCDFM respectively.
|
||||
Define a –-enable flag and an AM_CONFIGURE flag in configure.ac.
|
||||
For our example, we assume the option "--enable-ncm" and the AM_CONFIGURE
|
||||
flag "ENABLE_NCM". If you examine the existing configure.ac and see how,
|
||||
for example, dap2 is defined, then it should be clear how to do it for
|
||||
your code.
|
||||
|
||||
\section dispatch_step2 Step 2.
|
||||
\section dispatch_namespace Defining a "name space"
|
||||
|
||||
Choose some prefix of characters to identify the new dispatch
|
||||
system. In effect we are defining a name-space. For our in-memory
|
||||
@ -49,94 +60,66 @@ system, we will choose "NCM" and "ncm". NCM is used for non-static
|
||||
procedures to be entered into the dispatch table and ncm for all other
|
||||
non-static procedures.
|
||||
|
||||
\section dispatch_step3 Step 3.
|
||||
\section dispatch_netcdf_h Extend include/netcdf.h
|
||||
|
||||
Modify file libdispatch/ncdispatch.h as follows.
|
||||
|
||||
Add a index for this implementation:
|
||||
Modify file include/netcdf.h to add an NC_FORMATX_XXX flag
|
||||
by adding a flag for this dispatch format at the appropriate places.
|
||||
|
||||
\code
|
||||
#define NC_DISPATCH_NCM 5
|
||||
#define NC_FORMATX_NCM 7
|
||||
\endcode
|
||||
|
||||
Define an external reference to the in-memory dispatch table.
|
||||
Add any format specific new error codes.
|
||||
|
||||
\code
|
||||
#ifdef USE_NETCDFM
|
||||
#define NC_ENCM (?)
|
||||
\endcode
|
||||
|
||||
\section dispatch_ncdispatch Extend include/ncdispatch.h
|
||||
|
||||
Modify file include/ncdispatch.h as follows.
|
||||
|
||||
Add format specific data and functions; note the of our NCM namespace.
|
||||
|
||||
\code
|
||||
#ifdef ENABLE_NCM
|
||||
extern NC_Dispatch* NCM_dispatch_table;
|
||||
extern int NCM_initialize(void);
|
||||
#endif
|
||||
\endcode
|
||||
|
||||
\section dispatch_step4 Step 4.
|
||||
|
||||
Modify file libdispatch/netcdf.c as follows.
|
||||
|
||||
Add a ptr to the in-memory dispatch table.
|
||||
|
||||
\code
|
||||
#ifdef USE_NETCDFM
|
||||
NC_Dispatch* NCM_dispatch_table = NULL;
|
||||
#endif
|
||||
\endcode
|
||||
|
||||
Add includes for any necessary header files as needed.
|
||||
|
||||
\section dispatch_step5 Step 5.
|
||||
\section dispatch_define_code Define the dispatch table functions
|
||||
|
||||
Define the functions necessary to fill in the dispatch table. As a
|
||||
rule, we assume that a new directory is defined, libsrcm, say. Within
|
||||
this directory, we need to define Makefile.am, the source files
|
||||
this directory, we need to define Makefile.am and CMakeLists.txt.
|
||||
We also need to define the source files
|
||||
containing the dispatch table and the functions to be placed in the
|
||||
dispatch table – call them ncmdispatch.c and ncmdispatch.h. Look at
|
||||
libsrc/nc3dispatch.[ch] for an example.
|
||||
libsrc/nc3dispatch.[ch] or libdap4/ncd4dispatch.[ch] for examples.
|
||||
|
||||
As part of the ncmdispatch.c file, you must define the following.
|
||||
Similarly, it is best to take existing Makefile.am and CMakeLists.txt
|
||||
files (from libdap4 for example) and modify them.
|
||||
|
||||
\code
|
||||
NC_Dispatch NCM_dispatcher = {
|
||||
NC_DISPATCH_NCM,
|
||||
NCM_create,
|
||||
NCM_open,
|
||||
...
|
||||
};
|
||||
|
||||
int
|
||||
NCM_initialize(void)
|
||||
{
|
||||
NCM_dispatch_table = &NCM_dispatcher;
|
||||
return NC_NOERR;
|
||||
}
|
||||
\endcode
|
||||
|
||||
Assuming that the in-memory library does not require any external
|
||||
libraries, then the Makefile.am will look something like this.
|
||||
|
||||
\code
|
||||
NCM_SOURCES = ncmdispatch.c ncmdispatch.h ...
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/libsrc -I$(top_srcdir)/libdispatch
|
||||
libnetcdfm_la_SOURCES = $(NCM_SOURCES)
|
||||
noinst_LTLIBRARIES = libnetcdfm.la
|
||||
\endcode
|
||||
|
||||
\section dispatch_step6 Step 6.
|
||||
\section dispatch_lib Adding the dispatch code to libnetcdf
|
||||
|
||||
Provide for the inclusion of this library in the final libnetcdf
|
||||
library. This is accomplished by modifying liblib/Makefile.am by
|
||||
adding something like the following.
|
||||
|
||||
\code
|
||||
if USE_NETCDFM
|
||||
if ENABLE_NCM
|
||||
libnetcdf_la_LIBADD += $(top_builddir)/libsrcm/libnetcdfm.la
|
||||
endif
|
||||
\endcode
|
||||
|
||||
\section dispatch_step7 Step 7.
|
||||
\section dispatch_init Extend library initialization
|
||||
|
||||
Modify the NC_initialize function in liblib/stub.c by adding
|
||||
Modify the NC_initialize function in liblib/nc_initialize.c by adding
|
||||
appropriate references to the NCM dispatch function.
|
||||
|
||||
\code
|
||||
#ifdef USE_NETCDFM
|
||||
#ifdef ENABLE_NCM
|
||||
extern int NCM_initialize(void);
|
||||
#endif
|
||||
...
|
||||
@ -150,7 +133,7 @@ appropriate references to the NCM dispatch function.
|
||||
}
|
||||
\endcode
|
||||
|
||||
\section dispatch_step8 Step 8.
|
||||
\section dispatch_tests Testing the new dispatch table
|
||||
|
||||
Add a directory of tests; ncm_test, say. The file ncm_test/Makefile.am
|
||||
will look something like this.
|
||||
@ -169,13 +152,13 @@ will look something like this.
|
||||
EXTRA_DIST = ...
|
||||
\endcode
|
||||
|
||||
\section dispatch_step9 Step 9.
|
||||
\section dispatch_toplevel Top-Level build of the dispatch code
|
||||
|
||||
Provide for libnetcdfm to be constructed by adding the following to
|
||||
the top-level Makefile.am.
|
||||
|
||||
\code
|
||||
if USE_NETCDFM
|
||||
if ENABLE_NCM
|
||||
NCM=libsrcm
|
||||
NCMTESTDIR=ncm_test
|
||||
endif
|
||||
@ -186,29 +169,27 @@ the top-level Makefile.am.
|
||||
\section choosing_dispatch_table Choosing a Dispatch Table
|
||||
|
||||
The dispatch table is chosen in the NC_create and the NC_open
|
||||
procedures in libdispatch/netcdf.c. The decision is currently based on
|
||||
the following pieces of information.
|
||||
procedures in libdispatch/netcdf.c.
|
||||
This can be, unfortunately, a complex process.
|
||||
|
||||
The file path – this can be used to detect, for example, a DAP url
|
||||
versus a normal file system file.
|
||||
The decision is currently based on the following pieces of information.
|
||||
Using a mode flag is the most common mechanism, in which case
|
||||
netcdf.h needs to be modified to define the relevant mode flag.
|
||||
|
||||
The mode argument – this can be used to detect, for example, what kind
|
||||
1. The mode argument – this can be used to detect, for example, what kind
|
||||
of file to create: netcdf-3, netcdf-4, 64-bit netcdf-3, etc. For
|
||||
nc_open and when the file path references a real file, the contents of
|
||||
the file can also be used to determine the dispatch table. Although
|
||||
currently not used, this code could be modified to also use other
|
||||
pieces of information such as environment variables.
|
||||
|
||||
In addition to the above, there is one additional mechanism to force
|
||||
the use of a specific dispatch table. The procedure
|
||||
"NC_set_dispatch_override()" can be invoked to specify a dispatch
|
||||
table.
|
||||
2. The file path – this can be used to detect, for example, a DAP url
|
||||
versus a normal file system file.
|
||||
|
||||
When adding a new dispatcher, it is necessary to modify NC_create and
|
||||
NC_open in libdispatch/netcdf.c to detect when it is appropriate to
|
||||
NC_open in libdispatch/dfile.c to detect when it is appropriate to
|
||||
use the NCM dispatcher. Some possibilities are as follows.
|
||||
- Add a new mode flag: say NC_NETCDFM.
|
||||
- Use an environment variable.
|
||||
- Define a special file path format that indicates the need to use a
|
||||
special dispatch table.
|
||||
|
||||
@ -217,65 +198,35 @@ use the NCM dispatcher. Some possibilities are as follows.
|
||||
Several of the entries in the dispatch table are significantly
|
||||
different than those of the external API.
|
||||
|
||||
\section create_open_dispatch Create/Open
|
||||
\subsection create_open_dispatch Create/Open
|
||||
|
||||
The create table entry and the open table entry have the following
|
||||
signatures respectively.
|
||||
The create table entry and the open table entry in the dispatch table
|
||||
have the following signatures respectively.
|
||||
|
||||
\code
|
||||
int (*create)(const char *path, int cmode,
|
||||
size_t initialsz, int basepe, size_t *chunksizehintp,
|
||||
int useparallel, MPI_Comm comm, MPI_Info info,
|
||||
struct NC_Dispatch*, struct NC** ncp);
|
||||
int useparallel, void* parameters,
|
||||
struct NC_Dispatch* table, NC* ncp);
|
||||
\endcode
|
||||
|
||||
\code
|
||||
int (*open)(const char *path, int mode,
|
||||
int basepe, size_t *chunksizehintp,
|
||||
int use_parallel, MPI_Comm comm, MPI_Info info,
|
||||
NC_Dispatch*, NC** ncp);
|
||||
int use_parallel, void* parameters,
|
||||
struct NC_Dispatch* table, NC* ncp);
|
||||
\endcode
|
||||
|
||||
The key difference is that these are the union of all the possible
|
||||
create/open signatures from the netcdf.h API. Note especially the last
|
||||
two parameters. The dispatch table is included in case the create
|
||||
create/open signatures from the include/netcdfXXX.h files. Note especially the last
|
||||
three parameters. The parameters argument is a pointer to arbitrary data
|
||||
to provide extra info to the dispatcher.
|
||||
The table argument is included in case the create
|
||||
function (e.g. NCM_create) needs to invoke other dispatch
|
||||
functions. The very last parameter is a pointer to a pointer to an NC
|
||||
instance. It is expected that the create function will allocate and
|
||||
fill in an instance of an "NC" object and return a pointer to it in
|
||||
the ncp parameter.
|
||||
|
||||
\page dispatch_notes Dispatch Programming Notes
|
||||
|
||||
As with the existing code, and when MPI is not being used, the comm
|
||||
and info parameters should be passed in as 0. This is taken care of in
|
||||
the nc_open() and nc_create() API procedures in libdispatch/netcdf.c.
|
||||
|
||||
In fact, the object returned in the ncp parameter does not actually
|
||||
have to be an instance of struct NC. It only needs to "look like it
|
||||
for the first few fields. This is, in effect, a fake version of
|
||||
subclassing. Let us suppose that the NCM_create function uses a struct
|
||||
NCM object. The initial part of the definition of NCM must match the
|
||||
fields at the beginning of struct NC between the comments BEGIN_COMMON
|
||||
and END_COMMON. So, we would have the following.
|
||||
|
||||
\code
|
||||
typedef struct NCM {
|
||||
/*BEGIN COMMON*/
|
||||
int ext_ncid; /* uid «« 16 */
|
||||
int int_ncid; /* unspecified other id */
|
||||
struct NC_Dispatch* dispatch;
|
||||
#ifdef USE_DAP
|
||||
struct NCDRNO* drno;
|
||||
#endif
|
||||
/*END COMMON*/
|
||||
...
|
||||
} NCM;
|
||||
\endcode
|
||||
|
||||
This allows the pointer to the NCM object to be cast as an instance of
|
||||
NC* and its pointer returned in the ncp file. Eventually, this will be
|
||||
replaced with a separate structure containing the common fields.
|
||||
functions. The very last argument, ncp, is a pointer to an NC
|
||||
instance. The raw NC instance will have been created by libdispatch/dfile.c
|
||||
and is passed to e.g. open with the expectation that it will be filled in
|
||||
by the dispatch open function.
|
||||
|
||||
\page put_vara_dispatch Accessing Data with put_vara() and get_vara()
|
||||
|
||||
|
@ -63,7 +63,6 @@ to be used for different types of back-ends, for example, the HDF5
|
||||
library, or a DAP client accessing remote data.
|
||||
- \ref nc_dispatch
|
||||
- \ref adding_dispatch
|
||||
- \ref dispatch_notes
|
||||
- \ref put_vara_dispatch
|
||||
- \ref put_attr_dispatch
|
||||
|
||||
|
@ -22,9 +22,10 @@ The atomic external types supported by the netCDF interface are:
|
||||
- ::NC_UINT64 64-bit unsigned integer *
|
||||
- ::NC_FLOAT 32-bit floating point
|
||||
- ::NC_DOUBLE 64-bit floating point
|
||||
- ::NC_STRING variable length character string *
|
||||
- ::NC_STRING variable length character string +
|
||||
|
||||
\remark{* These types are available only for CDF5 (NC_CDF5) and netCDF-4 format (NC_NETCDF4) files. All the unsigned ints (except \ref NC_CHAR), the 64-bit ints, and string type are for CDF5 or netCDF-4 files only.}
|
||||
\remark * These types are available only for CDF5 (NC_CDF5) and netCDF-4 format (NC_NETCDF4) files. All the unsigned ints (except \ref NC_CHAR) and the 64-bit ints are for CDF5 or netCDF-4 files only.
|
||||
\remark + These types are available only for netCDF-4 (NC_NETCDF4) files.
|
||||
|
||||
These types were chosen to provide a reasonably wide range of
|
||||
trade-offs between data precision and number of bits required for each
|
||||
|
@ -10,10 +10,6 @@ INSTALL(FILES ${netCDF_SOURCE_DIR}/include/netcdf_mem.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
COMPONENT headers)
|
||||
|
||||
INSTALL(FILES ${netCDF_SOURCE_DIR}/include/netcdf_filter.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
COMPONENT headers)
|
||||
|
||||
INSTALL(FILES ${netCDF_BINARY_DIR}/include/netcdf_meta.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
COMPONENT headers)
|
||||
|
@ -4,7 +4,7 @@
|
||||
# This automake file generates the Makefile to build the include
|
||||
# directory.
|
||||
|
||||
include_HEADERS = netcdf.h netcdf_meta.h netcdf_filter.h
|
||||
include_HEADERS = netcdf.h netcdf_meta.h
|
||||
|
||||
if BUILD_PARALLEL
|
||||
include_HEADERS += netcdf_par.h
|
||||
@ -19,7 +19,7 @@ nclist.h ncuri.h ncutf8.h ncdispatch.h ncdimscale.h \
|
||||
netcdf_f.h err_macros.h ncbytes.h nchashmap.h ceconstraints.h rnd.h \
|
||||
nclog.h ncconfigure.h nc4internal.h nctime.h nc3internal.h \
|
||||
onstack.h nc_hashmap.h ncrc.h ncoffsets.h nctestserver.h \
|
||||
nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h
|
||||
nc4dispatch.h nc3dispatch.h ncexternl.h ncwinpath.h ncfilter.h
|
||||
|
||||
if USE_DAP
|
||||
noinst_HEADERS += ncdap.h
|
||||
|
25
include/ncfilter.h
Normal file
25
include/ncfilter.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
|
||||
See the COPYRIGHT file for more information. */
|
||||
|
||||
#ifndef NCFILTER_H
|
||||
#define NCFILTER_H 1
|
||||
|
||||
/* API for libdispatch/dfilter.c */
|
||||
|
||||
/* Must match values in <H5Zpublic.h> */
|
||||
#ifndef H5Z_FILTER_SZIP
|
||||
#define H5Z_FILTER_SZIP 4
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Provide consistent filter spec parser */
|
||||
EXTERNL int NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NCFILTER_H */
|
@ -9,6 +9,10 @@
|
||||
#define TIMEOUT 10 /*seconds*/
|
||||
#define BUFSIZE 8192 /*bytes*/
|
||||
|
||||
#ifndef HAVE_CURLINFO_RESPONSE_CODE
|
||||
#define CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
|
||||
#endif
|
||||
|
||||
static int ping(const char* url);
|
||||
|
||||
static char**
|
||||
|
@ -21,11 +21,11 @@
|
||||
#define NCU_ECONSTRAINTS (11)
|
||||
|
||||
/* Define flags to control what is included by ncuribuild*/
|
||||
#define NCURIPATH 1
|
||||
#define NCURIPWD 2
|
||||
#define NCURIQUERY 4
|
||||
#define NCURIFRAG 8
|
||||
#define NCURIENCODE 16 /* If output should be encoded */
|
||||
#define NCURIPATH 1
|
||||
#define NCURIPWD 2
|
||||
#define NCURIQUERY 4
|
||||
#define NCURIFRAG 8
|
||||
#define NCURIENCODE 16 /* If output should be encoded */
|
||||
#define NCURIBASE (NCURIPWD|NCURIPATH)
|
||||
#define NCURISVC (NCURIQUERY|NCURIBASE) /* for sending to server */
|
||||
#define NCURIALL (NCURIPATH|NCURIPWD|NCURIQUERY|NCURIFRAG) /* for rebuilding after changes */
|
||||
@ -81,9 +81,13 @@ extern const char* ncurilookup(NCURI*, const char* param);
|
||||
extern const char* ncuriquerylookup(NCURI*, const char* param);
|
||||
|
||||
/* URL Encode/Decode */
|
||||
extern char* ncuriencode(char* s, char* allowable);
|
||||
extern char* ncuridecode(char* s);
|
||||
extern char* ncuridecodeonly(char* s, char*);
|
||||
/* Partial decode */
|
||||
extern char* ncuridecodepartial(char* s, const char* decodeset);
|
||||
/* Encode using specified character set */
|
||||
extern char* ncuriencodeonly(char* s, char* allowable);
|
||||
/* Encode user or pwd */
|
||||
extern char* ncuriencodeuserpwd(char* s);
|
||||
|
||||
#if defined(_CPLUSPLUS_) || defined(__CPLUSPLUS__) || defined(__CPLUSPLUS)
|
||||
}
|
||||
|
@ -863,6 +863,14 @@ nc_def_var_endian(int ncid, int varid, int endian);
|
||||
EXTERNL int
|
||||
nc_inq_var_endian(int ncid, int varid, int *endianp);
|
||||
|
||||
/* Define a filter for a variable */
|
||||
EXTERNL int
|
||||
nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
|
||||
|
||||
/* Learn about the filter on a variable */
|
||||
EXTERNL int
|
||||
nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
|
||||
|
||||
/* Set the fill mode (classic or 64-bit offset files only). */
|
||||
EXTERNL int
|
||||
nc_set_fill(int ncid, int fillmode, int *old_modep);
|
||||
|
@ -1,34 +0,0 @@
|
||||
/*! \file netcdf_filter.h
|
||||
*
|
||||
* Main header file for filter functionality.
|
||||
*
|
||||
* Copyright 2010 University Corporation for Atmospheric
|
||||
* Research/Unidata. See COPYRIGHT file for more info.
|
||||
*
|
||||
* See \ref copyright file for more info.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NETCDF_FILTER_H
|
||||
#define NETCDF_FILTER_H 1
|
||||
|
||||
#include <netcdf.h>
|
||||
|
||||
/* Must match values in <H5Zpublic.h> */
|
||||
#ifndef H5Z_FILTER_SZIP
|
||||
#define H5Z_FILTER_SZIP 4
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
EXTERNL int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms);
|
||||
|
||||
EXTERNL int nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparams, unsigned int* params);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NETCDF_FILTER_H */
|
@ -48,6 +48,10 @@
|
||||
#define NC_HAS_MMAP @NC_HAS_MMAP@ /*!< mmap support. */
|
||||
#define NC_HAS_JNA @NC_HAS_JNA@ /*!< jna support. */
|
||||
#define NC_HAS_PNETCDF @NC_HAS_PNETCDF@ /*!< pnetcdf support. */
|
||||
#define NC_HAS_PARALLEL @NC_HAS_PARALLEL@ /*!< parallel IO support via hdf5 and/or pnetcdf. */
|
||||
#define NC_HAS_PARALLEL @NC_HAS_PARALLEL@ /*!< parallel IO support via hdf5 and
|
||||
/or pnetcdf. */
|
||||
|
||||
#define NC_HAS_CDF5 @NC_HAS_CDF5@ /*!< CDF5 support. */
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "dapincludes.h"
|
||||
#include "ncd2dispatch.h"
|
||||
#include "ncoffsets.h"
|
||||
#include "netcdf_filter.h"
|
||||
#ifdef DEBUG2
|
||||
#include "dapdump.h"
|
||||
#endif
|
||||
|
@ -11,7 +11,9 @@ struct CURLFLAG curlopts[] = {
|
||||
{"CURLOPT_PROXYUSERPWD",CURLOPT_PROXYUSERPWD,10006,CF_STRING},
|
||||
{"CURLOPT_SSLCERT",CURLOPT_SSLCERT,10025,CF_STRING},
|
||||
{"CURLOPT_SSLKEY",CURLOPT_SSLKEY,10087,CF_STRING},
|
||||
#ifdef HAVE_CURLOPT_KEYPASSWD
|
||||
{"CURLOPT_SSLKEYPASSWD",CURLOPT_SSLKEYPASSWD,CURLOPT_KEYPASSWD,CF_STRING},
|
||||
#endif
|
||||
{"CURLOPT_SSL_VERIFYHOST",CURLOPT_SSL_VERIFYHOST,81,CF_LONG},
|
||||
{"CURLOPT_SSL_VERIFYPEER",CURLOPT_SSL_VERIFYPEER,64,CF_LONG},
|
||||
{"CURLOPT_TIMEOUT",CURLOPT_TIMEOUT,13,CF_LONG},
|
||||
|
@ -56,9 +56,11 @@ set_curlflag(NCD4INFO* state, int flag)
|
||||
{
|
||||
int ret = NC_NOERR;
|
||||
switch (flag) {
|
||||
case CURLOPT_USERPWD:
|
||||
if(state->curl->creds.userpwd != NULL) {
|
||||
CHECK(state, CURLOPT_USERPWD, state->curl->creds.userpwd);
|
||||
case CURLOPT_USERPWD: /* Do both user and pwd */
|
||||
if(state->curl->creds.user != NULL
|
||||
&& state->curl->creds.pwd != NULL) {
|
||||
CHECK(state, CURLOPT_USERNAME, state->curl->creds.user);
|
||||
CHECK(state, CURLOPT_PASSWORD, state->curl->creds.pwd);
|
||||
CHECK(state, CURLOPT_HTTPAUTH, (OPTARG)CURLAUTH_ANY);
|
||||
}
|
||||
break;
|
||||
@ -107,8 +109,10 @@ set_curlflag(NCD4INFO* state, int flag)
|
||||
if(state->curl->proxy.host != NULL) {
|
||||
CHECK(state, CURLOPT_PROXY, state->curl->proxy.host);
|
||||
CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->curl->proxy.port);
|
||||
if(state->curl->proxy.userpwd) {
|
||||
CHECK(state, CURLOPT_PROXYUSERPWD, state->curl->proxy.userpwd);
|
||||
if(state->curl->proxy.user != NULL
|
||||
&& state->curl->proxy.pwd != NULL) {
|
||||
CHECK(state, CURLOPT_PROXYUSERNAME, state->curl->proxy.user);
|
||||
CHECK(state, CURLOPT_PROXYPASSWORD, state->curl->proxy.pwd);
|
||||
#ifdef CURLOPT_PROXYAUTH
|
||||
CHECK(state, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
|
||||
#endif
|
||||
@ -264,6 +268,7 @@ NCD4_curl_protocols(NCD4globalstate* state)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
"Inverse" of set_curlflag;
|
||||
Given a flag and value, it updates state.
|
||||
@ -349,6 +354,7 @@ NCD4_set_curlstate(NCD4INFO* state, int flag, void* value)
|
||||
done:
|
||||
return THROW(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
NCD4_curl_printerror(NCD4INFO* state)
|
||||
|
@ -6,6 +6,14 @@
|
||||
#ifndef D4CURLFUNCTIONS_H
|
||||
#define D4CURLFUNCTIONS_H
|
||||
|
||||
/* Aliases to older names */
|
||||
#ifndef HAVE_CURLOPT_KEYPASSWD
|
||||
#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
|
||||
#endif
|
||||
#ifndef HAVE_CURLINFO_RESPONSE_CODE
|
||||
#define CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
|
||||
#endif
|
||||
|
||||
enum CURLFLAGTYPE {CF_UNKNOWN=0,CF_OTHER=1,CF_STRING=2,CF_LONG=3};
|
||||
struct CURLFLAG {
|
||||
const char* name;
|
||||
@ -20,7 +28,6 @@ extern ncerror NCD4_set_flags_perfetch(NCD4INFO*);
|
||||
extern ncerror NCD4_set_flags_perlink(NCD4INFO*);
|
||||
|
||||
extern ncerror NCD4_set_curlflag(NCD4INFO*,int);
|
||||
extern ncerror NCD4_set_curlstate(NCD4INFO* state, int flag, void* value);
|
||||
|
||||
extern void NCD4_curl_debug(NCD4INFO* state);
|
||||
|
||||
|
@ -327,8 +327,10 @@ freeCurl(NCD4curl* curl)
|
||||
nullfree(curl->ssl.cainfo);
|
||||
nullfree(curl->ssl.capath);
|
||||
nullfree(curl->proxy.host);
|
||||
nullfree(curl->proxy.userpwd);
|
||||
nullfree(curl->creds.userpwd);
|
||||
nullfree(curl->proxy.user);
|
||||
nullfree(curl->proxy.pwd);
|
||||
nullfree(curl->creds.user);
|
||||
nullfree(curl->creds.pwd);
|
||||
if(curl->curlflags.createdflags & COOKIECREATED)
|
||||
d4removecookies(curl->curlflags.cookiejar);
|
||||
nullfree(curl->curlflags.cookiejar);
|
||||
|
@ -24,7 +24,7 @@ NCD4_fetchhttpcode(CURL* curl)
|
||||
#ifdef HAVE_CURLINFO_RESPONSE_CODE
|
||||
cstat = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&httpcode);
|
||||
#else
|
||||
cstat = curl_easy_getinfo(curl,CURLINFO_HTTP_CODE,&httpcode);
|
||||
cstat = curl_easy_getinfo(curl,CURLINFO_HTTP_CONNECTCODE,&httpcode);
|
||||
#endif
|
||||
if(cstat != CURLE_OK) {
|
||||
httpcode = 0;
|
||||
@ -321,7 +321,7 @@ curlerrtoncerr(CURLcode cstat)
|
||||
switch (cstat) {
|
||||
case CURLE_OK: return THROW(NC_NOERR);
|
||||
case CURLE_URL_MALFORMAT:
|
||||
return THROW(NC_EURL);
|
||||
return THROW(NC_EURL);
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
case CURLE_REMOTE_ACCESS_DENIED:
|
||||
@ -338,5 +338,5 @@ curlerrtoncerr(CURLcode cstat)
|
||||
case CURLE_SSL_CACERT_BADFILE:
|
||||
default: break;
|
||||
}
|
||||
return THROW(NC_ECURL);
|
||||
return THROW(NC_ECURL);
|
||||
}
|
||||
|
140
libdap4/d4rc.c
140
libdap4/d4rc.c
@ -16,14 +16,14 @@
|
||||
#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
|
||||
|
||||
/* Forward */
|
||||
static char* extract_credentials(NCURI*);
|
||||
static int rccompile(const char* path);
|
||||
static struct NCD4triple* rclocate(char* key, char* hostport);
|
||||
static void rcorder(NClist* rc);
|
||||
static NClist* rcorder(NClist* rc);
|
||||
static char* rcreadline(char**);
|
||||
static int rcsearch(const char* prefix, const char* rcname, char** pathp);
|
||||
static void rctrim(char* text);
|
||||
static int rcsetinfocurlflag(NCD4INFO*, const char* flag, const char* value);
|
||||
static int parsecredentials(const char* userpwd, char** userp, char** pwdp);
|
||||
#ifdef D4DEBUG
|
||||
static void storedump(char* msg, NClist* triples);
|
||||
#endif
|
||||
@ -80,30 +80,34 @@ rctrim(char* text)
|
||||
}
|
||||
}
|
||||
|
||||
/* Order the triples: put all those with urls first */
|
||||
static void
|
||||
/* Order the triples: those with urls must be first,
|
||||
but otherwise relative order does not matter.
|
||||
*/
|
||||
static NClist*
|
||||
rcorder(NClist* rc)
|
||||
{
|
||||
int i,j;
|
||||
int len = nclistlength(rc);
|
||||
if(rc == NULL || len == 0) return;
|
||||
NClist* newrc = nclistnew();
|
||||
if(rc == NULL || len == 0) return newrc;
|
||||
/* Two passes: 1) pull triples with host */
|
||||
for(i=0;i<len;i++) {
|
||||
NCD4triple* ti = nclistget(rc,i);
|
||||
NCD4triple* ti = nclistget(rc,i);
|
||||
if(ti->host == NULL) continue;
|
||||
nclistpush(newrc,ti);
|
||||
}
|
||||
/* pass 2 pull triples without host*/
|
||||
for(i=0;i<len;i++) {
|
||||
NCD4triple* ti = nclistget(rc,i);
|
||||
if(ti->host != NULL) continue;
|
||||
for(j=i;j<len;j++) {
|
||||
NCD4triple* tj = nclistget(rc,j);
|
||||
if(tj->host != NULL) {/*swap*/
|
||||
NCD4triple* t = ti;
|
||||
nclistset(rc,i,tj);
|
||||
nclistset(rc,j,t);
|
||||
}
|
||||
}
|
||||
nclistpush(newrc,ti);
|
||||
}
|
||||
#ifdef D4DEBUG
|
||||
storedump("reorder:",rc);
|
||||
storedump("reorder:",newrc);
|
||||
#endif
|
||||
}
|
||||
return newrc;
|
||||
|
||||
}
|
||||
|
||||
/* Create a triple store from a file */
|
||||
static int
|
||||
@ -373,10 +377,15 @@ rcsetinfocurlflag(NCD4INFO* info, const char* flag, const char* value)
|
||||
#endif
|
||||
}
|
||||
|
||||
if(strcmp(flag,"HTTP.CREDENTIALS.USERPASSWORD")==0) {
|
||||
nullfree(info->curl->creds.userpwd);
|
||||
info->curl->creds.userpwd = strdup(value);
|
||||
MEMCHECK(info->curl->creds.userpwd);
|
||||
if(strcmp(flag,"HTTP.CREDENTIALS.USERNAME")==0) {
|
||||
nullfree(info->curl->creds.user);
|
||||
info->curl->creds.user = strdup(value);
|
||||
MEMCHECK(info->curl->creds.user);
|
||||
}
|
||||
if(strcmp(flag,"HTTP.CREDENTIALS.PASSWORD")==0) {
|
||||
nullfree(info->curl->creds.pwd);
|
||||
info->curl->creds.pwd = strdup(value);
|
||||
MEMCHECK(info->curl->creds.pwd);
|
||||
}
|
||||
|
||||
done:
|
||||
@ -390,9 +399,7 @@ int
|
||||
NCD4_rcprocess(NCD4INFO* info)
|
||||
{
|
||||
int ret = NC_NOERR;
|
||||
char userpwd[NC_MAX_PATH];
|
||||
char hostport[NC_MAX_PATH];
|
||||
char* url_userpwd = userpwd; /* WATCH OUT: points to previous variable */
|
||||
char* url_hostport = hostport; /* WATCH OUT: points to previous variable */
|
||||
NCURI* uri = info->uri;
|
||||
|
||||
@ -403,15 +410,12 @@ NCD4_rcprocess(NCD4INFO* info)
|
||||
|
||||
/* Note, we still must do this function even if
|
||||
NCD4_globalstate->rc.ignore is set in order
|
||||
to getinfo e.g. user:pwd from url
|
||||
to getinfo e.g. host+port from url
|
||||
*/
|
||||
|
||||
url_hostport = NULL;
|
||||
if(uri != NULL) {
|
||||
NCD4_userpwd(uri,url_userpwd,sizeof(userpwd));
|
||||
NCD4_hostport(uri,url_hostport,sizeof(hostport));
|
||||
} else {
|
||||
url_hostport = NULL;
|
||||
url_userpwd = NULL;
|
||||
}
|
||||
|
||||
rcsetinfocurlflag(info,"HTTP.DEFLATE",
|
||||
@ -450,29 +454,38 @@ NCD4_rcprocess(NCD4INFO* info)
|
||||
NCD4_rclookup("HTTP.NETRC",url_hostport));
|
||||
{ /* Handle various cases for user + password */
|
||||
/* First, see if the user+pwd was in the original url */
|
||||
char* userpwd = NULL;
|
||||
char* user = NULL;
|
||||
char* pwd = NULL;
|
||||
if(url_userpwd != NULL)
|
||||
userpwd = url_userpwd;
|
||||
else {
|
||||
if(uri->user != NULL && uri->password != NULL) {
|
||||
user = uri->user;
|
||||
pwd = uri->password;
|
||||
} else {
|
||||
user = NCD4_rclookup("HTTP.CREDENTIALS.USER",url_hostport);
|
||||
pwd = NCD4_rclookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
|
||||
userpwd = NCD4_rclookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
|
||||
}
|
||||
if(userpwd == NULL && user != NULL && pwd != NULL) {
|
||||
char creds[NC_MAX_PATH];
|
||||
strncpy(creds,user,sizeof(creds));
|
||||
strncat(creds,":",sizeof(creds));
|
||||
strncat(creds,pwd,sizeof(creds));
|
||||
rcsetinfocurlflag(info,"HTTP.USERPASSWORD",creds);
|
||||
} else if(userpwd != NULL)
|
||||
rcsetinfocurlflag(info,"HTTP.USERPASSWORD",userpwd);
|
||||
if(user != NULL && pwd != NULL) {
|
||||
user = strdup(user); /* so we can consistently reclaim */
|
||||
pwd = strdup(pwd);
|
||||
} else {
|
||||
/* Could not get user and pwd, so try USERPASSWORD */
|
||||
const char* userpwd = NCD4_rclookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
|
||||
if(userpwd != NULL) {
|
||||
ret = parsecredentials(userpwd,&user,&pwd);
|
||||
if(ret) return ret;
|
||||
}
|
||||
}
|
||||
rcsetinfocurlflag(info,"HTTP.USERNAME",user);
|
||||
rcsetinfocurlflag(info,"HTTP.PASSWORD",pwd);
|
||||
nullfree(user);
|
||||
nullfree(pwd);
|
||||
}
|
||||
|
||||
return THROW(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Locate a triple by property key and host+port (may be null or "").
|
||||
* If duplicate keys, first takes precedence.
|
||||
*/
|
||||
static struct NCD4triple*
|
||||
rclocate(char* key, char* hostport)
|
||||
{
|
||||
@ -503,6 +516,10 @@ rclocate(char* key, char* hostport)
|
||||
return (found?triple:NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a triple by property key and host+port (may be null|"")
|
||||
* If duplicate keys, first takes precedence.
|
||||
*/
|
||||
char*
|
||||
NCD4_rclookup(char* key, char* hostport)
|
||||
{
|
||||
@ -524,13 +541,16 @@ storedump(char* msg, NClist* triples)
|
||||
for(i=0;i<nclistlength(triples);i++) {
|
||||
NCD4triple* t = (NCD4triple*)nclistget(triples,i);
|
||||
fprintf(stderr,"\t%s\t%s\t%s\n",
|
||||
(t->host == NULL || strlen(t->host)==0?"--":t->host),t->key,t->value);
|
||||
|
||||
((t->host == NULL || strlen(t->host)==0)?"--":t->host),t->key,t->value);
|
||||
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Locate rc file by searching in directory prefix.
|
||||
* Prefix must end in '/'
|
||||
*/
|
||||
static
|
||||
@ -592,7 +612,8 @@ NCD4_parseproxy(NCD4INFO* info, const char* surl)
|
||||
return THROW(NC_NOERR); /* nothing there*/
|
||||
if(ncuriparse(surl,&uri) != NCU_OK)
|
||||
return THROW(NC_EURL);
|
||||
info->curl->proxy.userpwd = extract_credentials(uri);
|
||||
info->curl->proxy.user = uri->user;
|
||||
info->curl->proxy.pwd = uri->password;
|
||||
info->curl->proxy.host = strdup(uri->host);
|
||||
if(uri->port != NULL)
|
||||
info->curl->proxy.port = atoi(uri->port);
|
||||
@ -601,15 +622,32 @@ NCD4_parseproxy(NCD4INFO* info, const char* surl)
|
||||
return THROW(ret);
|
||||
}
|
||||
|
||||
/* Caller must free result_url */
|
||||
static char*
|
||||
extract_credentials(NCURI* url)
|
||||
/*
|
||||
Given form user:pwd, parse into user and pwd
|
||||
and do %xx unescaping
|
||||
*/
|
||||
static int
|
||||
parsecredentials(const char* userpwd, char** userp, char** pwdp)
|
||||
{
|
||||
char tmp[NC_MAX_PATH];
|
||||
if(url->user == NULL || url->password == NULL)
|
||||
return NULL;
|
||||
NCD4_userpwd(url,tmp,sizeof(tmp));
|
||||
return strdup(tmp);
|
||||
char* user = NULL;
|
||||
char* pwd = NULL;
|
||||
|
||||
if(userpwd == NULL)
|
||||
return NC_EINVAL;
|
||||
user = strdup(userpwd);
|
||||
if(user == NULL)
|
||||
return NC_ENOMEM;
|
||||
pwd = strchr(user,':');
|
||||
if(pwd == NULL)
|
||||
return NC_EINVAL;
|
||||
*pwd = '\0';
|
||||
pwd++;
|
||||
if(userp)
|
||||
*userp = ncuridecode(user);
|
||||
if(pwdp)
|
||||
*pwdp = ncuridecode(pwd);
|
||||
free(user);
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -408,6 +408,7 @@ NCD4_hostport(NCURI* uri, char* space, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
NCD4_userpwd(NCURI* uri, char* space, size_t len)
|
||||
{
|
||||
@ -420,6 +421,7 @@ NCD4_userpwd(NCURI* uri, char* space, size_t len)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BLOB
|
||||
void
|
||||
|
@ -129,7 +129,6 @@ extern int NCD4_getToplevelVars(NCD4meta* meta, NCD4node* group, NClist* topleve
|
||||
/* From d4util.c */
|
||||
extern d4size_t NCD4_dimproduct(NCD4node* node);
|
||||
extern void NCD4_hostport(NCURI* uri, char* space, size_t len);
|
||||
extern void NCD4_userpwd(NCURI* uri, char* space, size_t len);
|
||||
extern size_t NCD4_typesize(nc_type tid);
|
||||
extern int NCD4_isLittleEndian(void);/* Return 1 if this machine is little endian */
|
||||
extern int NCD4_errorNC(int code, const int line, const char* file);
|
||||
|
@ -325,10 +325,12 @@ struct NCD4curl {
|
||||
struct proxy {
|
||||
char *host; /*CURLOPT_PROXY*/
|
||||
int port; /*CURLOPT_PROXYPORT*/
|
||||
char* userpwd; /*CURLOPT_PROXYUSERPWD*/
|
||||
char* user; /*CURLOPT_PROXYUSERNAME*/
|
||||
char* pwd; /*CURLOPT_PROXYPASSWORD*/
|
||||
} proxy;
|
||||
struct credentials {
|
||||
char *userpwd; /*CURLOPT_USERPWD*/
|
||||
char *user; /*CURLOPT_USERNAME*/
|
||||
char *pwd; /*CURLOPT_PASSWORD*/
|
||||
} creds;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
SET(libdispatch_SOURCES dparallel.c dcopy.c dfile.c ddim.c datt.c dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c dvarinq.c ddispatch.c nclog.c dstring.c dutf8.c dinternal.c doffsets.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c nclistmgr.c utf8proc.h utf8proc.c dwinpath.c)
|
||||
|
||||
IF(USE_NETCDF4)
|
||||
SET(libdispatch_SOURCES ${libdispatch_SOURCES} dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c)
|
||||
SET(libdispatch_SOURCES ${libdispatch_SOURCES} dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c dfilter.c)
|
||||
ENDIF(USE_NETCDF4)
|
||||
|
||||
IF(BUILD_V2)
|
||||
|
@ -17,9 +17,8 @@ libdispatch_la_CPPFLAGS = ${AM_CPPFLAGS}
|
||||
# The source files.
|
||||
libdispatch_la_SOURCES = dparallel.c dcopy.c dfile.c ddim.c datt.c \
|
||||
dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c \
|
||||
dvarinq.c dinternal.c ddispatch.c dutf8.c \
|
||||
nclog.c dstring.c \
|
||||
ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c \
|
||||
dvarinq.c dinternal.c ddispatch.c dutf8.c dstring.c \
|
||||
nclog.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c \
|
||||
nc.c nclistmgr.c drc.c doffsets.c dwinpath.c
|
||||
|
||||
# Add the utf8 codebase
|
||||
@ -28,7 +27,7 @@ libdispatch_la_SOURCES += utf8proc.c utf8proc.h
|
||||
# Add functions only found in netCDF-4.
|
||||
if USE_NETCDF4
|
||||
libdispatch_la_SOURCES += dgroup.c dvlen.c dcompound.c dtype.c denum.c \
|
||||
dopaque.c ncaux.c
|
||||
dopaque.c dfilter.c ncaux.c
|
||||
endif # USE_NETCDF4
|
||||
|
||||
# Turn on pre-processor flag when building a DLL for windows.
|
||||
|
@ -258,7 +258,7 @@ const char *nc_strerror(int ncerr1)
|
||||
case NC_EDISKLESS:
|
||||
return "NetCDF: Error in using diskless access";
|
||||
case NC_EFILTER:
|
||||
return "NetCDF: Error in filter id or parameters";
|
||||
return "NetCDF: Filter error: bad id or parameters or filter library non-existent";
|
||||
default:
|
||||
#ifdef USE_PNETCDF
|
||||
/* The behavior of ncmpi_strerror here is to return
|
||||
|
@ -104,10 +104,12 @@ NC_interpret_magic_number(char* magic, int* model, int* version, int use_paralle
|
||||
} else if(magic[3] == '\002') {
|
||||
*version = 2; /* netcdf classic version 2 */
|
||||
*model = NC_FORMATX_NC3;
|
||||
} else if(magic[3] == '\005') {
|
||||
*version = 5; /* cdf5 (including pnetcdf) file */
|
||||
#ifdef USE_CDF5
|
||||
} else if(magic[3] == '\005') {
|
||||
*version = 5; /* cdf5 (including pnetcdf) file */
|
||||
*model = NC_FORMATX_NC3;
|
||||
} else
|
||||
#endif
|
||||
} else
|
||||
{status = NC_ENOTNC; goto done;}
|
||||
} else
|
||||
{status = NC_ENOTNC; goto done;}
|
||||
@ -1608,11 +1610,10 @@ Create a file, calling the appropriate dispatch create call.
|
||||
|
||||
For create, we have the following pieces of information to use to
|
||||
determine the dispatch table:
|
||||
- table specified by override
|
||||
- path
|
||||
- cmode
|
||||
|
||||
\param path The file name of the new netCDF dataset.
|
||||
\param path0 The file name of the new netCDF dataset.
|
||||
|
||||
\param cmode The creation mode flag, the same as in nc_create().
|
||||
|
||||
@ -1720,11 +1721,13 @@ fprintf(stderr,"XXX: path0=%s path=%s\n",path0,path); fflush(stderr);
|
||||
model = NC_FORMATX_NC4;
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_CDF5
|
||||
case NC_FORMAT_CDF5:
|
||||
xcmode |= NC_64BIT_DATA;
|
||||
model = NC_FORMATX_NC3;
|
||||
break;
|
||||
case NC_FORMAT_64BIT_OFFSET:
|
||||
#endif
|
||||
case NC_FORMAT_64BIT_OFFSET:
|
||||
xcmode |= NC_64BIT_OFFSET;
|
||||
model = NC_FORMATX_NC3;
|
||||
break;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*********************************************************************
|
||||
* Copyright 2016, UCAR/Unidata
|
||||
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
||||
*********************************************************************/
|
||||
/*
|
||||
Copyright (c) 1998-2017 University Corporation for Atmospheric Research/Unidata
|
||||
See LICENSE.txt for license information.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
|
@ -6,7 +6,13 @@ Research/Unidata. See COPYRIGHT file for more info.
|
||||
*/
|
||||
|
||||
#include "ncdispatch.h"
|
||||
#include "netcdf_filter.h"
|
||||
#ifdef USE_NETCDF4
|
||||
#include <hdf5.h>
|
||||
#endif
|
||||
|
||||
#ifndef H5Z_FILTER_SZIP
|
||||
#define H5Z_FILTER_SZIP 4
|
||||
#endif
|
||||
|
||||
/** \name Learning about Variables
|
||||
|
||||
@ -245,7 +251,6 @@ nc_inq_varnatts(int ncid, int varid, int *nattsp)
|
||||
nattsp);
|
||||
}
|
||||
|
||||
#ifdef USE_NETCDF4
|
||||
/** \ingroup variables
|
||||
Learn the storage and deflate settings for a variable.
|
||||
|
||||
@ -300,97 +305,6 @@ nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep,
|
||||
);
|
||||
}
|
||||
|
||||
/** \ingroup variables
|
||||
Learn the szip settings of a variable.
|
||||
|
||||
This function returns the szip settings for a variable.
|
||||
With the introduction of general filter support,
|
||||
szip inquiry is converted to use the filter interface.
|
||||
|
||||
This is a wrapper for nc_inq_var_filter().
|
||||
|
||||
\param ncid NetCDF or group ID, from a previous call to nc_open(),
|
||||
nc_create(), nc_def_grp(), or associated inquiry functions such as
|
||||
nc_inq_ncid().
|
||||
|
||||
\param varid Variable ID
|
||||
|
||||
\param options_maskp The szip options mask will be copied to this
|
||||
pointer. \ref ignored_if_null.
|
||||
|
||||
\param pixels_per_blockp The szip pixels per block will be copied
|
||||
here. \ref ignored_if_null.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
\returns ::NC_EBADID Bad ncid.
|
||||
\returns ::NC_ENOTNC4 Not a netCDF-4 file.
|
||||
\returns ::NC_ENOTVAR Invalid variable ID.
|
||||
\returns ::NC_EFILTER Variable is not szip encoded
|
||||
*/
|
||||
int
|
||||
nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
|
||||
{
|
||||
NC* ncp;
|
||||
unsigned int id;
|
||||
size_t nparams;
|
||||
unsigned int params[2];
|
||||
|
||||
int stat = NC_check_id(ncid,&ncp);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
TRACE(nc_inq_var_szip);
|
||||
|
||||
/* Verify id and nparams */
|
||||
stat = ncp->dispatch->inq_var_all(
|
||||
ncid, varid,
|
||||
NULL, /*name*/
|
||||
NULL, /*xtypep*/
|
||||
NULL, /*ndimsp*/
|
||||
NULL, /*dimidsp*/
|
||||
NULL, /*nattsp*/
|
||||
NULL, /*shufflep*/
|
||||
NULL, /*deflatep*/
|
||||
NULL, /*deflatelevelp*/
|
||||
NULL, /*fletcher32p*/
|
||||
NULL, /*contiguousp*/
|
||||
NULL, /*chunksizep*/
|
||||
NULL, /*nofillp*/
|
||||
NULL, /*fillvaluep*/
|
||||
NULL, /*endianp*/
|
||||
&id,
|
||||
&nparams,
|
||||
NULL
|
||||
);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
if(id != H5Z_FILTER_SZIP || nparams != 2)
|
||||
return NC_EFILTER; /* not szip or bad # params */
|
||||
/* Get params */
|
||||
stat = ncp->dispatch->inq_var_all(
|
||||
ncid, varid,
|
||||
NULL, /*name*/
|
||||
NULL, /*xtypep*/
|
||||
NULL, /*ndimsp*/
|
||||
NULL, /*dimidsp*/
|
||||
NULL, /*nattsp*/
|
||||
NULL, /*shufflep*/
|
||||
NULL, /*deflatep*/
|
||||
NULL, /*deflatelevelp*/
|
||||
NULL, /*fletcher32p*/
|
||||
NULL, /*contiguousp*/
|
||||
NULL, /*chunksizep*/
|
||||
NULL, /*nofillp*/
|
||||
NULL, /*fillvaluep*/
|
||||
NULL, /*endianp*/
|
||||
&id,
|
||||
&nparams,
|
||||
params
|
||||
);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
/* Param[0] should be options_mask, Param[1] should be pixels_per_block */
|
||||
if(options_maskp) *options_maskp = (int)params[0];
|
||||
if(pixels_per_blockp) *pixels_per_blockp = (int)params[1];
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/** \ingroup variables
|
||||
Learn the checksum settings for a variable.
|
||||
|
||||
@ -633,12 +547,16 @@ This function will return one of the following values.
|
||||
int
|
||||
nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp)
|
||||
{
|
||||
#ifndef USE_NETCDF4
|
||||
return NC_ENOTNC4;
|
||||
#else
|
||||
NC* ncp;
|
||||
int stat = NC_check_id(ncid,&ncp);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
TRACE(nc_inq_unlimdims);
|
||||
TRACE(nc_inq_unlimdims);
|
||||
return ncp->dispatch->inq_unlimdims(ncid, nunlimdimsp,
|
||||
unlimdimidsp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \ingroup variables
|
||||
@ -691,7 +609,97 @@ nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparamsp, unsi
|
||||
idp, nparamsp, params);
|
||||
}
|
||||
|
||||
#endif /* USE_NETCDF4 */
|
||||
/** \ingroup variables
|
||||
Learn the szip settings of a variable.
|
||||
Similar to nc_inq_var_deflate.
|
||||
|
||||
This function returns the szip settings for a variable.
|
||||
With the introduction of general filter support,
|
||||
szip inquiry is converted to use the filter interface.
|
||||
|
||||
This is a wrapper for nc_inq_var_filter().
|
||||
|
||||
\param ncid NetCDF or group ID, from a previous call to nc_open(),
|
||||
nc_create(), nc_def_grp(), or associated inquiry functions such as
|
||||
nc_inq_ncid().
|
||||
|
||||
\param varid Variable ID
|
||||
|
||||
\param options_maskp The szip options mask will be copied to this
|
||||
pointer. \ref ignored_if_null.
|
||||
|
||||
\param pixels_per_blockp The szip pixels per block will be copied
|
||||
here. \ref ignored_if_null.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
\returns ::NC_EBADID Bad ncid.
|
||||
\returns ::NC_ENOTNC4 Not a netCDF-4 file.
|
||||
\returns ::NC_ENOTVAR Invalid variable ID.
|
||||
\returns ::NC_EFILTER Variable is not szip encoded
|
||||
*/
|
||||
int
|
||||
nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
|
||||
{
|
||||
NC* ncp;
|
||||
unsigned int id;
|
||||
size_t nparams;
|
||||
unsigned int params[2];
|
||||
|
||||
int stat = NC_check_id(ncid,&ncp);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
TRACE(nc_inq_var_szip);
|
||||
|
||||
/* Verify id and nparams */
|
||||
stat = ncp->dispatch->inq_var_all(
|
||||
ncid, varid,
|
||||
NULL, /*name*/
|
||||
NULL, /*xtypep*/
|
||||
NULL, /*ndimsp*/
|
||||
NULL, /*dimidsp*/
|
||||
NULL, /*nattsp*/
|
||||
NULL, /*shufflep*/
|
||||
NULL, /*deflatep*/
|
||||
NULL, /*deflatelevelp*/
|
||||
NULL, /*fletcher32p*/
|
||||
NULL, /*contiguousp*/
|
||||
NULL, /*chunksizep*/
|
||||
NULL, /*nofillp*/
|
||||
NULL, /*fillvaluep*/
|
||||
NULL, /*endianp*/
|
||||
&id,
|
||||
&nparams,
|
||||
NULL
|
||||
);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
if(id != H5Z_FILTER_SZIP || nparams != 2)
|
||||
return NC_EFILTER; /* not szip or bad # params */
|
||||
/* Get params */
|
||||
stat = ncp->dispatch->inq_var_all(
|
||||
ncid, varid,
|
||||
NULL, /*name*/
|
||||
NULL, /*xtypep*/
|
||||
NULL, /*ndimsp*/
|
||||
NULL, /*dimidsp*/
|
||||
NULL, /*nattsp*/
|
||||
NULL, /*shufflep*/
|
||||
NULL, /*deflatep*/
|
||||
NULL, /*deflatelevelp*/
|
||||
NULL, /*fletcher32p*/
|
||||
NULL, /*contiguousp*/
|
||||
NULL, /*chunksizep*/
|
||||
NULL, /*nofillp*/
|
||||
NULL, /*fillvaluep*/
|
||||
NULL, /*endianp*/
|
||||
&id,
|
||||
&nparams,
|
||||
params
|
||||
);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
/* Param[0] should be options_mask, Param[1] should be pixels_per_block */
|
||||
if(options_maskp) *options_maskp = (int)params[0];
|
||||
if(pixels_per_blockp) *pixels_per_blockp = (int)params[1];
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@ -713,8 +721,6 @@ Used in libdap2 and libdap4.
|
||||
@param[out] no_fill Pointer to memory to store whether or not there is a fill value associated with the variable.
|
||||
@param[out] fill_valuep Pointer to memory to store the fill value (if one exists) for the variable.
|
||||
@param[out] endiannessp Pointer to memory to store endianness value. One of ::NC_ENDIAN_BIG ::NC_ENDIAN_LITTLE ::NC_ENDIAN_NATIVE
|
||||
@param[out] options_maskp Pointer to memory to store mask options information.
|
||||
@param[out] pixels_per_blockp Pointer to memory to store pixels-per-block information for chunked data.
|
||||
@param[out] idp Pointer to memory to store filter id.
|
||||
@param[out] nparamsp Pointer to memory to store filter parameter count.
|
||||
@param[out] params Pointer to vector of unsigned integers into which
|
||||
|
@ -63,6 +63,10 @@ static char* pathallow =
|
||||
static char* queryallow =
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$&'()*+,-./:;=?@_~";
|
||||
|
||||
/* user+pwd allow = path allow - "@:" */
|
||||
static char* userpwdallow =
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$&'()*+,-.;=_~?#/";
|
||||
|
||||
#ifndef HAVE_STRNCMP
|
||||
#define strndup ncstrndup
|
||||
/* Not all systems have strndup, so provide one*/
|
||||
@ -345,8 +349,13 @@ ncuriparse(const char* uri0, NCURI** durip)
|
||||
/* save original uri */
|
||||
duri->uri = strdup(uri0);
|
||||
duri->protocol = nulldup(tmp.protocol);
|
||||
duri->user = nulldup(tmp.user);
|
||||
duri->password = nulldup(tmp.password);
|
||||
/* before saving, we need to decode the user+pwd */
|
||||
duri->user = NULL;
|
||||
duri->password = NULL;
|
||||
if(tmp.user != NULL)
|
||||
duri->user = ncuridecode(tmp.user);
|
||||
if(tmp.password != NULL)
|
||||
duri->password = ncuridecode(tmp.password);
|
||||
duri->host = nulldup(tmp.host);
|
||||
duri->port = nulldup(tmp.port);
|
||||
if(tmp.path != NULL) {
|
||||
@ -530,9 +539,14 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
|
||||
ncbytescat(buf,"://"); /* this will produce file:///... */
|
||||
|
||||
if((flags & NCURIPWD) && duri->user != NULL && duri->password != NULL) {
|
||||
ncbytescat(buf,duri->user);
|
||||
/* The user and password must be encoded */
|
||||
char* encoded = ncuriencodeonly(duri->user,userpwdallow);
|
||||
ncbytescat(buf,encoded);
|
||||
nullfree(encoded);
|
||||
ncbytescat(buf,":");
|
||||
ncbytescat(buf,duri->password);
|
||||
encoded = ncuriencodeonly(duri->password,userpwdallow);
|
||||
ncbytescat(buf,encoded);
|
||||
nullfree(encoded);
|
||||
ncbytescat(buf,"@");
|
||||
}
|
||||
if(duri->host != NULL) ncbytescat(buf,duri->host);
|
||||
@ -544,7 +558,7 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
|
||||
if(duri->path == NULL)
|
||||
ncbytescat(buf,"/");
|
||||
else if(encode) {
|
||||
char* encoded = ncuriencode(duri->path,pathallow);
|
||||
char* encoded = ncuriencodeonly(duri->path,pathallow);
|
||||
ncbytescat(buf,encoded);
|
||||
nullfree(encoded);
|
||||
} else
|
||||
@ -566,7 +580,7 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
|
||||
if(p[1] != NULL && strlen(p[1]) > 0) {
|
||||
ncbytescat(buf,"=");
|
||||
if(encode) {
|
||||
char* encoded = ncuriencode(p[1],queryallow);
|
||||
char* encoded = ncuriencodeonly(p[1],queryallow);
|
||||
ncbytescat(buf,encoded);
|
||||
nullfree(encoded);
|
||||
} else
|
||||
@ -583,7 +597,7 @@ ncuribuild(NCURI* duri, const char* prefix, const char* suffix, int flags)
|
||||
if(p[1] != NULL && strlen(p[1]) > 0) {
|
||||
ncbytescat(buf,"=");
|
||||
if(encode) {
|
||||
char* encoded = ncuriencode(p[1],queryallow);
|
||||
char* encoded = ncuriencodeonly(p[1],queryallow);
|
||||
ncbytescat(buf,encoded);
|
||||
nullfree(encoded);
|
||||
} else
|
||||
@ -720,8 +734,8 @@ static char* hexchars = "0123456789abcdefABCDEF";
|
||||
static void
|
||||
toHex(unsigned int b, char hex[2])
|
||||
{
|
||||
hex[0] = hexchars[(b >> 4) & 0xff];
|
||||
hex[1] = hexchars[(b) & 0xff];
|
||||
hex[0] = hexchars[(b >> 4) & 0xf];
|
||||
hex[1] = hexchars[(b) & 0xf];
|
||||
}
|
||||
|
||||
|
||||
@ -734,6 +748,14 @@ fromHex(int c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Support encode of user and password fields
|
||||
*/
|
||||
char*
|
||||
ncuriencodeuserpwd(char* s)
|
||||
{
|
||||
return ncuriencodeonly(s,userpwdallow);
|
||||
}
|
||||
|
||||
/* Return a string representing encoding of input; caller must free;
|
||||
watch out: will encode whole string, so watch what you give it.
|
||||
@ -741,7 +763,7 @@ fromHex(int c)
|
||||
*/
|
||||
|
||||
char*
|
||||
ncuriencode(char* s, char* allowable)
|
||||
ncuriencodeonly(char* s, char* allowable)
|
||||
{
|
||||
size_t slen;
|
||||
char* encoded;
|
||||
@ -760,12 +782,10 @@ ncuriencode(char* s, char* allowable)
|
||||
} else {
|
||||
/* search allowable */
|
||||
int c2;
|
||||
char* a = allowable;
|
||||
while((c2=*a++)) {
|
||||
if(c == c2) break;
|
||||
}
|
||||
if(c2) {*outptr++ = (char)c;}
|
||||
else {
|
||||
char* p = strchr(allowable,c);
|
||||
if(p != NULL) {
|
||||
*outptr++ = (char)c;
|
||||
} else {
|
||||
char hex[2];
|
||||
toHex(c,hex);
|
||||
*outptr++ = '%';
|
||||
@ -781,15 +801,6 @@ ncuriencode(char* s, char* allowable)
|
||||
/* Return a string representing decoding of input; caller must free;*/
|
||||
char*
|
||||
ncuridecode(char* s)
|
||||
{
|
||||
return ncuridecodeonly(s,NULL);
|
||||
}
|
||||
|
||||
/* Return a string representing decoding of input only for specified
|
||||
characters; caller must free
|
||||
*/
|
||||
char*
|
||||
ncuridecodeonly(char* s, char* only)
|
||||
{
|
||||
size_t slen;
|
||||
char* decoded;
|
||||
@ -805,7 +816,45 @@ ncuridecodeonly(char* s, char* only)
|
||||
outptr = decoded;
|
||||
inptr = s;
|
||||
while((c = (unsigned int)*inptr++)) {
|
||||
if(c == '+' && only != NULL && strchr(only,'+') != NULL)
|
||||
if(c == '%') {
|
||||
/* try to pull two hex more characters */
|
||||
if(inptr[0] != EOFCHAR && inptr[1] != EOFCHAR
|
||||
&& strchr(hexchars,inptr[0]) != NULL
|
||||
&& strchr(hexchars,inptr[1]) != NULL) {
|
||||
/* test conversion */
|
||||
int xc = (fromHex(inptr[0]) << 4) | (fromHex(inptr[1]));
|
||||
inptr += 2; /* decode it */
|
||||
c = (unsigned int)xc;
|
||||
}
|
||||
}
|
||||
*outptr++ = (char)c;
|
||||
}
|
||||
*outptr = EOFCHAR;
|
||||
return decoded;
|
||||
}
|
||||
|
||||
/*
|
||||
Partially decode a string. Only characters in 'decodeset'
|
||||
are decoded. Return decoded string; caller must free.
|
||||
*/
|
||||
char*
|
||||
ncuridecodepartial(char* s, const char* decodeset)
|
||||
{
|
||||
size_t slen;
|
||||
char* decoded;
|
||||
char* outptr;
|
||||
char* inptr;
|
||||
unsigned int c;
|
||||
|
||||
if (s == NULL || decodeset == NULL) return NULL;
|
||||
|
||||
slen = strlen(s);
|
||||
decoded = (char*)malloc(slen+1); /* Should be max we need */
|
||||
|
||||
outptr = decoded;
|
||||
inptr = s;
|
||||
while((c = (unsigned int)*inptr++)) {
|
||||
if(c == '+' && strchr(decodeset,'+') != NULL)
|
||||
*outptr++ = ' ';
|
||||
else if(c == '%') {
|
||||
/* try to pull two hex more characters */
|
||||
@ -814,13 +863,14 @@ ncuridecodeonly(char* s, char* only)
|
||||
&& strchr(hexchars,inptr[1]) != NULL) {
|
||||
/* test conversion */
|
||||
int xc = (fromHex(inptr[0]) << 4) | (fromHex(inptr[1]));
|
||||
if(only == NULL || strchr(only,xc) != NULL) {
|
||||
if(strchr(decodeset,xc) != NULL) {
|
||||
inptr += 2; /* decode it */
|
||||
c = (unsigned int)xc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*outptr++ = (char)c;
|
||||
*outptr++ = (char)c; /* pass either the % or decoded char */
|
||||
} else /* Not a % char */
|
||||
*outptr++ = (char)c;
|
||||
}
|
||||
*outptr = EOFCHAR;
|
||||
return decoded;
|
||||
|
@ -34,3 +34,4 @@ DAP4 Support: @HAS_DAP4@
|
||||
Diskless Support: @HAS_DISKLESS@
|
||||
MMap Support: @HAS_MMAP@
|
||||
JNA Support: @HAS_JNA@
|
||||
CDF5 Support: @HAS_CDF5@
|
||||
|
@ -95,9 +95,12 @@ err:
|
||||
int
|
||||
nc3_cktype(int mode, nc_type type)
|
||||
{
|
||||
#ifdef USE_CDF5
|
||||
if (mode & NC_CDF5) { /* CDF-5 format */
|
||||
if (type >= NC_BYTE && type < NC_STRING) return NC_NOERR;
|
||||
} else if (mode & NC_64BIT_OFFSET) { /* CDF-2 format */
|
||||
} else
|
||||
#endif
|
||||
if (mode & NC_64BIT_OFFSET) { /* CDF-2 format */
|
||||
if (type >= NC_BYTE && type <= NC_DOUBLE) return NC_NOERR;
|
||||
} else if ((mode & NC_64BIT_OFFSET) == 0) { /* CDF-1 format */
|
||||
if (type >= NC_BYTE && type <= NC_DOUBLE) return NC_NOERR;
|
||||
@ -1086,8 +1089,11 @@ nc_set_default_format(int format, int *old_formatp)
|
||||
format != NC_FORMAT_NETCDF4 && format != NC_FORMAT_NETCDF4_CLASSIC)
|
||||
return NC_EINVAL;
|
||||
#else
|
||||
if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT_OFFSET &&
|
||||
format != NC_FORMAT_CDF5)
|
||||
if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT_OFFSET
|
||||
#ifdef USE_CDF5
|
||||
&& format != NC_FORMAT_CDF5
|
||||
#endif
|
||||
)
|
||||
return NC_EINVAL;
|
||||
#endif
|
||||
default_create_format = format;
|
||||
@ -1582,9 +1588,12 @@ NC3_inq_format(int ncid, int *formatp)
|
||||
nc3 = NC3_DATA(nc);
|
||||
|
||||
/* only need to check for netCDF-3 variants, since this is never called for netCDF-4 files */
|
||||
#ifdef USE_CDF5
|
||||
if (fIsSet(nc3->flags, NC_64BIT_DATA))
|
||||
*formatp = NC_FORMAT_CDF5;
|
||||
else if (fIsSet(nc3->flags, NC_64BIT_OFFSET))
|
||||
else
|
||||
#endif
|
||||
if (fIsSet(nc3->flags, NC_64BIT_OFFSET))
|
||||
*formatp = NC_FORMAT_64BIT_OFFSET;
|
||||
else
|
||||
*formatp = NC_FORMAT_CLASSIC;
|
||||
|
@ -13,68 +13,78 @@ cc="@CMAKE_C_COMPILER@"
|
||||
cflags="-I@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@"
|
||||
libs="-L@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ @NC_LIBS@"
|
||||
|
||||
if [ -z "@USE_DAP@" -o -z "@ENABLE_DAP2@" ] ; then
|
||||
has_dap2=ON
|
||||
fi
|
||||
if [ -z $has_dap2 ]; then
|
||||
has_dap2="@ENABLE_DAP2@"
|
||||
if [ -z $has_dap2 -o "$has_dap2" = "OFF" ]; then
|
||||
has_dap2="no"
|
||||
else
|
||||
has_dap2="yes"
|
||||
fi
|
||||
|
||||
has_dap4="@ENABLE_DAP4"
|
||||
has_dap4="@ENABLE_DAP4@"
|
||||
if [ -z $has_dap4 -o "$has_dap4" = "OFF" ]; then
|
||||
has_dap4="no"
|
||||
else
|
||||
has_dap4="yes"
|
||||
fi
|
||||
|
||||
has_nc2="@BUILD_V2@"
|
||||
|
||||
|
||||
if [ -z $has_nc2 -o "$has_nc2" = "OFF" ]; then
|
||||
if [ -z "$has_nc2" -o "$has_nc2" = "OFF" ]; then
|
||||
has_nc2="no"
|
||||
else
|
||||
has_nc2="yes"
|
||||
fi
|
||||
|
||||
has_nc4="@USE_NETCDF4@"
|
||||
if [ -z $has_nc4 ]; then
|
||||
if [ -z "$has_nc4" -o "$has_nc4" = "OFF" ]; then
|
||||
has_nc4="no"
|
||||
else
|
||||
has_nc4="yes"
|
||||
fi
|
||||
|
||||
has_logging="@ENABLE_LOGGING@"
|
||||
if [ -z $has_logging ]; then
|
||||
if [ -z "$has_logging" -o "$has_logging" = "OFF" ]; then
|
||||
has_logging="no"
|
||||
else
|
||||
has_logging="yes"
|
||||
fi
|
||||
|
||||
has_hdf4="@USE_HDF4@"
|
||||
if [ -z $has_hdf4 ]; then
|
||||
if [ -z "$has_hdf4" -o "$has_hdf4" = "OFF" ]; then
|
||||
has_hdf4="no"
|
||||
else
|
||||
has_hdf4="yes"
|
||||
fi
|
||||
|
||||
has_pnetcdf="@USE_PNETCDF@"
|
||||
if [ -z $has_pnetcdf ]; then
|
||||
if [ -z "$has_pnetcdf" -o "$has_pnetcdf" = "OFF" ]; then
|
||||
has_pnetcdf="no"
|
||||
else
|
||||
has_pnetcdf="yes"
|
||||
fi
|
||||
|
||||
has_hdf5="@USE_HDF5@"
|
||||
if [ -z $has_hdf5 -o "$has_hdf5" = "OFF" ]; then
|
||||
if [ -z "$has_hdf5" -o "$has_hdf5" = "OFF" ]; then
|
||||
has_hdf5="no"
|
||||
else
|
||||
has_hdf5="yes"
|
||||
fi
|
||||
|
||||
has_szlib="@USE_SZLIB@"
|
||||
if [ -z $has_szlib ]; then
|
||||
if [ -z "$has_szlib" -o "$has_szlib" = "OFF" ]; then
|
||||
has_szlib="no"
|
||||
else
|
||||
has_szlib="yes"
|
||||
fi
|
||||
|
||||
has_cdf5="@ENABLE_CDF5@"
|
||||
if [ -z "has_cdf5" -o "$has_cdf5" = "OFF" -o "$has_cdf5" = "FALSE" ]; then
|
||||
has_cdf5="no"
|
||||
else
|
||||
has_cdf5="yes"
|
||||
fi
|
||||
|
||||
|
||||
version="@PACKAGE@ @VERSION@"
|
||||
|
||||
@ -128,7 +138,7 @@ Available values for OPTION include:
|
||||
--has-fortran whether Fortran API is installed
|
||||
--has-dap2 whether OPeNDAP (DAP2) is enabled in this build
|
||||
--has-dap4 whether DAP4 is enabled in this build
|
||||
--has-dap same as --has-dp (Deprecated)
|
||||
--has-dap same as --has-dap2 (Deprecated)
|
||||
--has-nc2 whether NetCDF-2 API is enabled
|
||||
--has-nc4 whether NetCDF-4/HDF-5 is enabled in this build
|
||||
--has-hdf5 whether HDF5 is used in build (always the same as --has-nc4)
|
||||
@ -136,6 +146,7 @@ Available values for OPTION include:
|
||||
--has-logging whether logging is enabled with --enable-logging.
|
||||
--has-pnetcdf whether parallel-netcdf (a.k.a. pnetcdf) was used in build
|
||||
--has-szlib whether szlib is included in build
|
||||
--has-cdf5 whether cdf5 support is included in build
|
||||
--libs library linking information for netcdf
|
||||
--prefix Install prefix
|
||||
--includedir Include directory
|
||||
@ -202,7 +213,7 @@ if [ -f "$nfconf" ]; then
|
||||
echo " --has-f03 -> $has_f03"
|
||||
echo
|
||||
fi
|
||||
echo " --has-dap -> $has_dap"
|
||||
echo " --has-dap -> $has_dap2"
|
||||
echo " --has-dap2 -> $has_dap2"
|
||||
echo " --has-dap4 -> $has_dap4"
|
||||
echo " --has-nc2 -> $has_nc2"
|
||||
@ -212,6 +223,7 @@ fi
|
||||
echo " --has-logging-> $has_logging"
|
||||
echo " --has-pnetcdf-> $has_pnetcdf"
|
||||
echo " --has-szlib -> $has_szlib"
|
||||
echo " --has-cdf5 -> $has_cdf5"
|
||||
echo
|
||||
echo " --prefix -> $prefix"
|
||||
echo " --includedir-> $includedir"
|
||||
@ -252,7 +264,7 @@ while test $# -gt 0; do
|
||||
;;
|
||||
|
||||
--has-dap)
|
||||
echo $has_dap2 $has_dap4
|
||||
echo $has_dap2
|
||||
;;
|
||||
|
||||
--has-dap2)
|
||||
@ -291,6 +303,10 @@ while test $# -gt 0; do
|
||||
echo $has_szlib
|
||||
;;
|
||||
|
||||
--has-cdf5)
|
||||
echo $has_cdf5
|
||||
;;
|
||||
|
||||
--libs)
|
||||
echo $libs
|
||||
;;
|
||||
|
12
nc-config.in
12
nc-config.in
@ -21,8 +21,12 @@ has_hdf4="@HAS_HDF4@"
|
||||
has_pnetcdf="@HAS_PNETCDF@"
|
||||
has_hdf5="@HAS_HDF5@"
|
||||
has_logging="@HAS_LOGGING@"
|
||||
has_cdf5="@HAS_CDF5@"
|
||||
has_szlib="@HAS_SZLIB@"
|
||||
version="@PACKAGE_NAME@ @PACKAGE_VERSION@"
|
||||
|
||||
|
||||
|
||||
has_fortran="no"
|
||||
has_f90="no"
|
||||
has_f03="no"
|
||||
@ -79,8 +83,9 @@ Available values for OPTION include:
|
||||
--has-logging whether logging is enabled with --enable-logging.
|
||||
--has-pnetcdf whether parallel-netcdf (a.k.a. pnetcdf) was used in build
|
||||
--has-szlib whether szlib is included in build
|
||||
--has-cdf5 whether cdf5 support is included in build
|
||||
--libs library linking information for netcdf
|
||||
--prefix Install prefix
|
||||
--prefix Install prefixx
|
||||
--includedir Include directory
|
||||
--libdir Library directory
|
||||
--version Library version
|
||||
@ -154,6 +159,7 @@ fi
|
||||
echo " --has-logging-> $has_logging"
|
||||
echo " --has-pnetcdf-> $has_pnetcdf"
|
||||
echo " --has-szlib -> $has_szlib"
|
||||
echo " --has-cdf5 -> $has_cdf5"
|
||||
echo
|
||||
echo " --prefix -> $prefix"
|
||||
echo " --includedir-> $includedir"
|
||||
@ -229,6 +235,10 @@ while test $# -gt 0; do
|
||||
echo $has_szlib
|
||||
;;
|
||||
|
||||
--has-cdf5)
|
||||
echo $has_cdf5
|
||||
;;
|
||||
|
||||
--libs)
|
||||
echo $libs
|
||||
;;
|
||||
|
@ -9,6 +9,8 @@ int numVars; /* number of variables */
|
||||
int numTypes; /* number of netCDF data types to test */
|
||||
|
||||
#include "tests.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
/*
|
||||
* Test driver for netCDF-3 interface. This program performs tests against
|
||||
@ -130,14 +132,19 @@ main(int argc, char *argv[])
|
||||
fprintf(stderr, "\n\nSwitching to 64-bit offset format.\n");
|
||||
strcpy(testfile, "nc_test_64bit.nc");
|
||||
break;
|
||||
|
||||
case NC_FORMAT_CDF5:
|
||||
nc_set_default_format(NC_FORMAT_CDF5, NULL);
|
||||
#ifdef USE_CDF5
|
||||
nc_set_default_format(NC_FORMAT_CDF5, NULL);
|
||||
fprintf(stderr, "\n\nSwitching to 64-bit data format.\n");
|
||||
strcpy(testfile, "nc_test_cdf5.nc");
|
||||
numGatts = NGATTS;
|
||||
numVars = NVARS;
|
||||
numTypes = NTYPES;
|
||||
break;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
case NC_FORMAT_NETCDF4_CLASSIC:
|
||||
case NC_FORMAT_NETCDF4: /* actually it's _CLASSIC. */
|
||||
#ifdef USE_NETCDF4
|
||||
|
@ -33,6 +33,7 @@ dnl
|
||||
#endif
|
||||
|
||||
#include "tests.h"
|
||||
#include "config.h"
|
||||
#include "math.h"
|
||||
|
||||
define(`EXPECT_ERR',`error("expecting $1 but got %s",nc_err_code_name($2));')dnl
|
||||
@ -2405,8 +2406,11 @@ APIFunc(get_file_version)(char *path, int *version)
|
||||
|
||||
if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0) {
|
||||
if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC ||
|
||||
magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET ||
|
||||
magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5)
|
||||
magic[MAGIC_NUM_LEN-1] == NC_FORMAT_64BIT_OFFSET
|
||||
#ifdef USE_CDF5
|
||||
|| magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF5
|
||||
#endif
|
||||
)
|
||||
*version = magic[MAGIC_NUM_LEN-1];
|
||||
else
|
||||
return NC_ENOTNC;
|
||||
@ -2449,8 +2453,8 @@ TestFunc(set_default_format)(void)
|
||||
ELSE_NOK
|
||||
|
||||
/* Cycle through available formats. */
|
||||
for(i=NC_FORMAT_CLASSIC; i<NC_FORMAT_64BIT_DATA; i++)
|
||||
{
|
||||
|
||||
for(i=NC_FORMAT_CLASSIC; i<NC_FORMAT_64BIT_DATA; i++) {
|
||||
if (i == NC_FORMAT_NETCDF4 || i == NC_FORMAT_NETCDF4_CLASSIC)
|
||||
continue; /* test classic formats only */
|
||||
if ((err = APIFunc(set_default_format)(i, NULL)))
|
||||
|
@ -54,8 +54,11 @@ static int file_create(const char *filename, int cmode, int *ncid)
|
||||
|
||||
#ifdef USE_PNETCDF
|
||||
if (default_format == NC_FORMAT_CLASSIC ||
|
||||
default_format == NC_FORMAT_64BIT_OFFSET ||
|
||||
default_format == NC_FORMAT_64BIT_DATA)
|
||||
default_format == NC_FORMAT_64BIT_OFFSET
|
||||
#ifdef USE_CDF5
|
||||
|| default_format == NC_FORMAT_64BIT_DATA
|
||||
#endif
|
||||
)
|
||||
err = nc_create_par(filename, cmode|NC_PNETCDF, MPI_COMM_WORLD, MPI_INFO_NULL, ncid);
|
||||
else
|
||||
#endif
|
||||
@ -522,11 +525,16 @@ main(int argc, char **argv)
|
||||
printf("Switching to 64-bit offset format.\n");
|
||||
strcpy(testfile, "tst_small_64bit.nc");
|
||||
break;
|
||||
#ifdef USE_CDF5
|
||||
case NC_FORMAT_CDF5:
|
||||
nc_set_default_format(NC_FORMAT_CDF5, NULL);
|
||||
printf("Switching to 64-bit data format.\n");
|
||||
strcpy(testfile, "tst_small_cdf5.nc");
|
||||
break;
|
||||
#else
|
||||
case NC_FORMAT_CDF5:
|
||||
continue;
|
||||
#endif
|
||||
#ifdef USE_NETCDF4
|
||||
case NC_FORMAT_NETCDF4_CLASSIC:
|
||||
nc_set_default_format(NC_FORMAT_NETCDF4_CLASSIC, NULL);
|
||||
|
@ -10,7 +10,7 @@ SET(NC4_TESTS tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars
|
||||
tst_vars2 tst_files5 tst_files6 tst_sync tst_h_strbug tst_h_refs
|
||||
tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite
|
||||
tst_put_vars_two_unlim_dim tst_hdf5_file_compat tst_fill_attr_vanish
|
||||
tst_rehash)
|
||||
tst_rehash tst_filterparser)
|
||||
|
||||
# Note, renamegroup needs to be compiled before run_grp_rename
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Test c output
|
||||
T=tst_szip
|
||||
T=tst_filterparser
|
||||
#CMD=valgrind --leak-check=full
|
||||
CMD=gdb --args
|
||||
|
||||
|
@ -22,7 +22,7 @@ tst_xplatform tst_xplatform2 tst_h_atts2 tst_endian_fill tst_atts \
|
||||
t_type cdm_sea_soundings tst_camrun tst_vl tst_atts1 tst_atts2 \
|
||||
tst_vars2 tst_files5 tst_files6 tst_sync \
|
||||
tst_h_scalar tst_rename tst_h5_endians tst_atts_string_rewrite \
|
||||
tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash
|
||||
tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash tst_filterparser
|
||||
|
||||
# Temporary I hope
|
||||
if !ISCYGWIN
|
||||
@ -167,7 +167,6 @@ MYD29.A2009152.0000.005.2009153124331.hdf \
|
||||
MYD29.A2002185.0000.005.2007160150627.hdf \
|
||||
MOD29.A2000055.0005.005.2006267200024.hdf
|
||||
|
||||
|
||||
endif # HDF4_FILE_TESTS
|
||||
|
||||
SUBDIRS=filter_test
|
||||
|
38
nc_test4/filter_test/Make0
Normal file
38
nc_test4/filter_test/Make0
Normal file
@ -0,0 +1,38 @@
|
||||
# Test c output
|
||||
T=test_filter
|
||||
#CMD=valgrind --leak-check=full
|
||||
CMD=gdb --args
|
||||
|
||||
EXECDIR=../..
|
||||
SRCDIR=../..
|
||||
|
||||
#PAR=1
|
||||
SZIP=1
|
||||
|
||||
CFLAGS = -Wall -Wno-unused-variable -Wno-unused-function -g -O0 -I${SRCDIR} -I${SRCDIR}/include
|
||||
|
||||
LDFLAGS = ${EXECDIR}/liblib/.libs/libnetcdf.a -L/usr/local/lib -lhdf5_hl -lhdf5 -lz -ldl -lcurl -lm
|
||||
|
||||
ifdef PAR
|
||||
CC=mpicc
|
||||
LDFLAGS += -lmpich
|
||||
else
|
||||
CC=gcc
|
||||
endif
|
||||
|
||||
ifdef SZIP
|
||||
LDFLAGS += -lsz -laec
|
||||
endif
|
||||
|
||||
LLP=/usr/local/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
all:: cmp
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CMD} ./t
|
||||
|
||||
cmp::
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${LDFLAGS}
|
||||
|
||||
cpp::
|
||||
${CC} -E ${CFLAGS} ${T}.c > ${T}.txt
|
@ -54,7 +54,8 @@ HDF5LIBDIR = /usr/local/lib
|
||||
# Ditto for zlib
|
||||
ZLIBDIR = ${HDF5LIBDIR}
|
||||
|
||||
makebzip2::
|
||||
BUILT_SOURCES = ${LIBNAME}
|
||||
${LIBNAME}:
|
||||
SDIR=${srcdir} ;\
|
||||
for f in ${PLUGINSRC} ${BZIP2SRC} ; do \
|
||||
DLLSRC="$${DLLSRC} $${SDIR}/$$f" ; \
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netcdf.h>
|
||||
#include <netcdf_filter.h>
|
||||
|
||||
|
||||
static size_t var_chunksizes[4] = {4, 4, 4, 4} ;
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "netcdf.h"
|
||||
#include "netcdf_filter.h"
|
||||
|
||||
//#define BASELINE 1
|
||||
|
||||
@ -102,6 +101,8 @@ check(int err,int line)
|
||||
{
|
||||
if(err != NC_NOERR) {
|
||||
fprintf(stderr,"fail (%d): %s\n",line,nc_strerror(err));
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "nc_tests.h"
|
||||
#include "err_macros.h"
|
||||
#include "netcdf.h"
|
||||
#include "netcdf_filter.h"
|
||||
|
||||
#undef PLAIN
|
||||
#define USECLOSE
|
||||
|
292
nc_test4/tst_filterparser.c
Normal file
292
nc_test4/tst_filterparser.c
Normal file
@ -0,0 +1,292 @@
|
||||
|
||||
/*
|
||||
Copyright 2008, UCAR/Unidata
|
||||
See COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "netcdf.h"
|
||||
#include "ncfilter.h"
|
||||
|
||||
#undef USE_INTERNAL
|
||||
|
||||
#define PARAMS_ID 32768
|
||||
|
||||
static const unsigned int baseline[] = {
|
||||
-17, /*0 signed int*/
|
||||
23, /*1 unsigned int*/
|
||||
-25, /*2 signed int*/
|
||||
27, /*3 unsigned int*/
|
||||
77, /*4 signed int*/
|
||||
93, /*5 unsigned int*/
|
||||
1145389056U, /*6 float*/
|
||||
697067329, 2723935171, /*7-8 double*/
|
||||
128, 16777216, /*9-10 signed long long*/
|
||||
4294967295, 4294967295, /*11-12 unsigned long long*/
|
||||
/* Edge cases */
|
||||
2147483647, /*13 max signed int*/
|
||||
-2147483648, /*14 min signed int*/
|
||||
4294967295 /*15 max unsigned int with no trailing U*/
|
||||
};
|
||||
|
||||
static const char* spec =
|
||||
"32768, -17b, 23ub, -25S, 27US, 77, 93U, 789f, 12345678.12345678d, -9223372036854775807L, 18446744073709551615UL, 2147483647, -2147483648, 4294967295";
|
||||
|
||||
/* Test support for the conversions */
|
||||
/* Not sure if this kind of casting via union is legal C99 */
|
||||
static union {
|
||||
unsigned int ui;
|
||||
float f;
|
||||
} uf;
|
||||
|
||||
static union {
|
||||
unsigned int ui[2];
|
||||
double d;
|
||||
} ud;
|
||||
|
||||
static union {
|
||||
unsigned int ui[2];
|
||||
unsigned long long ull;
|
||||
long long ll;
|
||||
} ul;
|
||||
|
||||
static int nerrs = 0;
|
||||
|
||||
#ifdef USE_INTERNAL
|
||||
static int parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);
|
||||
#endif
|
||||
|
||||
static void byteswap8(unsigned char* mem);
|
||||
|
||||
static void
|
||||
report(const char* which)
|
||||
{
|
||||
fprintf(stderr,"mismatch: %s\n",which);
|
||||
fflush(stderr);
|
||||
nerrs++;
|
||||
}
|
||||
|
||||
static void
|
||||
mismatch(size_t i, unsigned int baseline, unsigned int params)
|
||||
{
|
||||
fprintf(stderr,"mismatch: [%d] baseline=%ud spec=%ud\n",i,baseline,params);
|
||||
fflush(stderr);
|
||||
nerrs++;
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int stat = 0;
|
||||
unsigned int id = 0;
|
||||
size_t i,nparams = 0;
|
||||
unsigned int* params = NULL;
|
||||
|
||||
#ifdef USE_INTERNAL
|
||||
stat = parsefilterspec(spec,&id,&nparams,¶ms);
|
||||
#else
|
||||
stat = NC_parsefilterspec(spec,&id,&nparams,¶ms);
|
||||
#endif
|
||||
if(!stat) {
|
||||
report("NC_parsefilterspec failed");
|
||||
exit(1);
|
||||
}
|
||||
for(i=0;i<nparams;i++) {
|
||||
if(baseline[i] != params[i])
|
||||
mismatch(i,baseline[i],params[i]);
|
||||
}
|
||||
/* Now some specialized tests */
|
||||
uf.ui = params[6];
|
||||
if(uf.f != (float)789.0)
|
||||
report("uf.f");
|
||||
ud.ui[0] = params[7];
|
||||
ud.ui[1] = params[8];
|
||||
#ifndef WORD_BIGENDIAN
|
||||
byteswap8((unsigned char*)&ud.d);
|
||||
#endif
|
||||
if(ud.d != (double)12345678.12345678)
|
||||
report("ud.d");
|
||||
ul.ui[0] = params[9];
|
||||
ul.ui[1] = params[10];
|
||||
#ifndef WORD_BIGENDIAN
|
||||
byteswap8((unsigned char*)&ul.ll);
|
||||
#endif
|
||||
if(ul.ll != -9223372036854775807LL)
|
||||
report("ul.ll");
|
||||
ul.ui[0] = params[11];
|
||||
ul.ui[1] = params[12];
|
||||
#ifndef WORD_BIGENDIAN
|
||||
byteswap8((unsigned char*)&ul.ull);
|
||||
#endif
|
||||
if(ul.ull != 18446744073709551615ULL)
|
||||
report("ul.ull");
|
||||
|
||||
return (nerrs > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
/* Byte swap an 8-byte integer in place */
|
||||
static void
|
||||
byteswap8(unsigned char* mem)
|
||||
{
|
||||
unsigned char c;
|
||||
c = mem[0];
|
||||
mem[0] = mem[7];
|
||||
mem[7] = c;
|
||||
c = mem[1];
|
||||
mem[1] = mem[6];
|
||||
mem[6] = c;
|
||||
c = mem[2];
|
||||
mem[2] = mem[5];
|
||||
mem[5] = c;
|
||||
c = mem[3];
|
||||
mem[3] = mem[4];
|
||||
mem[4] = c;
|
||||
}
|
||||
|
||||
#ifdef USE_INTERNAL
|
||||
static int
|
||||
parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp)
|
||||
{
|
||||
char* p;
|
||||
char* sdata = NULL;
|
||||
int stat;
|
||||
unsigned int uval, id;
|
||||
size_t count; /* no. of comma delimited params */
|
||||
size_t nparams; /* final no. of unsigned ints */
|
||||
size_t i;
|
||||
unsigned int* ulist = NULL;
|
||||
unsigned char mem[8]; /* to convert to network byte order */
|
||||
|
||||
if(spec == NULL || strlen(spec) == 0) goto fail;
|
||||
sdata = strdup(spec);
|
||||
|
||||
/* Count number of parameters + id and delimit */
|
||||
p=sdata;
|
||||
for(count=0;;count++) {
|
||||
char* q = strchr(p,',');
|
||||
if(q == NULL) break;
|
||||
*q++ = '\0';
|
||||
p = q;
|
||||
}
|
||||
count++; /* for final piece */
|
||||
|
||||
if(count == 0)
|
||||
goto fail; /* no id and no parameters */
|
||||
|
||||
/* Extract the filter id */
|
||||
p = sdata;
|
||||
stat = sscanf(p,"%u",&id);
|
||||
if(stat != 1) goto fail;
|
||||
p = p + strlen(p) + 1; /* skip the filter id */
|
||||
count--;
|
||||
|
||||
/* Allocate the max needed space; *2 in case the params are all doubles */
|
||||
ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count)*2);
|
||||
if(ulist == NULL) goto fail;
|
||||
|
||||
/* walk and convert */
|
||||
nparams = 0;
|
||||
for(i=0;i<count;i++) {
|
||||
char* q;
|
||||
unsigned long long val64u;
|
||||
unsigned int val32u;
|
||||
double vald;
|
||||
float valf;
|
||||
unsigned int *vector;
|
||||
int isunsigned;
|
||||
int isnegative;
|
||||
int type;
|
||||
|
||||
/* Get trailing discrimination characters */
|
||||
isunsigned = 0;
|
||||
isnegative = 0;
|
||||
type = 0;
|
||||
if(strchr(p,'-') != NULL) isnegative = 1;
|
||||
q = p+strlen(p)-2;
|
||||
if(*q == 'U' || *q == 'u') isunsigned = 1;
|
||||
q++;
|
||||
switch (*q) {
|
||||
case 'f': case 'F': type = 'f'; break; /* short */
|
||||
case 'd': case 'D': type = 'd'; break; /* double */
|
||||
case 'b': case 'B': type = 'b'; break; /* byte */
|
||||
case 's': case 'S': type = 's'; break; /* short */
|
||||
case 'l': case 'L': type = 'l'; break; /* long long */
|
||||
case 'u': case 'U': type = 'i'; isunsigned = 1; break; /* integer */
|
||||
case '.':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9': type = 'i'; break;
|
||||
default:
|
||||
if(*q == '\0')
|
||||
type = 'i';
|
||||
else goto fail;
|
||||
}
|
||||
/* Now parse */
|
||||
switch (type) {
|
||||
case 'b':
|
||||
case 's':
|
||||
case 'i':
|
||||
/* special case for a positive integer;for back compatibility.*/
|
||||
if(!isnegative)
|
||||
stat = sscanf(p,"%u",&val32u);
|
||||
else
|
||||
stat = sscanf(p,"%d",(int*)&val32u);
|
||||
if(stat != 1) goto fail;
|
||||
ulist[nparams++] = val32u;
|
||||
break;
|
||||
case 'f':
|
||||
stat = sscanf(p,"%lf",&vald);
|
||||
if(stat != 1) goto fail;
|
||||
valf = (float)vald;
|
||||
ulist[nparams++] = *(unsigned int*)&valf;
|
||||
break;
|
||||
case 'd':
|
||||
stat = sscanf(p,"%lf",&vald);
|
||||
if(stat != 1) goto fail;
|
||||
/* convert to network byte order */
|
||||
memcpy(mem,&vald,sizeof(mem));
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
byteswap8(mem); /* convert little endian to big endian */
|
||||
#endif
|
||||
vector = (unsigned int*)mem;
|
||||
ulist[nparams++] = vector[0];
|
||||
ulist[nparams++] = vector[1];
|
||||
break;
|
||||
case 'l': /* long long */
|
||||
if(isunsigned)
|
||||
stat = sscanf(p,"%llu",&val64u);
|
||||
else
|
||||
stat = sscanf(p,"%lld",(long long*)&val64u);
|
||||
if(stat != 1) goto fail;
|
||||
/* convert to network byte order */
|
||||
memcpy(mem,&val64u,sizeof(mem));
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
byteswap8(mem); /* convert little endian to big endian */
|
||||
#endif
|
||||
vector = (unsigned int*)mem;
|
||||
ulist[nparams++] = vector[0];
|
||||
ulist[nparams++] = vector[1];
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
p = p + strlen(p) + 1; /* move to next param */
|
||||
}
|
||||
/* Now return results */
|
||||
if(idp) *idp = id;
|
||||
if(nparamsp) *nparamsp = nparams;
|
||||
if(paramsp) *paramsp = ulist;
|
||||
ulist = NULL; /* avoid duplicate free */
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 1;
|
||||
fail:
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 0;
|
||||
}
|
||||
#endif /*USE_INTERNAL*/
|
@ -131,6 +131,7 @@ ENDIF()
|
||||
ENDIF(USE_NETCDF4)
|
||||
|
||||
add_sh_test(ncdump tst_nccopy3)
|
||||
add_sh_test(ncdump tst_nccopy3_subset)
|
||||
add_sh_test(ncdump tst_charfill)
|
||||
|
||||
add_sh_test(ncdump tst_formatx3)
|
||||
|
@ -43,7 +43,7 @@ check_PROGRAMS = rewrite-scalar ctest ctest64 ncdump tst_utf8 bom tst_dimsizes n
|
||||
|
||||
TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ctest ctest64 tst_output.sh \
|
||||
tst_lengths.sh tst_calendars.sh tst_utf8 run_utf8_tests.sh \
|
||||
tst_nccopy3.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
|
||||
tst_nccopy3.sh tst_nccopy3_subset.sh tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
|
||||
tst_dimsizes.sh run_ncgen_tests.sh
|
||||
|
||||
if USE_NETCDF4
|
||||
@ -62,6 +62,10 @@ TESTS += tst_inmemory_nc4.sh
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_NETCDF4
|
||||
TESTS += tst_inttags4.sh
|
||||
endif
|
||||
|
||||
if USE_NETCDF4
|
||||
# NetCDF-4 has some extra tests.
|
||||
check_PROGRAMS += tst_create_files tst_h_rdc0 tst_group_data \
|
||||
@ -69,7 +73,7 @@ tst_enum_data tst_opaque_data tst_string_data tst_vlen_data tst_comp \
|
||||
tst_comp2 tst_nans tst_special_atts tst_unicode tst_fillbug tst_compress \
|
||||
tst_chunking tst_h_scalar tst_bug324
|
||||
|
||||
TESTS += tst_inttags4.sh tst_create_files tst_group_data tst_enum_data tst_opaque_data \
|
||||
TESTS += tst_create_files tst_group_data tst_enum_data tst_opaque_data \
|
||||
tst_string_data tst_vlen_data tst_comp tst_comp2 tst_nans \
|
||||
tst_special_atts tst_netcdf4.sh tst_h_rdc0 tst_unicode tst_fillbug \
|
||||
tst_fillbug.sh tst_netcdf4_4.sh tst_compress tst_nccopy4.sh \
|
||||
@ -110,7 +114,10 @@ endif
|
||||
|
||||
endif BUILD_TESTSETS
|
||||
|
||||
CLEANFILES = test0.nc test1.cdl test1.nc test2.cdl ctest1.cdl \
|
||||
CLEANFILES = test0.nc test1_ncdump.cdl test1_ncdump.nc test2_ncdump.cdl \
|
||||
test1.cdl test0_ncdump.nc ctest1.cdl \
|
||||
test1_cdf5.nc test1_cdf5.cdl test0_cdf5.nc test2_cdf5.nc test2_cdf5.cdl \
|
||||
test0_offset.nc test1_offset.nc test1_offset.cdl test2_offset.nc test2_offset.cdl \
|
||||
ctest0.nc ctest0_64.nc c1.cdl c1_4.cdl ctest1_64.cdl c0.nc c0_4.nc small.nc \
|
||||
small2.nc c0tmp.nc c1.ncml utf8.cdl utf8_64.cdl utf8.nc utf8_64.nc \
|
||||
tmp.cdl tst_vlen_data.nc tst_utf8.nc tst_special_atts.nc \
|
||||
@ -135,10 +142,10 @@ tst_dimsize_classic.nc tst_dimsize_64offset.nc tst_dimsize_64data.nc \
|
||||
nc4_fileinfo.nc hdf5_fileinfo.hdf \
|
||||
ref_hdf5_compat1.nc ref_hdf5_compat2.nc ref_hdf5_compat3.nc \
|
||||
ref_tst_compounds.nc ref_tst_dims.nc ref_tst_interops4.nc \
|
||||
ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc
|
||||
ref_tst_xplatform2_1.nc ref_tst_xplatform2_2.nc nccopy3_subset_out.nc
|
||||
|
||||
# These files all have to be included with the distribution.
|
||||
EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
|
||||
EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
|
||||
ref_ctest1_nc4.cdl ref_ctest1_nc4c.cdl ref_tst_solar_1.cdl \
|
||||
ref_tst_solar_2.cdl tst_netcdf4.sh tst_netcdf4_4.sh ref_tst_small.cdl \
|
||||
tst_lengths.sh tst_ncml.cdl ref1.ncml ref_tst_group_data.cdl \
|
||||
@ -164,7 +171,7 @@ tst_formatx3.sh tst_formatx4.sh ref_tst_utf8_4.cdl \
|
||||
tst_inttags.sh tst_inttags4.sh \
|
||||
CMakeLists.txt XGetopt.c tst_bom.sh tst_inmemory_nc3.sh \
|
||||
tst_dimsizes.sh tst_inmemory_nc4.sh tst_fileinfo.sh run_ncgen_tests.sh \
|
||||
run_ncgen_nc4_tests.sh
|
||||
run_ncgen_nc4_tests.sh tst_nccopy3_subset.sh ref_nccopy3_subset.nc
|
||||
|
||||
# CDL files and Expected results
|
||||
SUBDIRS=cdl expected
|
||||
@ -177,7 +184,7 @@ CLEANFILES += results/*.nc results/*.dmp results/*.dmp2 tmp*.cdl \
|
||||
tst_c0_64.cdl tst_compound_datasize_test.cdl \
|
||||
tst_compound_datasize_test2.cdl tst_gattenum.nc \
|
||||
tst_ncf199.cdl tst_tst_gattenum.cdl tst_tst_usuffix.cdl \
|
||||
tst_usuffix.nc tst_bug324.nc
|
||||
tst_usuffix.nc tst_bug324.nc nccopy3_subset_out.nc
|
||||
|
||||
DISTCLEANFILES = results
|
||||
|
||||
|
217
ncdump/nccopy.c
217
ncdump/nccopy.c
@ -1,7 +1,7 @@
|
||||
/*********************************************************************
|
||||
* Copyright 2010, University Corporation for Atmospheric Research
|
||||
* See netcdf/README file for copying and redistribution conditions.
|
||||
* Thanks to Philippe Poilbarbe and Antonio S. Cofiño for
|
||||
* Thanks to Philippe Poilbarbe and Antonio S. Cofiño for
|
||||
* compression additions.
|
||||
* $Id: nccopy.c 400 2010-08-27 21:02:52Z russ $
|
||||
*********************************************************************/
|
||||
@ -17,14 +17,12 @@
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "netcdf.h"
|
||||
#ifdef USE_NETCDF4
|
||||
#include "netcdf_filter.h"
|
||||
#endif
|
||||
#include "nciter.h"
|
||||
#include "utils.h"
|
||||
#include "chunkspec.h"
|
||||
#include "dimmap.h"
|
||||
#include "nccomps.h"
|
||||
#include "ncfilter.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "XGetopt.h"
|
||||
@ -230,18 +228,17 @@ done:
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
{
|
||||
char* p;
|
||||
char* q;
|
||||
char* optarg = NULL;
|
||||
unsigned int* params = NULL;
|
||||
size_t nparams;
|
||||
unsigned int id;
|
||||
char* p = NULL;
|
||||
char* remainder = NULL;
|
||||
unsigned int params[MAX_FILTER_PARAMS];
|
||||
int nparams = 0;
|
||||
|
||||
if(optarg0 == NULL || strlen(optarg0) == 0) return 0;
|
||||
|
||||
if(optarg0 == NULL || strlen(optarg0) == 0 || spec == NULL) return 0;
|
||||
optarg = strdup(optarg0);
|
||||
|
||||
/* Collect the fqn, taking escapes into account */
|
||||
@ -263,37 +260,14 @@ parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
strcat(spec->fqn,optarg);
|
||||
}
|
||||
|
||||
/* Get filterid */
|
||||
q = (p = remainder);
|
||||
for(;;) {
|
||||
if(*p == ',') {*p = '\0'; remainder = p+1; break;}
|
||||
else if(*p == '\0') {remainder = p; break;}
|
||||
else if(strchr("0123456789",*p) == NULL) return 0; /* not a number */
|
||||
/* else continue */
|
||||
p++;
|
||||
/* Collect the id+parameters */
|
||||
if(!NC_parsefilterspec(remainder,&id,&nparams,¶ms))
|
||||
return 0;
|
||||
if(spec != NULL) {
|
||||
spec->filterid = id;
|
||||
spec->nparams = nparams;
|
||||
spec->params = params;
|
||||
}
|
||||
if(strlen(q) == 0) return 0; /* id does not exist */
|
||||
sscanf(q,"%u",&spec->filterid);
|
||||
|
||||
/* Collect the parameters */
|
||||
q = (p = remainder);
|
||||
for(;;) {
|
||||
int c = *p;
|
||||
if(c == ',' || c == '\0') {
|
||||
unsigned int parm;
|
||||
*p++ = '\0';
|
||||
if(strlen(q) == 0) return 0; /* bad param */
|
||||
sscanf(q,"%u",&parm);
|
||||
params[nparams++] = parm;
|
||||
q = p;
|
||||
if(c == '\0') break;
|
||||
} else if(strchr("0123456789",*p) == NULL) return 0; /* not a number */
|
||||
/* else continue */
|
||||
p++;
|
||||
}
|
||||
spec->nparams = nparams;
|
||||
spec->params = (unsigned int*)malloc(sizeof(unsigned int)*nparams);
|
||||
memcpy(spec->params,params,(sizeof(unsigned int)*nparams));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -412,14 +386,14 @@ inq_var_chunking_params(int igrp, int ivarid, int ogrp, int ovarid,
|
||||
/* Forward declaration, because copy_type, copy_vlen_type call each other */
|
||||
static int copy_type(int igrp, nc_type typeid, int ogrp);
|
||||
|
||||
/*
|
||||
/*
|
||||
* copy a user-defined variable length type in the group igrp to the
|
||||
* group ogrp
|
||||
*/
|
||||
static int
|
||||
copy_vlen_type(int igrp, nc_type itype, int ogrp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int stat = NC_NOERR;
|
||||
nc_type ibasetype;
|
||||
nc_type obasetype; /* base type in target group */
|
||||
char name[NC_MAX_NAME];
|
||||
@ -446,13 +420,13 @@ copy_vlen_type(int igrp, nc_type itype, int ogrp)
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* copy a user-defined opaque type in the group igrp to the group ogrp
|
||||
*/
|
||||
static int
|
||||
copy_opaque_type(int igrp, nc_type itype, int ogrp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int stat = NC_NOERR;
|
||||
nc_type otype;
|
||||
char name[NC_MAX_NAME];
|
||||
size_t size;
|
||||
@ -463,13 +437,13 @@ copy_opaque_type(int igrp, nc_type itype, int ogrp)
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* copy a user-defined enum type in the group igrp to the group ogrp
|
||||
*/
|
||||
static int
|
||||
copy_enum_type(int igrp, nc_type itype, int ogrp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int stat = NC_NOERR;
|
||||
nc_type otype;
|
||||
nc_type basetype;
|
||||
size_t basesize;
|
||||
@ -488,13 +462,13 @@ copy_enum_type(int igrp, nc_type itype, int ogrp)
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* copy a user-defined compound type in the group igrp to the group ogrp
|
||||
*/
|
||||
static int
|
||||
copy_compound_type(int igrp, nc_type itype, int ogrp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int stat = NC_NOERR;
|
||||
char name[NC_MAX_NAME];
|
||||
size_t size;
|
||||
size_t nfields;
|
||||
@ -522,7 +496,7 @@ copy_compound_type(int igrp, nc_type itype, int ogrp)
|
||||
} else { /* field is array type */
|
||||
int *fdimsizes;
|
||||
fdimsizes = (int *) emalloc((fndims + 1) * sizeof(int));
|
||||
stat = nc_inq_compound_field(igrp, itype, fid, NULL, NULL, NULL,
|
||||
stat = nc_inq_compound_field(igrp, itype, fid, NULL, NULL, NULL,
|
||||
NULL, fdimsizes);
|
||||
NC_CHECK(nc_insert_array_compound(ogrp, otype, fname, foff, oftype, fndims, fdimsizes));
|
||||
free(fdimsizes);
|
||||
@ -532,13 +506,13 @@ copy_compound_type(int igrp, nc_type itype, int ogrp)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* copy a user-defined type in the group igrp to the group ogrp
|
||||
*/
|
||||
static int
|
||||
copy_type(int igrp, nc_type typeid, int ogrp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int stat = NC_NOERR;
|
||||
nc_type type_class;
|
||||
|
||||
NC_CHECK(nc_inq_user_type(igrp, typeid, NULL, NULL, NULL, NULL, &type_class));
|
||||
@ -593,7 +567,7 @@ copy_groups(int iroot, int oroot)
|
||||
NC_CHECK(nc_inq_grpname_full(grpids[i], &len_name, grpname_full));
|
||||
/* Make sure, the parent group is also wanted (root group is always wanted) */
|
||||
NC_CHECK(nc_inq_parid(iroot, grpname_full, &iparid));
|
||||
if (!option_grpstruct && !group_wanted(iparid, option_nlgrps, option_grpids)
|
||||
if (!option_grpstruct && !group_wanted(iparid, option_nlgrps, option_grpids)
|
||||
&& iparid != iroot) {
|
||||
error("ERROR: trying to copy a group but not the parent: %s", grpname_full);
|
||||
}
|
||||
@ -610,17 +584,17 @@ copy_groups(int iroot, int oroot)
|
||||
}
|
||||
free(grpids);
|
||||
}
|
||||
return stat;
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copy the user-defined types in this group (igrp) and all its
|
||||
* subgroups, recursively, to corresponding group in output (ogrp)
|
||||
*/
|
||||
static int
|
||||
copy_types(int igrp, int ogrp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int stat = NC_NOERR;
|
||||
int ntypes;
|
||||
nc_type *types = NULL;
|
||||
int numgrps;
|
||||
@ -672,7 +646,7 @@ copy_var_specials(int igrp, int varid, int ogrp, int o_varid)
|
||||
size_t *chunkp = (size_t *) emalloc(ndims * sizeof(size_t));
|
||||
int *dimids = (int *) emalloc(ndims * sizeof(int));
|
||||
int idim;
|
||||
/* size of a chunk: product of dimension chunksizes and size of value */
|
||||
/* size of a chunk: product of dimension chunksizes and size of value */
|
||||
size_t csprod = val_size(ogrp, o_varid);
|
||||
int is_unlimited = 0;
|
||||
NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, chunkp));
|
||||
@ -788,8 +762,10 @@ copy_var_filter(int igrp, int varid, int ogrp, int o_varid)
|
||||
}
|
||||
/* Apply filter spec if any */
|
||||
if(spec.filterid > 0) {/* Apply filter */
|
||||
#ifdef USE_NETCDF4
|
||||
if((stat=nc_def_var_filter(ovid.grpid,ovid.varid,spec.filterid,spec.nparams,spec.params)))
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
done:
|
||||
/* Cleanup */
|
||||
@ -842,7 +818,7 @@ set_var_chunked(int ogrp, int o_varid)
|
||||
size_t dimlen;
|
||||
NC_CHECK(nc_inq_dimlen(ogrp, odimid, &dimlen));
|
||||
if( (chunksize > 0) || dimmap_ounlim(odimid)) {
|
||||
chunked = 1;
|
||||
chunked = 1;
|
||||
}
|
||||
if(dimlen > 0) { /* dimlen for unlimited dims is still 0 before copying data */
|
||||
varsize *= dimlen;
|
||||
@ -934,7 +910,7 @@ copy_dims(int igrp, int ogrp)
|
||||
int *unlimids;
|
||||
#else
|
||||
int unlimid;
|
||||
#endif /* USE_NETCDF4 */
|
||||
#endif /* USE_NETCDF4 */
|
||||
|
||||
NC_CHECK(nc_inq_ndims(igrp, &ndims));
|
||||
|
||||
@ -971,7 +947,7 @@ copy_dims(int igrp, int ogrp)
|
||||
if(idimid == unlimids[uld]) {
|
||||
i_is_unlim = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
idimid = dgrp;
|
||||
@ -983,7 +959,7 @@ copy_dims(int igrp, int ogrp)
|
||||
stat = nc_inq_dim(igrp, idimid, name, &length);
|
||||
if (stat == NC_EDIMSIZE && sizeof(size_t) < 8) {
|
||||
error("dimension \"%s\" requires 64-bit platform", name);
|
||||
}
|
||||
}
|
||||
NC_CHECK(stat);
|
||||
o_is_unlim = i_is_unlim;
|
||||
if(i_is_unlim && !option_fix_unlimdims) {
|
||||
@ -998,7 +974,7 @@ copy_dims(int igrp, int ogrp)
|
||||
#ifdef USE_NETCDF4
|
||||
free(dimids);
|
||||
free(unlimids);
|
||||
#endif /* USE_NETCDF4 */
|
||||
#endif /* USE_NETCDF4 */
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -1013,7 +989,7 @@ copy_atts(int igrp, int ivar, int ogrp, int ovar)
|
||||
int stat = NC_NOERR;
|
||||
|
||||
NC_CHECK(nc_inq_varnatts(igrp, ivar, &natts));
|
||||
|
||||
|
||||
for(iatt = 0; iatt < natts; iatt++) {
|
||||
char name[NC_MAX_NAME];
|
||||
NC_CHECK(nc_inq_attname(igrp, ivar, iatt, name));
|
||||
@ -1064,7 +1040,7 @@ copy_var(int igrp, int varid, int ogrp)
|
||||
NC_CHECK(nc_def_var(ogrp, name, o_typeid, ndims, odimids, &o_varid));
|
||||
/* attach the variable attributes to the output variable */
|
||||
NC_CHECK(copy_atts(igrp, varid, ogrp, o_varid));
|
||||
#ifdef USE_NETCDF4
|
||||
#ifdef USE_NETCDF4
|
||||
{
|
||||
int inkind;
|
||||
int outkind;
|
||||
@ -1112,7 +1088,7 @@ copy_vars(int igrp, int ogrp)
|
||||
if(nc_inq_gvarid(igrp, option_lvars[iv], &varid) == NC_NOERR)
|
||||
idadd(vlist, varid);
|
||||
}
|
||||
|
||||
|
||||
NC_CHECK(nc_inq_nvars(igrp, &nvars));
|
||||
for (varid = 0; varid < nvars; varid++) {
|
||||
if (!option_varstruct && option_nlvars > 0 && ! idmember(vlist, varid))
|
||||
@ -1127,7 +1103,7 @@ copy_vars(int igrp, int ogrp)
|
||||
* group igrp in input to parent group ogrp in destination. Use
|
||||
* dimmap array to map input dimids to output dimids. */
|
||||
static int
|
||||
copy_schema(int igrp, int ogrp)
|
||||
copy_schema(int igrp, int ogrp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int ogid; /* like igrp but in output file */
|
||||
@ -1139,7 +1115,7 @@ copy_schema(int igrp, int ogrp)
|
||||
NC_CHECK(copy_dims(igrp, ogid));
|
||||
NC_CHECK(copy_atts(igrp, NC_GLOBAL, ogid, NC_GLOBAL));
|
||||
NC_CHECK(copy_vars(igrp, ogid));
|
||||
#ifdef USE_NETCDF4
|
||||
#ifdef USE_NETCDF4
|
||||
{
|
||||
int numgrps;
|
||||
int *grpids;
|
||||
@ -1148,7 +1124,7 @@ copy_schema(int igrp, int ogrp)
|
||||
stat = nc_inq_grps(igrp, &numgrps, NULL);
|
||||
grpids = (int *)emalloc((numgrps + 1) * sizeof(int));
|
||||
NC_CHECK(nc_inq_grps(igrp, &numgrps, grpids));
|
||||
|
||||
|
||||
for(i = 0; i < numgrps; i++) {
|
||||
if (option_grpstruct || group_wanted(grpids[i], option_nlgrps, option_grpids)) {
|
||||
NC_CHECK(copy_schema(grpids[i], ogid));
|
||||
@ -1157,7 +1133,7 @@ copy_schema(int igrp, int ogrp)
|
||||
free(grpids);
|
||||
}
|
||||
#endif /* USE_NETCDF4 */
|
||||
return stat;
|
||||
return stat;
|
||||
}
|
||||
|
||||
/* Return number of values for a variable varid in a group igrp */
|
||||
@ -1199,7 +1175,7 @@ copy_var_data(int igrp, int varid, int ogrp) {
|
||||
size_t *count;
|
||||
nciter_t *iterp; /* opaque structure for iteration status */
|
||||
int do_realloc = 0;
|
||||
#ifdef USE_NETCDF4
|
||||
#ifdef USE_NETCDF4
|
||||
int okind;
|
||||
size_t chunksize;
|
||||
#endif
|
||||
@ -1216,10 +1192,10 @@ copy_var_data(int igrp, int varid, int ogrp) {
|
||||
option_copy_buffer_size = value_size;
|
||||
do_realloc = 1;
|
||||
}
|
||||
#ifdef USE_NETCDF4
|
||||
#ifdef USE_NETCDF4
|
||||
NC_CHECK(nc_inq_format(ogrp, &okind));
|
||||
if(okind == NC_FORMAT_NETCDF4 || okind == NC_FORMAT_NETCDF4_CLASSIC) {
|
||||
/* if this variable chunked, set variable chunk cache size */
|
||||
/* if this variable chunked, set variable chunk cache size */
|
||||
int contig = 1;
|
||||
NC_CHECK(nc_inq_var_chunking(ogrp, ovarid, &contig, NULL));
|
||||
if(contig == 0) { /* chunked */
|
||||
@ -1230,16 +1206,16 @@ copy_var_data(int igrp, int varid, int ogrp) {
|
||||
size_t chunkcache_size, chunkcache_nelems;
|
||||
float chunkcache_preemption;
|
||||
NC_CHECK(inq_var_chunking_params(igrp, varid, ogrp, ovarid,
|
||||
&chunkcache_size,
|
||||
&chunkcache_nelems,
|
||||
&chunkcache_size,
|
||||
&chunkcache_nelems,
|
||||
&chunkcache_preemption));
|
||||
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
|
||||
chunkcache_size,
|
||||
chunkcache_nelems,
|
||||
chunkcache_preemption));
|
||||
} else {
|
||||
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
|
||||
chunkcache_size,
|
||||
chunkcache_nelems,
|
||||
chunkcache_preemption));
|
||||
} else {
|
||||
/* by default, use same chunk cache for all chunked variables */
|
||||
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
|
||||
NC_CHECK(nc_set_var_chunk_cache(ogrp, ovarid,
|
||||
option_chunk_cache_size,
|
||||
option_chunk_cache_nelems,
|
||||
COPY_CHUNKCACHE_PREEMPTION));
|
||||
@ -1331,11 +1307,11 @@ copy_data(int igrp, int ogrp)
|
||||
if(nc_inq_gvarid(igrp, option_lvars[iv], &varid) == NC_NOERR)
|
||||
idadd(vlist, varid);
|
||||
}
|
||||
|
||||
|
||||
/* get groupid in output corresponding to group igrp in input,
|
||||
* given parent group (or root group) ogrp in output */
|
||||
NC_CHECK(get_grpid(igrp, ogrp, &ogid));
|
||||
|
||||
|
||||
/* Copy data from this group */
|
||||
NC_CHECK(nc_inq_nvars(igrp, &nvars));
|
||||
|
||||
@ -1378,7 +1354,7 @@ count_dims(int ncid) {
|
||||
for(igrp = 0; igrp < numgrps; igrp++) {
|
||||
ndims += count_dims(grpids[igrp]);
|
||||
}
|
||||
free(grpids);
|
||||
free(grpids);
|
||||
}
|
||||
#endif /* USE_NETCDF4 */
|
||||
return ndims;
|
||||
@ -1433,20 +1409,36 @@ classify_vars(
|
||||
int **rvars) /* the array of record variable IDs, caller should free */
|
||||
{
|
||||
int varid;
|
||||
int varindex = 0;
|
||||
int nvars;
|
||||
NC_CHECK(nc_inq_nvars(ncid, &nvars));
|
||||
*nf = 0;
|
||||
*fvars = (int *) emalloc(nvars * sizeof(int));
|
||||
*nr = 0;
|
||||
*rvars = (int *) emalloc(nvars * sizeof(int));
|
||||
for (varid = 0; varid < nvars; varid++) {
|
||||
if (isrecvar(ncid, varid)) {
|
||||
(*rvars)[*nr] = varid;
|
||||
(*nr)++;
|
||||
} else {
|
||||
(*fvars)[*nf] = varid;
|
||||
(*nf)++;
|
||||
}
|
||||
|
||||
if(option_nlvars > 0) {
|
||||
for (varindex = 0; varindex < option_nlvars; varindex++) {
|
||||
nc_inq_varid(ncid,option_lvars[varindex],&varid);
|
||||
|
||||
if (isrecvar(ncid, varid)) {
|
||||
(*rvars)[*nr] = varid;
|
||||
(*nr)++;
|
||||
} else {
|
||||
(*fvars)[*nf] = varid;
|
||||
(*nf)++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (varid = 0; varid < nvars; varid++) {
|
||||
if (isrecvar(ncid, varid)) {
|
||||
(*rvars)[*nr] = varid;
|
||||
(*nr)++;
|
||||
} else {
|
||||
(*fvars)[*nf] = varid;
|
||||
(*nf)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NC_NOERR;
|
||||
}
|
||||
@ -1475,7 +1467,7 @@ copy_rec_var_data(int ncid, /* input */
|
||||
size_t *start, /* start indices for record data */
|
||||
size_t *count, /* edge lengths for record data */
|
||||
void *buf /* buffer large enough to hold data */
|
||||
)
|
||||
)
|
||||
{
|
||||
NC_CHECK(nc_get_vara(ncid, varid, start, count, buf));
|
||||
NC_CHECK(nc_put_vara(ogrp, ovarid, start, count, buf));
|
||||
@ -1525,7 +1517,7 @@ copy_record_data(int ncid, int ogrp, size_t nrec_vars, int *rec_varids) {
|
||||
start[ivar][ii] = 0;
|
||||
count[ivar][ii] = dimlen;
|
||||
}
|
||||
start[ivar][0] = 0;
|
||||
start[ivar][0] = 0;
|
||||
count[ivar][0] = 1; /* 1 record */
|
||||
buf[ivar] = (void *) emalloc(nvals * value_size);
|
||||
NC_CHECK(nc_inq_varname(ncid, varid, varname));
|
||||
@ -1541,7 +1533,7 @@ copy_record_data(int ncid, int ogrp, size_t nrec_vars, int *rec_varids) {
|
||||
varid = rec_varids[ivar];
|
||||
ovarid = rec_ovarids[ivar];
|
||||
start[ivar][0] = irec;
|
||||
NC_CHECK(copy_rec_var_data(ncid, ogrp, irec, varid, ovarid,
|
||||
NC_CHECK(copy_rec_var_data(ncid, ogrp, irec, varid, ovarid,
|
||||
start[ivar], count[ivar], buf[ivar]));
|
||||
}
|
||||
}
|
||||
@ -1591,11 +1583,11 @@ copy(char* infile, char* outfile)
|
||||
|
||||
/* option_kind specifies which netCDF format for output, one of
|
||||
*
|
||||
* SAME_AS_INPUT, NC_FORMAT_CLASSIC, NC_FORMAT_64BIT,
|
||||
* NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC
|
||||
* SAME_AS_INPUT, NC_FORMAT_CLASSIC, NC_FORMAT_64BIT,
|
||||
* NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC
|
||||
*
|
||||
* However, if compression or shuffling was specified and kind was SAME_AS_INPUT,
|
||||
* option_kind is changed to NC_FORMAT_NETCDF4_CLASSIC, if input format is
|
||||
* option_kind is changed to NC_FORMAT_NETCDF4_CLASSIC, if input format is
|
||||
* NC_FORMAT_CLASSIC or NC_FORMAT_64BIT .
|
||||
*/
|
||||
outkind = option_kind;
|
||||
@ -1603,11 +1595,11 @@ copy(char* infile, char* outfile)
|
||||
outkind = inkind;
|
||||
/* Deduce output kind if netCDF-4 features requested */
|
||||
if (inkind == NC_FORMAT_CLASSIC || inkind == NC_FORMAT_64BIT_OFFSET
|
||||
|| inkind == NC_FORMAT_CDF5) {
|
||||
if (option_deflate_level > 0 ||
|
||||
option_shuffle_vars == NC_SHUFFLE ||
|
||||
option_chunkspec)
|
||||
{
|
||||
|| inkind == NC_FORMAT_CDF5) {
|
||||
if (option_deflate_level > 0 ||
|
||||
option_shuffle_vars == NC_SHUFFLE ||
|
||||
option_chunkspec)
|
||||
{
|
||||
outkind = NC_FORMAT_NETCDF4_CLASSIC;
|
||||
}
|
||||
}
|
||||
@ -1645,8 +1637,13 @@ copy(char* infile, char* outfile)
|
||||
create_mode |= NC_64BIT_OFFSET;
|
||||
break;
|
||||
case NC_FORMAT_CDF5:
|
||||
create_mode |= NC_64BIT_DATA;
|
||||
break;
|
||||
#ifdef USE_CDF5
|
||||
create_mode |= NC_64BIT_DATA;
|
||||
break;
|
||||
#else
|
||||
error("netCDF library built without CDF5 support, can't create CDF5 files");
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_NETCDF4
|
||||
case NC_FORMAT_NETCDF4:
|
||||
create_mode |= NC_NETCDF4;
|
||||
@ -1700,7 +1697,7 @@ copy(char* infile, char* outfile)
|
||||
NC_CHECK(classify_vars(ogrp, &nfixed_vars, &fixed_varids, &nrec_vars, &rec_varids));
|
||||
NC_CHECK(copy_fixed_size_data(igrp, ogrp, nfixed_vars, fixed_varids));
|
||||
NC_CHECK(copy_record_data(igrp, ogrp, nrec_vars, rec_varids));
|
||||
} else {
|
||||
} else {
|
||||
NC_CHECK(copy_data(igrp, ogrp)); /* recursive, to handle nested groups */
|
||||
}
|
||||
|
||||
@ -1709,7 +1706,7 @@ copy(char* infile, char* outfile)
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* For non-negative numeric string with multiplier suffix K, M, G, T,
|
||||
* or P (or lower-case equivalent), return corresponding value
|
||||
* incorporating multiplier 1000, 1000000, 1.0d9, ... 1.0d15, or -1.0
|
||||
@ -1742,7 +1739,7 @@ double_with_suffix(char *str) {
|
||||
break;
|
||||
default:
|
||||
dval = -1.0; /* error, suffix multiplier must be K, M, G, or T */
|
||||
}
|
||||
}
|
||||
}
|
||||
return dval;
|
||||
}
|
||||
@ -1802,13 +1799,13 @@ main(int argc, char**argv)
|
||||
{"classic", NC_FORMAT_CLASSIC}, /* canonical format name */
|
||||
{"nc3", NC_FORMAT_CLASSIC}, /* short format name */
|
||||
{"1", NC_FORMAT_CLASSIC}, /* deprecated, use "-3" or "-k nc3" instead */
|
||||
|
||||
|
||||
/* NetCDF-3 64-bit offset format */
|
||||
{"64-bit offset", NC_FORMAT_64BIT_OFFSET}, /* canonical format name */
|
||||
{"nc6", NC_FORMAT_64BIT_OFFSET}, /* short format name */
|
||||
{"2", NC_FORMAT_64BIT_OFFSET}, /* deprecated, use "-6" or "-k nc6" instead */
|
||||
{"64-bit-offset", NC_FORMAT_64BIT_OFFSET}, /* deprecated alias */
|
||||
|
||||
|
||||
/* NetCDF-4 HDF5-based format */
|
||||
{"netCDF-4", NC_FORMAT_NETCDF4}, /* canonical format name */
|
||||
{"nc4", NC_FORMAT_NETCDF4}, /* short format name */
|
||||
@ -1848,7 +1845,7 @@ main(int argc, char**argv)
|
||||
|
||||
while ((c = getopt(argc, argv, "k:3467d:sum:c:h:e:rwxg:G:v:V:F:")) != -1) {
|
||||
switch(c) {
|
||||
case 'k': /* for specifying variant of netCDF format to be generated
|
||||
case 'k': /* for specifying variant of netCDF format to be generated
|
||||
Format names:
|
||||
"classic" or "nc3"
|
||||
"64-bit offset" or "nc6"
|
||||
|
@ -36,7 +36,6 @@ int optind;
|
||||
|
||||
#include "netcdf.h"
|
||||
#include "netcdf_mem.h"
|
||||
#include "netcdf_filter.h"
|
||||
#include "utils.h"
|
||||
#include "nccomps.h"
|
||||
#include "nctime0.h" /* new iso time and calendar stuff */
|
||||
|
@ -5,7 +5,7 @@ variables:
|
||||
ubyte ub(d) ;
|
||||
ushort us(d) ;
|
||||
uint ui(d) ;
|
||||
int i64(d) ;
|
||||
int64 i64(d) ;
|
||||
uint64 ui64(d) ;
|
||||
|
||||
// global attributes:
|
||||
@ -18,7 +18,7 @@ data:
|
||||
|
||||
ui = 4294967294, 4294967294, 4294967294 ;
|
||||
|
||||
i64 = -1, -1, -1 ;
|
||||
i64 = 9223372036854775807, 9223372036854775807, 9223372036854775807 ;
|
||||
|
||||
ui64 = 18446744073709551615, 18446744073709551615, 18446744073709551615 ;
|
||||
}
|
||||
|
BIN
ncdump/ref_nccopy3_subset.nc
Normal file
BIN
ncdump/ref_nccopy3_subset.nc
Normal file
Binary file not shown.
@ -8,6 +8,19 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
echo "*** Testing ncgen."
|
||||
set -e
|
||||
|
||||
# This shell script runs the ncdump tests.
|
||||
# get some config.h parameters
|
||||
if test -f ${top_builddir}/config.h ; then
|
||||
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
|
||||
CDF5=1
|
||||
else
|
||||
CDF5=0
|
||||
fi
|
||||
else
|
||||
echo "Cannot locate config.h"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#VALGRIND="valgrind -q --error-exitcode=2 --leak-check=full"
|
||||
|
||||
validateNC() {
|
||||
@ -37,11 +50,15 @@ echo "*** creating 64-bit offset file c0_64.nc from c0.cdl..."
|
||||
|
||||
validateNC c0 "c0_64" -k 64-bit-offset -b
|
||||
|
||||
echo "*** creating 64-bit offset file c5.nc from c5.cdl..."
|
||||
${NCGEN} -k 64-bit-data -b -o c5.nc $top_srcdir/ncgen/c5.cdl
|
||||
if [ ! -f c5.nc ]; then
|
||||
echo "Failure."
|
||||
exit 1
|
||||
if test "x$USE_CDF5" = x1 ; then
|
||||
|
||||
echo "*** creating 64-bit data file c5.nc from c5.cdl..."
|
||||
${NCGEN} -k 64-bit-data -b -o c5.nc $top_srcdir/ncgen/c5.cdl
|
||||
if [ ! -f c5.nc ]; then
|
||||
echo "Failure."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
echo "*** Test successful!"
|
||||
|
@ -15,16 +15,16 @@ echo "*** creating tst_small.cdl from tst_small.nc..."
|
||||
${NCDUMP} tst_small.nc > tst_small.cdl
|
||||
diff -b -w tst_small.cdl $srcdir/ref_tst_small.cdl
|
||||
|
||||
echo "*** creating test0.nc from test0.cdl..."
|
||||
${NCGEN} -b $srcdir/test0.cdl
|
||||
echo "*** creating test1.cdl from test0.nc..."
|
||||
${NCDUMP} -n test1 test0.nc > test1.cdl
|
||||
echo "*** creating test1.nc from test1.cdl..."
|
||||
${NCGEN} -b test1.cdl
|
||||
echo "*** creating test2.cdl from test1.nc..."
|
||||
${NCDUMP} test1.nc > test2.cdl
|
||||
echo "*** checking that test1.cdl and test2.cdl are the same..."
|
||||
diff -b -w test1.cdl test2.cdl
|
||||
echo "*** creating test0_ncdump.nc from test0.cdl..."
|
||||
${NCGEN} -o test0_ncdump.nc -b $srcdir/test0.cdl
|
||||
echo "*** creating test1_ncdump.cdl from test0_ncdump.nc..."
|
||||
${NCDUMP} -n test1_ncdump test0_ncdump.nc > test1_ncdump.cdl
|
||||
echo "*** creating test1_ncdump.nc from test1_ncdump.cdl..."
|
||||
${NCGEN} -b test1_ncdump.cdl
|
||||
echo "*** creating test2_ncdump.cdl from test1_ncdump.nc..."
|
||||
${NCDUMP} test1_ncdump.nc > test2_ncdump.cdl
|
||||
echo "*** checking that test1_ncdump.cdl and test2_ncdump.cdl are the same..."
|
||||
diff -b -w test1_ncdump.cdl test2_ncdump.cdl
|
||||
|
||||
echo "*** All tests of ncgen and ncdump using test0.cdl passed!"
|
||||
exit 0
|
||||
|
@ -1,37 +1,52 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
set -e
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
# This shell script runs the ncdump tests.
|
||||
|
||||
# get some config.h parameters
|
||||
if test -f ${top_builddir}/config.h ; then
|
||||
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
|
||||
CDF5=1
|
||||
else
|
||||
CDF5=0
|
||||
fi
|
||||
else
|
||||
echo "Cannot locate config.h"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "*** Testing ncgen and ncdump with 64-bit offset format."
|
||||
set -e
|
||||
echo "*** creating test0.nc from test0.cdl..."
|
||||
${NCGEN} -b -k2 $srcdir/test0.cdl
|
||||
echo "*** creating test1.cdl from test0.nc..."
|
||||
${NCDUMP} -n test1 test0.nc > test1.cdl
|
||||
echo "*** creating test1.nc from test1.cdl..."
|
||||
${NCGEN} -b -k2 test1.cdl
|
||||
echo "*** creating test2.cdl from test1.nc..."
|
||||
${NCDUMP} test1.nc > test2.cdl
|
||||
cmp test1.cdl test2.cdl
|
||||
echo "*** creating test0_offset.nc from test0.cdl..."
|
||||
${NCGEN} -b -k2 -o test0_offset.nc $srcdir/test0.cdl
|
||||
echo "*** creating test1_offset.cdl from test0_offset.nc..."
|
||||
${NCDUMP} -n test1_offset test0_offset.nc > test1_offset.cdl
|
||||
echo "*** creating test1_offset.nc from test1_offset.cdl..."
|
||||
${NCGEN} -b -k2 -o test1_offset.nc test1_offset.cdl
|
||||
echo "*** creating test2_offset.cdl from test1.nc..."
|
||||
${NCDUMP} test1_offset.nc > test2_offset.cdl
|
||||
cmp test1_offset.cdl test2_offset.cdl
|
||||
echo "*** All ncgen and ncdump with 64-bit offset format tests passed!"
|
||||
|
||||
|
||||
if test "x$CDF5" = x1 ; then
|
||||
echo ""
|
||||
echo "*** Testing ncgen and ncdump with CDF5 format."
|
||||
set -e
|
||||
echo "*** creating test0.nc from test0.cdl..."
|
||||
${NCGEN} -b -k5 $srcdir/test0.cdl
|
||||
echo "*** creating test1.cdl from test0.nc..."
|
||||
${NCDUMP} -n test1 test0.nc > test1.cdl
|
||||
echo "*** creating test1.nc from test1.cdl..."
|
||||
${NCGEN} -b -k5 test1.cdl
|
||||
echo "*** creating test2.cdl from test1.nc..."
|
||||
${NCDUMP} test1.nc > test2.cdl
|
||||
cmp test1.cdl test2.cdl
|
||||
echo "*** creating test0_cdf5.nc from test0.cdl..."
|
||||
${NCGEN} -b -k5 -o test0_cdf5.nc $srcdir/test0.cdl
|
||||
echo "*** creating test1_cdf5.cdl from test0_cdf5.nc..."
|
||||
${NCDUMP} -n test1_cdf5 test0_cdf5.nc > test1_cdf5.cdl
|
||||
echo "*** creating test1_cdf5.nc from test1_cdf5.cdl..."
|
||||
${NCGEN} -b -k5 -o test1_cdf5.nc test1_cdf5.cdl
|
||||
echo "*** creating test2_cdf5.cdl from test1_cdf5.nc..."
|
||||
${NCDUMP} test1_cdf5.nc > test2_cdf5.cdl
|
||||
cmp test1_cdf5.cdl test2_cdf5.cdl
|
||||
echo "*** All ncgen and ncdump with CDF5 format tests passed!"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "config.h"
|
||||
#include <nc_tests.h>
|
||||
#include "err_macros.h"
|
||||
#include <stdio.h>
|
||||
@ -10,7 +11,10 @@
|
||||
|
||||
#define DIMMAXCLASSIC (NC_MAX_INT - 3)
|
||||
#define DIMMAX64OFFSET (NC_MAX_UINT - 3)
|
||||
|
||||
#ifdef USE_CDF5
|
||||
#define DIMMAX64DATA (NC_MAX_UINT64 - 3)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Test that at least the meta-data works
|
||||
@ -62,6 +66,7 @@ main(int argc, char **argv)
|
||||
if(dimsize != DIMMAX64OFFSET) ERR;
|
||||
if ((stat=nc_close(ncid))) ERRSTAT(stat);
|
||||
|
||||
#ifdef USE_CDF5
|
||||
if(sizeof(size_t) == 8) {
|
||||
printf("\n*** Writing Max Dimension Size (%llu) For NC_64BIT_DATA\n",DIMMAX64DATA);
|
||||
if ((stat=nc_create(FILE64DATA, NC_CLOBBER | NC_64BIT_DATA, &ncid))) ERRSTAT(stat);
|
||||
@ -76,6 +81,7 @@ main(int argc, char **argv)
|
||||
if(dimsize != DIMMAX64DATA) ERR;
|
||||
if ((stat=nc_close(ncid))) ERRSTAT(stat);
|
||||
}
|
||||
#endif /* USE_CDF5 */
|
||||
|
||||
SUMMARIZE_ERR;
|
||||
FINAL_RESULTS;
|
||||
|
@ -1,8 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
# This shell script runs the ncdump tests.
|
||||
# get some config.h parameters
|
||||
if test -f ${top_builddir}/config.h ; then
|
||||
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
|
||||
USE_CDF5=1
|
||||
else
|
||||
USE_CDF5=0
|
||||
fi
|
||||
else
|
||||
echo "Cannot locate config.h"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# This shell script tests the output several previous tests.
|
||||
|
||||
ECODE=0
|
||||
@ -28,17 +41,20 @@ echo "*** Fail: extended format for a 64-bit classic file"
|
||||
ECODE=1
|
||||
fi
|
||||
|
||||
echo "Test extended format output for a 64-bit CDF-5 classic file"
|
||||
rm -f tmp
|
||||
${NCGEN} -k5 -b -o ./test.nc $srcdir/ref_tst_small.cdl
|
||||
${NCDUMP} -K test.nc >tmp
|
||||
if ! grep -F '64-bit data mode=00000020' <tmp ; then
|
||||
echo "*** Fail: extended format for a 64-bit CDF-5 classic file"
|
||||
ECODE=1
|
||||
|
||||
# Only do following test if USE_CDF5 is true.
|
||||
|
||||
if test "x$USE_CDF5" = x1 ; then
|
||||
echo "Test extended format output for a 64-bit CDF-5 classic file"
|
||||
rm -f tmp
|
||||
${NCGEN} -k5 -b -o ./test.nc $srcdir/ref_tst_small.cdl
|
||||
${NCDUMP} -K test.nc >tmp
|
||||
if ! grep -F '64-bit data mode=00000020' <tmp ; then
|
||||
echo "*** Fail: extended format for a 64-bit CDF-5 classic file"
|
||||
ECODE=1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f tmp test.nc
|
||||
|
||||
exit $ECODE
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
set -e
|
||||
@ -8,7 +8,7 @@ set -e
|
||||
echo "*** Test netcdf-4 integer constant suffixes"
|
||||
|
||||
echo "*** creating inttags4.nc from inttags4.cdl..."
|
||||
${NCGEN} -lb -o inttags4.nc $srcdir/inttags4.cdl
|
||||
${NCGEN} -lb -k nc4 -o inttags4.nc $srcdir/inttags4.cdl
|
||||
echo "*** creating tst_inttags4.cdl from inttags4.nc..."
|
||||
${NCDUMP} inttags4.nc > tst_inttags4.cdl
|
||||
echo "*** comparing tst_inttags4.cdl to ref_inttags4.nc..."
|
||||
|
@ -1,8 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
# get some config.h parameters
|
||||
if test -f ${top_builddir}/config.h ; then
|
||||
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
|
||||
HAVE_CDF5=1
|
||||
else
|
||||
HAVE_CDF5=0
|
||||
fi
|
||||
else
|
||||
echo "Cannot locate config.h"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# It is unreasonable to test actual lengths of files
|
||||
# (even netcdf-3 files).
|
||||
#However, the files created in this script are used in later ones
|
||||
@ -10,7 +22,7 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
${NCGEN} -b ${srcdir}/small.cdl
|
||||
${NCGEN} -b ${srcdir}/small2.cdl
|
||||
|
||||
# This shell script tests lengths of small netcdf files and tests
|
||||
# This shell script tests lengths of small netcdf files and tests
|
||||
# that rewriting a numeric value doesn't change file length
|
||||
# $Id: tst_lengths.sh,v 1.10 2008/08/07 00:07:52 ed Exp $
|
||||
|
||||
@ -93,39 +105,44 @@ ${NCGEN} -b -k64-bit-offset -x ${srcdir}/small.cdl && ${execdir}/rewrite-scalar
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
echo "*** testing length of 64-bit data file"
|
||||
${NCGEN} -b -k64-bit-data ${srcdir}/small.cdl
|
||||
if test `wc -c < small.nc` != 104; then
|
||||
exit 1
|
||||
# The following tests only occur if we have CDF5.
|
||||
if test "x$HAVE_CDF5" = x1 ; then
|
||||
|
||||
echo "*** testing length of 64-bit data file"
|
||||
${NCGEN} -b -k64-bit-data ${srcdir}/small.cdl
|
||||
if test `wc -c < small.nc` != 104; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "*** testing length of 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small.cdl
|
||||
if test `wc -c < small.nc` != 104; then
|
||||
exit 1
|
||||
fi
|
||||
echo "*** testing length of 64-bit data file written with NOFILL"
|
||||
${NCGEN} -b -5 -x ${srcdir}/small.cdl
|
||||
#if test `wc -c < small.nc` != 104; then
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
echo "*** testing length of rewritten 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
|
||||
# Watch out, it appears that the CDF-5 files are being rounded up to next page size
|
||||
# So, we need to truncate them wrt nul's in order to check size.
|
||||
# Bad hack, but what else can I do?
|
||||
if test `${execdir}/nctrunc <small.nc |wc -c` != 104; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "*** testing length of rewritten 64-bit data file written with NOFILL"
|
||||
${NCGEN} -b -5 -x ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
|
||||
#if test `wc -c < small.nc` != 104; then
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
# End HAVE_CDF5 block.
|
||||
fi
|
||||
|
||||
echo "*** testing length of 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small.cdl
|
||||
if test `wc -c < small.nc` != 104; then
|
||||
exit 1
|
||||
fi
|
||||
echo "*** testing length of 64-bit data file written with NOFILL"
|
||||
${NCGEN} -b -5 -x ${srcdir}/small.cdl
|
||||
#if test `wc -c < small.nc` != 104; then
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
echo "*** testing length of rewritten 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
|
||||
# Watch out, it appears that the CDF-5 files are being rounded up to next page size
|
||||
# So, we need to truncate them wrt nul's in order to check size.
|
||||
# Bad hack, but what else can I do?
|
||||
if test `${execdir}/nctrunc <small.nc |wc -c` != 104; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "*** testing length of rewritten 64-bit data file written with NOFILL"
|
||||
${NCGEN} -b -5 -x ${srcdir}/small.cdl && ${execdir}/rewrite-scalar small.nc t
|
||||
#if test `wc -c < small.nc` != 104; then
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
|
||||
# test with only one record variable of type byte or short, which need
|
||||
# not be 4-byte aligned
|
||||
echo "*** testing length of one-record-variable classic file"
|
||||
@ -134,22 +151,28 @@ ${NCGEN} -b ${srcdir}/small2.cdl
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
echo "*** testing length of one-record-variable 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small2.cdl
|
||||
if test `wc -c < small2.nc` != 161; then
|
||||
exit 1
|
||||
fi
|
||||
# The following tests only occur if we have CDF5.
|
||||
if test "x$HAVE_CDF5" = x1 ; then
|
||||
|
||||
echo "*** testing length of one-record-variable 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small2.cdl
|
||||
if test `wc -c < small2.nc` != 161; then
|
||||
exit 1
|
||||
fi
|
||||
echo "*** testing length of one-record-variable 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small2.cdl
|
||||
if test `wc -c < small2.nc` != 161; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "*** testing length of one-record-variable 64-bit data file written with NOFILL"
|
||||
${NCGEN} -b -5 -x ${srcdir}/small2.cdl
|
||||
if test `wc -c < small2.nc` != 161; then
|
||||
exit 1
|
||||
echo "*** testing length of one-record-variable 64-bit data file"
|
||||
${NCGEN} -b -5 ${srcdir}/small2.cdl
|
||||
if test `wc -c < small2.nc` != 161; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "*** testing length of one-record-variable 64-bit data file written with NOFILL"
|
||||
${NCGEN} -b -5 -x ${srcdir}/small2.cdl
|
||||
if test `wc -c < small2.nc` != 161; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#end HAVE_CDF5 block
|
||||
fi
|
||||
|
||||
echo "*** testing length of one-record-variable classic file written with NOFILL"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
# For a netCDF-3 build, test nccopy on netCDF files in this directory
|
||||
@ -8,9 +8,26 @@ if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
set -e
|
||||
echo ""
|
||||
|
||||
TESTFILES='c0 c0tmp ctest0 ctest0_64 small small2 test0 test1
|
||||
# get some config.h parameters
|
||||
if test -f ${top_builddir}/config.h ; then
|
||||
if fgrep -e '#define USE_CDF5 1' ${top_builddir}/config.h >/dev/null ; then
|
||||
HAVE_CDF5=1
|
||||
else
|
||||
HAVE_CDF5=0
|
||||
fi
|
||||
else
|
||||
echo "Cannot locate config.h"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TESTFILES='c0 c0tmp ctest0 ctest0_64 test0_offset test1_offset
|
||||
tst_calendars tst_mslp tst_mslp_64 tst_ncml tst_small tst_utf8 utf8'
|
||||
|
||||
if test "x$HAVE_CDF5" = x1 ; then
|
||||
TESTFILES="$TESTFILES small small2"
|
||||
fi
|
||||
|
||||
|
||||
echo "*** Testing netCDF-3 features of nccopy on ncdump/*.nc files"
|
||||
for i in $TESTFILES ; do
|
||||
echo "*** Testing nccopy $i.nc copy_of_$i.nc ..."
|
||||
|
41
ncdump/tst_nccopy3_subset.sh
Executable file
41
ncdump/tst_nccopy3_subset.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Added in support of https://github.com/Unidata/netcdf-c/gh425 and
|
||||
# https://github.com/Unidata/netcdf-c/gh469
|
||||
#
|
||||
# The output isn't validated, but the regression it is fixing fails on nccopy.
|
||||
#
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
# For a netCDF-3 build, test nccopy on netCDF files in this directory
|
||||
|
||||
set -e
|
||||
echo ""
|
||||
|
||||
INFILE=${TOPSRCDIR}/ncdump/ref_nccopy3_subset.nc
|
||||
OUTFILE=nccopy3_subset_out.nc
|
||||
|
||||
echo "*** Testing netCDF-3 nccopy -v/-V flags on $IN"
|
||||
|
||||
echo "*** One Dimensional Tests"
|
||||
echo "*** Testing nccopy -v"
|
||||
|
||||
${NCCOPY} -v lat ${INFILE} ${OUTFILE}
|
||||
|
||||
echo "*** Testing nccopy -V"
|
||||
|
||||
${NCCOPY} -V lat ${INFILE} ${OUTFILE}
|
||||
|
||||
echo "*** Two Dimensional Tests"
|
||||
echo "*** Testing nccopy -v"
|
||||
|
||||
${NCCOPY} -v lat_2D_rct ${INFILE} ${OUTFILE}
|
||||
|
||||
echo "*** Testing nccopy -V"
|
||||
|
||||
${NCCOPY} -V lat_2D_rct ${INFILE} ${OUTFILE}
|
||||
|
||||
echo "nccopy passed!"
|
||||
exit 0
|
@ -59,7 +59,6 @@ gen_ncc(const char *filename)
|
||||
codeline("#include <stdio.h>");
|
||||
codeline("#include <stdlib.h>");
|
||||
codeline("#include <netcdf.h>");
|
||||
codeline("#include <netcdf_filter.h>");
|
||||
codeline("");
|
||||
codeflush();
|
||||
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
#include "nc.h"
|
||||
#include "netcdf_filter.h"
|
||||
#ifdef USE_NETCDF4
|
||||
#include "nc4internal.h"
|
||||
#endif
|
||||
|
23
ncgen/main.c
23
ncgen/main.c
@ -498,6 +498,13 @@ main(
|
||||
|
||||
/* Compute the k_flag (1st pass) using rules in the man page (ncgen.1).*/
|
||||
|
||||
#ifndef USE_CDF5
|
||||
if(k_flag == NC_FORMAT_CDF5) {
|
||||
derror("Output format CDF5 requested, but netcdf was built without cdf5 support.");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_NETCDF4
|
||||
if(enhanced_flag) {
|
||||
derror("CDL input is enhanced mode, but --disable-netcdf4 was specified during build");
|
||||
@ -506,7 +513,7 @@ main(
|
||||
#endif
|
||||
|
||||
if(l_flag == L_JAVA || l_flag == L_F77) {
|
||||
k_flag = 1;
|
||||
k_flag = NC_FORMAT_CLASSIC;
|
||||
if(enhanced_flag) {
|
||||
derror("Java or Fortran requires classic model CDL input");
|
||||
return 0;
|
||||
@ -517,12 +524,12 @@ main(
|
||||
k_flag = globalspecials._Format;
|
||||
|
||||
if(cdf5_flag && !enhanced_flag && k_flag == 0)
|
||||
k_flag = 5;
|
||||
k_flag = NC_FORMAT_64BIT_DATA;
|
||||
if(enhanced_flag && k_flag == 0)
|
||||
k_flag = 3;
|
||||
k_flag = NC_FORMAT_NETCDF4;
|
||||
|
||||
if(enhanced_flag && k_flag != 3) {
|
||||
if(enhanced_flag && k_flag != 3 && k_flag != 5) {
|
||||
if(enhanced_flag && k_flag != NC_FORMAT_NETCDF4) {
|
||||
if(enhanced_flag && k_flag != NC_FORMAT_NETCDF4 && k_flag != NC_FORMAT_64BIT_DATA) {
|
||||
derror("-k or _Format conflicts with enhanced CDL input");
|
||||
return 0;
|
||||
}
|
||||
@ -530,13 +537,13 @@ main(
|
||||
|
||||
if(specials_flag > 0 && k_flag == 0)
|
||||
#ifdef USE_NETCDF4
|
||||
k_flag = 3;
|
||||
k_flag = NC_FORMAT_NETCDF4;
|
||||
#else
|
||||
k_flag = 1;
|
||||
k_flag = NC_FORMAT_CLASSIC;
|
||||
#endif
|
||||
|
||||
if(k_flag == 0)
|
||||
k_flag = 1;
|
||||
k_flag = NC_FORMAT_CLASSIC;
|
||||
|
||||
/* Figure out usingclassic */
|
||||
switch (k_flag) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
flex -Pncg -8 ncgen.l
|
||||
rm -f ncgenl.c
|
||||
sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
|
||||
bison -pncg -t -d ncgen.y
|
||||
rm -f ncgeny.c ncgeny.h
|
||||
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.c >ncgeny.c
|
||||
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.h >ncgeny.h
|
||||
flex -Pncg -8 ncgen.l
|
||||
rm -f ncgenl.c
|
||||
sed -e s/lex.ncg.c/ncgenl.c/g <lex.ncg.c >ncgenl.c
|
||||
bison -pncg -t -d ncgen.y
|
||||
rm -f ncgeny.c ncgeny.h
|
||||
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.c >ncgeny.c
|
||||
sed -e s/ncgen.tab.c/ncgeny.c/g -e s/ncgen.tab.h/ncgeny.h/g <ncgen.tab.h >ncgeny.h
|
||||
|
@ -1410,15 +1410,19 @@ datalistextend(Datalist* dl, NCConstant* con)
|
||||
dlappend(dl,con);
|
||||
}
|
||||
|
||||
/*
|
||||
Try to infer the file type from the
|
||||
kinds of constructs used in the cdl file.
|
||||
*/
|
||||
static void
|
||||
vercheck(int tid)
|
||||
{
|
||||
switch (tid) {
|
||||
case NC_UBYTE: markcdf5("netCDF4/5 type: UBYTE"); break;
|
||||
case NC_USHORT: markcdf5("netCDF4/5 type: USHORT"); break;
|
||||
case NC_UINT: markcdf5("netCDF4/5 type: UINT"); break;
|
||||
case NC_INT64: markcdf5("netCDF4/5 type: INT64"); break;
|
||||
case NC_UINT64: markcdf5("netCDF4/5 type: UINT64"); break;
|
||||
case NC_UBYTE: markcdf4("netCDF4/5 type: UBYTE"); break;
|
||||
case NC_USHORT: markcdf4("netCDF4/5 type: USHORT"); break;
|
||||
case NC_UINT: markcdf4("netCDF4/5 type: UINT"); break;
|
||||
case NC_INT64: markcdf4("netCDF4/5 type: INT64"); break;
|
||||
case NC_UINT64: markcdf4("netCDF4/5 type: UINT64"); break;
|
||||
case NC_STRING: markcdf4("netCDF4 type: STRING"); break;
|
||||
case NC_VLEN: markcdf4("netCDF4 type: VLEN"); break;
|
||||
case NC_OPAQUE: markcdf4("netCDF4 type: OPAQUE"); break;
|
||||
@ -1445,54 +1449,26 @@ Parse a filter spec string and store it in special
|
||||
static int
|
||||
parsefilterflag(const char* sdata0, Specialdata* special)
|
||||
{
|
||||
char* p;
|
||||
char* sdata = NULL;
|
||||
int stat;
|
||||
size_t count;
|
||||
unsigned int* ulist = NULL;
|
||||
unsigned int* params = NULL;
|
||||
size_t nparams;
|
||||
unsigned int id;
|
||||
|
||||
if(sdata0 == NULL || strlen(sdata0) == 0) goto fail;
|
||||
sdata = strdup(sdata0);
|
||||
if(!NC_parsefilterspec(sdata0,&id,&nparams,*params))
|
||||
goto fail;
|
||||
|
||||
/* Count number of unsigned integers and delimit */
|
||||
p=sdata;
|
||||
for(count=0;;count++) {
|
||||
char* q = strchr(p,',');
|
||||
if(q == NULL) break;
|
||||
*q++ = '\0'; /* delimit */
|
||||
p = q;
|
||||
if(special) {
|
||||
/* Store the id */
|
||||
special->_FilterID = id;
|
||||
/* And the parameter info */
|
||||
special->nparams = nparams;
|
||||
special->_FilterParams = params;
|
||||
ulist = NULL; /* avoid duplicate free */
|
||||
}
|
||||
count++; /* for final piece */
|
||||
|
||||
/* Start by collecting the filter id */
|
||||
p = sdata;
|
||||
stat = sscanf(p,"%u",&special->_FilterID);
|
||||
if(stat != 1) goto fail;
|
||||
count--; /* actual param count minus the id */
|
||||
|
||||
ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count));
|
||||
if(ulist == NULL) goto fail;
|
||||
|
||||
special->nparams = count;
|
||||
for(count=0;count < special->nparams ;) {
|
||||
unsigned int uval;
|
||||
p = p + strlen(p) + 1; /* move to next param */
|
||||
stat = sscanf(p,"%u",&uval);
|
||||
if(stat != 1) goto fail;
|
||||
ulist[count++] = uval;
|
||||
}
|
||||
special->_FilterParams = ulist;
|
||||
ulist = NULL; /* avoid duplicate free */
|
||||
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 1;
|
||||
fail:
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
if(params) free(params);
|
||||
if(special) special->_FilterID = 0;
|
||||
derror("Malformed filter spec: %s",sdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3434,15 +3434,19 @@ datalistextend(Datalist* dl, NCConstant* con)
|
||||
dlappend(dl,con);
|
||||
}
|
||||
|
||||
/*
|
||||
Try to infer the file type from the
|
||||
kinds of constructs used in the cdl file.
|
||||
*/
|
||||
static void
|
||||
vercheck(int tid)
|
||||
{
|
||||
switch (tid) {
|
||||
case NC_UBYTE: markcdf5("netCDF4/5 type: UBYTE"); break;
|
||||
case NC_USHORT: markcdf5("netCDF4/5 type: USHORT"); break;
|
||||
case NC_UINT: markcdf5("netCDF4/5 type: UINT"); break;
|
||||
case NC_INT64: markcdf5("netCDF4/5 type: INT64"); break;
|
||||
case NC_UINT64: markcdf5("netCDF4/5 type: UINT64"); break;
|
||||
case NC_UBYTE: markcdf4("netCDF4/5 type: UBYTE"); break;
|
||||
case NC_USHORT: markcdf4("netCDF4/5 type: USHORT"); break;
|
||||
case NC_UINT: markcdf4("netCDF4/5 type: UINT"); break;
|
||||
case NC_INT64: markcdf4("netCDF4/5 type: INT64"); break;
|
||||
case NC_UINT64: markcdf4("netCDF4/5 type: UINT64"); break;
|
||||
case NC_STRING: markcdf4("netCDF4 type: STRING"); break;
|
||||
case NC_VLEN: markcdf4("netCDF4 type: VLEN"); break;
|
||||
case NC_OPAQUE: markcdf4("netCDF4 type: OPAQUE"); break;
|
||||
|
13
oc2/daplex.c
13
oc2/daplex.c
@ -11,6 +11,9 @@
|
||||
|
||||
#undef URLCVT /* NEVER turn this on */
|
||||
|
||||
/* Do we %xx decode all or part of a DAP Identifer: see dapdecode() */
|
||||
#define DECODE_PARTIAL
|
||||
|
||||
#define DAP2ENCODE
|
||||
#ifdef DAP2ENCODE
|
||||
#define KEEPSLASH
|
||||
@ -355,8 +358,8 @@ daplexcleanup(DAPlexstate** lexstatep)
|
||||
1. if the encoded character is in fact a legal DAP2 character
|
||||
(alphanum+"_!~*'-\"") then it is decoded, otherwise not.
|
||||
*/
|
||||
#ifndef DECODE_IDENTIFIERS
|
||||
static char* decodelist =
|
||||
#ifdef DECODE_PARTIAL
|
||||
static char* decodeset = /* Specify which characters are decoded */
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_!~*'-\"";
|
||||
#endif
|
||||
|
||||
@ -364,10 +367,10 @@ char*
|
||||
dapdecode(DAPlexstate* lexstate, char* name)
|
||||
{
|
||||
char* decoded = NULL;
|
||||
#ifdef DECODE_IDENTIFIERS
|
||||
decoded = ncuridecode(name);
|
||||
#ifdef DECODE_PARTIAL
|
||||
decoded = ncuridecodepartial(name,decodeset); /* Decode selected */
|
||||
#else
|
||||
decoded = ncuridecodeonly(name,decodelist);
|
||||
decoded = ncuridecode(name); /* Decode everything */
|
||||
#endif
|
||||
nclistpush(lexstate->reclaim,(void*)decoded);
|
||||
return decoded;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "config.h"
|
||||
#include <curl/curl.h>
|
||||
#include "ocinternal.h"
|
||||
#include "occurlfunctions.h"
|
||||
#include "ocdebug.h"
|
||||
|
||||
static int nflags = 0;
|
||||
@ -22,7 +23,10 @@ static struct OCCURLFLAG oc_curlflags[] = {
|
||||
{"CURLOPT_ERRORBUFFER",CURLOPT_ERRORBUFFER,10010,CF_STRING},
|
||||
{"CURLOPT_FOLLOWLOCATION",CURLOPT_FOLLOWLOCATION,52,CF_LONG},
|
||||
{"CURLOPT_HTTPAUTH",CURLOPT_HTTPAUTH,1007,CF_LONG},
|
||||
#ifdef HAVE_CURLOPT_KEYPASSWD
|
||||
{"CURLOPT_KEYPASSWD",CURLOPT_KEYPASSWD,10026,CF_STRING},
|
||||
{"CURLOPT_SSLKEYPASSWD",CURLOPT_SSLKEYPASSWD,CURLOPT_KEYPASSWD,CF_STRING},
|
||||
#endif
|
||||
{"CURLOPT_MAXREDIRS",CURLOPT_MAXREDIRS,68,CF_LONG},
|
||||
{"CURLOPT_NETRC",CURLOPT_NETRC,51,CF_LONG},
|
||||
{"CURLOPT_NETRC_FILE",CURLOPT_NETRC_FILE,10118,CF_STRING},
|
||||
@ -32,7 +36,6 @@ static struct OCCURLFLAG oc_curlflags[] = {
|
||||
{"CURLOPT_PROXYUSERPWD",CURLOPT_PROXYUSERPWD,10006,CF_STRING},
|
||||
{"CURLOPT_SSLCERT",CURLOPT_SSLCERT,10025,CF_STRING},
|
||||
{"CURLOPT_SSLKEY",CURLOPT_SSLKEY,10087,CF_STRING},
|
||||
{"CURLOPT_SSLKEYPASSWD",CURLOPT_SSLKEYPASSWD,CURLOPT_KEYPASSWD,CF_STRING},
|
||||
{"CURLOPT_SSL_VERIFYHOST",CURLOPT_SSL_VERIFYHOST,81,CF_LONG},
|
||||
{"CURLOPT_SSL_VERIFYPEER",CURLOPT_SSL_VERIFYPEER,64,CF_LONG},
|
||||
{"CURLOPT_TIMEOUT",CURLOPT_TIMEOUT,13,CF_LONG},
|
||||
@ -43,205 +46,6 @@ static struct OCCURLFLAG oc_curlflags[] = {
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
#if 0
|
||||
static struct OCCURLFLAG oc_allcurlflags[] = {
|
||||
{"CURLOPT_ADDRESS_SCOPE",CURLOPT_ADDRESS_SCOPE,171,CF_UNKNOWN},
|
||||
{"CURLOPT_APPEND",CURLOPT_APPEND,50,CF_UNKNOWN},
|
||||
{"CURLOPT_AUTOREFERER",CURLOPT_AUTOREFERER,58,CF_UNKNOWN},
|
||||
{"CURLOPT_BUFFERSIZE",CURLOPT_BUFFERSIZE,98,CF_UNKNOWN},
|
||||
{"CURLOPT_CAINFO",CURLOPT_CAINFO,10065,CF_UNKNOWN},
|
||||
{"CURLOPT_CAPATH",CURLOPT_CAPATH,10097,CF_UNKNOWN},
|
||||
{"CURLOPT_CERTINFO",CURLOPT_CERTINFO,172,CF_UNKNOWN},
|
||||
{"CURLOPT_CHUNK_BGN_FUNCTION",CURLOPT_CHUNK_BGN_FUNCTION,20198,CF_UNKNOWN},
|
||||
{"CURLOPT_CHUNK_DATA",CURLOPT_CHUNK_DATA,10201,CF_UNKNOWN},
|
||||
{"CURLOPT_CHUNK_END_FUNCTION",CURLOPT_CHUNK_END_FUNCTION,20199,CF_UNKNOWN},
|
||||
{"CURLOPT_CLOSEPOLICY",CURLOPT_CLOSEPOLICY,72,CF_UNKNOWN},
|
||||
{"CURLOPT_CONNECT_ONLY",CURLOPT_CONNECT_ONLY,141,CF_UNKNOWN},
|
||||
{"CURLOPT_CONNECTTIMEOUT",CURLOPT_CONNECTTIMEOUT,78,CF_UNKNOWN},
|
||||
{"CURLOPT_CONNECTTIMEOUT_MS",CURLOPT_CONNECTTIMEOUT_MS,156,CF_UNKNOWN},
|
||||
{"CURLOPT_CONV_FROM_NETWORK_FUNCTION",CURLOPT_CONV_FROM_NETWORK_FUNCTION,20142,CF_UNKNOWN},
|
||||
{"CURLOPT_CONV_FROM_UTF8_FUNCTION",CURLOPT_CONV_FROM_UTF8_FUNCTION,20144,CF_UNKNOWN},
|
||||
{"CURLOPT_CONV_TO_NETWORK_FUNCTION",CURLOPT_CONV_TO_NETWORK_FUNCTION,20143,CF_UNKNOWN},
|
||||
{"CURLOPT_COOKIE",CURLOPT_COOKIE,10022,CF_UNKNOWN},
|
||||
{"CURLOPT_COOKIEFILE",CURLOPT_COOKIEFILE,10031,CF_UNKNOWN},
|
||||
{"CURLOPT_COOKIEJAR",CURLOPT_COOKIEJAR,10082,CF_UNKNOWN},
|
||||
{"CURLOPT_COOKIELIST",CURLOPT_COOKIELIST,10135,CF_UNKNOWN},
|
||||
{"CURLOPT_COOKIESESSION",CURLOPT_COOKIESESSION,96,CF_UNKNOWN},
|
||||
{"CURLOPT_COPYPOSTFIELDS",CURLOPT_COPYPOSTFIELDS,10165,CF_UNKNOWN},
|
||||
{"CURLOPT_CRLF",CURLOPT_CRLF,27,CF_UNKNOWN},
|
||||
{"CURLOPT_CRLFILE",CURLOPT_CRLFILE,10169,CF_UNKNOWN},
|
||||
{"CURLOPT_CUSTOMREQUEST",CURLOPT_CUSTOMREQUEST,10036,CF_UNKNOWN},
|
||||
{"CURLOPT_DEBUGDATA",CURLOPT_DEBUGDATA,10095,CF_UNKNOWN},
|
||||
{"CURLOPT_DEBUGFUNCTION",CURLOPT_DEBUGFUNCTION,20094,CF_UNKNOWN},
|
||||
{"CURLOPT_DIRLISTONLY",CURLOPT_DIRLISTONLY,48,CF_UNKNOWN},
|
||||
{"CURLOPT_DNS_CACHE_TIMEOUT",CURLOPT_DNS_CACHE_TIMEOUT,92,CF_UNKNOWN},
|
||||
{"CURLOPT_DNS_USE_GLOBAL_CACHE",CURLOPT_DNS_USE_GLOBAL_CACHE,91,CF_UNKNOWN},
|
||||
{"CURLOPT_EGDSOCKET",CURLOPT_EGDSOCKET,10077,CF_UNKNOWN},
|
||||
{"CURLOPT_ENCODING",CURLOPT_ENCODING,10102,CF_UNKNOWN},
|
||||
{"CURLOPT_ERRORBUFFER",CURLOPT_ERRORBUFFER,10010,CF_UNKNOWN},
|
||||
{"CURLOPT_FAILONERROR",CURLOPT_FAILONERROR,45,CF_UNKNOWN},
|
||||
{"CURLOPT_FILE",CURLOPT_FILE,10001,CF_UNKNOWN},
|
||||
{"CURLOPT_FILETIME",CURLOPT_FILETIME,69,CF_UNKNOWN},
|
||||
{"CURLOPT_FNMATCH_DATA",CURLOPT_FNMATCH_DATA,10202,CF_UNKNOWN},
|
||||
{"CURLOPT_FNMATCH_FUNCTION",CURLOPT_FNMATCH_FUNCTION,20200,CF_UNKNOWN},
|
||||
{"CURLOPT_FOLLOWLOCATION",CURLOPT_FOLLOWLOCATION,52,CF_UNKNOWN},
|
||||
{"CURLOPT_FORBID_REUSE",CURLOPT_FORBID_REUSE,75,CF_UNKNOWN},
|
||||
{"CURLOPT_FRESH_CONNECT",CURLOPT_FRESH_CONNECT,74,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_ACCOUNT",CURLOPT_FTP_ACCOUNT,10134,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_ALTERNATIVE_TO_USER",CURLOPT_FTP_ALTERNATIVE_TO_USER,10147,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_CREATE_MISSING_DIRS",CURLOPT_FTP_CREATE_MISSING_DIRS,110,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_FILEMETHOD",CURLOPT_FTP_FILEMETHOD,138,CF_UNKNOWN},
|
||||
{"CURLOPT_FTPPORT",CURLOPT_FTPPORT,10017,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_RESPONSE_TIMEOUT",CURLOPT_FTP_RESPONSE_TIMEOUT,112,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_SKIP_PASV_IP",CURLOPT_FTP_SKIP_PASV_IP,137,CF_UNKNOWN},
|
||||
{"CURLOPT_FTPSSLAUTH",CURLOPT_FTPSSLAUTH,129,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_SSL_CCC",CURLOPT_FTP_SSL_CCC,154,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_USE_EPRT",CURLOPT_FTP_USE_EPRT,106,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_USE_EPSV",CURLOPT_FTP_USE_EPSV,85,CF_UNKNOWN},
|
||||
{"CURLOPT_FTP_USE_PRET",CURLOPT_FTP_USE_PRET,188,CF_UNKNOWN},
|
||||
{"CURLOPT_GSSAPI_DELEGATION",CURLOPT_GSSAPI_DELEGATION,210,CF_UNKNOWN},
|
||||
{"CURLOPT_HEADER",CURLOPT_HEADER,42,CF_UNKNOWN},
|
||||
{"CURLOPT_HEADERFUNCTION",CURLOPT_HEADERFUNCTION,20079,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTP200ALIASES",CURLOPT_HTTP200ALIASES,10104,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTPAUTH",CURLOPT_HTTPAUTH,107,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTP_CONTENT_DECODING",CURLOPT_HTTP_CONTENT_DECODING,158,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTPGET",CURLOPT_HTTPGET,80,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTPHEADER",CURLOPT_HTTPHEADER,10023,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTPPOST",CURLOPT_HTTPPOST,10024,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTPPROXYTUNNEL",CURLOPT_HTTPPROXYTUNNEL,61,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTP_TRANSFER_DECODING",CURLOPT_HTTP_TRANSFER_DECODING,157,CF_UNKNOWN},
|
||||
{"CURLOPT_HTTP_VERSION",CURLOPT_HTTP_VERSION,84,CF_UNKNOWN},
|
||||
{"CURLOPT_IGNORE_CONTENT_LENGTH",CURLOPT_IGNORE_CONTENT_LENGTH,136,CF_UNKNOWN},
|
||||
{"CURLOPT_INFILE",CURLOPT_INFILE,10009,CF_UNKNOWN},
|
||||
{"CURLOPT_INFILESIZE",CURLOPT_INFILESIZE,14,CF_UNKNOWN},
|
||||
{"CURLOPT_INFILESIZE_LARGE",CURLOPT_INFILESIZE_LARGE,30115,CF_UNKNOWN},
|
||||
{"CURLOPT_INTERFACE",CURLOPT_INTERFACE,10062,CF_UNKNOWN},
|
||||
{"CURLOPT_INTERLEAVEDATA",CURLOPT_INTERLEAVEDATA,10195,CF_UNKNOWN},
|
||||
{"CURLOPT_INTERLEAVEFUNCTION",CURLOPT_INTERLEAVEFUNCTION,20196,CF_UNKNOWN},
|
||||
{"CURLOPT_IOCTLDATA",CURLOPT_IOCTLDATA,10131,CF_UNKNOWN},
|
||||
{"CURLOPT_IOCTLFUNCTION",CURLOPT_IOCTLFUNCTION,20130,CF_UNKNOWN},
|
||||
{"CURLOPT_IPRESOLVE",CURLOPT_IPRESOLVE,113,CF_UNKNOWN},
|
||||
{"CURLOPT_ISSUERCERT",CURLOPT_ISSUERCERT,10170,CF_UNKNOWN},
|
||||
{"CURLOPT_KEYPASSWD",CURLOPT_KEYPASSWD,10026,CF_UNKNOWN},
|
||||
{"CURLOPT_KRBLEVEL",CURLOPT_KRBLEVEL,10063,CF_UNKNOWN},
|
||||
{"CURLOPT_LOCALPORT",CURLOPT_LOCALPORT,139,CF_UNKNOWN},
|
||||
{"CURLOPT_LOCALPORTRANGE",CURLOPT_LOCALPORTRANGE,140,CF_UNKNOWN},
|
||||
{"CURLOPT_LOW_SPEED_LIMIT",CURLOPT_LOW_SPEED_LIMIT,19,CF_UNKNOWN},
|
||||
{"CURLOPT_LOW_SPEED_TIME",CURLOPT_LOW_SPEED_TIME,20,CF_UNKNOWN},
|
||||
{"CURLOPT_MAIL_FROM",CURLOPT_MAIL_FROM,10186,CF_UNKNOWN},
|
||||
{"CURLOPT_MAIL_RCPT",CURLOPT_MAIL_RCPT,10187,CF_UNKNOWN},
|
||||
{"CURLOPT_MAXCONNECTS",CURLOPT_MAXCONNECTS,71,CF_UNKNOWN},
|
||||
{"CURLOPT_MAXFILESIZE",CURLOPT_MAXFILESIZE,114,CF_UNKNOWN},
|
||||
{"CURLOPT_MAXFILESIZE_LARGE",CURLOPT_MAXFILESIZE_LARGE,30117,CF_UNKNOWN},
|
||||
{"CURLOPT_MAX_RECV_SPEED_LARGE",CURLOPT_MAX_RECV_SPEED_LARGE,30146,CF_UNKNOWN},
|
||||
{"CURLOPT_MAXREDIRS",CURLOPT_MAXREDIRS,68,CF_UNKNOWN},
|
||||
{"CURLOPT_MAX_SEND_SPEED_LARGE",CURLOPT_MAX_SEND_SPEED_LARGE,30145,CF_UNKNOWN},
|
||||
{"CURLOPT_NETRC",CURLOPT_NETRC,51,CF_UNKNOWN},
|
||||
{"CURLOPT_NETRC_FILE",CURLOPT_NETRC_FILE,10118,CF_UNKNOWN},
|
||||
{"CURLOPT_NEW_DIRECTORY_PERMS",CURLOPT_NEW_DIRECTORY_PERMS,160,CF_UNKNOWN},
|
||||
{"CURLOPT_NEW_FILE_PERMS",CURLOPT_NEW_FILE_PERMS,159,CF_UNKNOWN},
|
||||
{"CURLOPT_NOBODY",CURLOPT_NOBODY,44,CF_UNKNOWN},
|
||||
{"CURLOPT_NOPROGRESS",CURLOPT_NOPROGRESS,43,CF_UNKNOWN},
|
||||
{"CURLOPT_NOPROXY",CURLOPT_NOPROXY,10177,CF_UNKNOWN},
|
||||
{"CURLOPT_NOSIGNAL",CURLOPT_NOSIGNAL,99,CF_UNKNOWN},
|
||||
{"CURLOPT_OPENSOCKETDATA",CURLOPT_OPENSOCKETDATA,10164,CF_UNKNOWN},
|
||||
{"CURLOPT_OPENSOCKETFUNCTION",CURLOPT_OPENSOCKETFUNCTION,20163,CF_UNKNOWN},
|
||||
{"CURLOPT_PASSWORD",CURLOPT_PASSWORD,10174,CF_UNKNOWN},
|
||||
{"CURLOPT_PORT",CURLOPT_PORT,3,CF_UNKNOWN},
|
||||
{"CURLOPT_POST",CURLOPT_POST,47,CF_UNKNOWN},
|
||||
{"CURLOPT_POSTFIELDS",CURLOPT_POSTFIELDS,10015,CF_UNKNOWN},
|
||||
{"CURLOPT_POSTFIELDSIZE",CURLOPT_POSTFIELDSIZE,60,CF_UNKNOWN},
|
||||
{"CURLOPT_POSTFIELDSIZE_LARGE",CURLOPT_POSTFIELDSIZE_LARGE,30120,CF_UNKNOWN},
|
||||
{"CURLOPT_POSTQUOTE",CURLOPT_POSTQUOTE,10039,CF_UNKNOWN},
|
||||
{"CURLOPT_POSTREDIR",CURLOPT_POSTREDIR,161,CF_UNKNOWN},
|
||||
{"CURLOPT_PREQUOTE",CURLOPT_PREQUOTE,10093,CF_UNKNOWN},
|
||||
{"CURLOPT_PRIVATE",CURLOPT_PRIVATE,10103,CF_UNKNOWN},
|
||||
{"CURLOPT_PROGRESSDATA",CURLOPT_PROGRESSDATA,10057,CF_UNKNOWN},
|
||||
{"CURLOPT_PROGRESSFUNCTION",CURLOPT_PROGRESSFUNCTION,20056,CF_UNKNOWN},
|
||||
{"CURLOPT_PROTOCOLS",CURLOPT_PROTOCOLS,181,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXY",CURLOPT_PROXY,10004,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXYAUTH",CURLOPT_PROXYAUTH,111,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXYPASSWORD",CURLOPT_PROXYPASSWORD,10176,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXYPORT",CURLOPT_PROXYPORT,59,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXY_TRANSFER_MODE",CURLOPT_PROXY_TRANSFER_MODE,166,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXYTYPE",CURLOPT_PROXYTYPE,101,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXYUSERNAME",CURLOPT_PROXYUSERNAME,10175,CF_UNKNOWN},
|
||||
{"CURLOPT_PROXYUSERPWD",CURLOPT_PROXYUSERPWD,10006,CF_UNKNOWN},
|
||||
{"CURLOPT_PUT",CURLOPT_PUT,54,CF_UNKNOWN},
|
||||
{"CURLOPT_QUOTE",CURLOPT_QUOTE,10028,CF_UNKNOWN},
|
||||
{"CURLOPT_RANDOM_FILE",CURLOPT_RANDOM_FILE,10076,CF_UNKNOWN},
|
||||
{"CURLOPT_RANGE",CURLOPT_RANGE,10007,CF_UNKNOWN},
|
||||
{"CURLOPT_READFUNCTION",CURLOPT_READFUNCTION,20012,CF_UNKNOWN},
|
||||
{"CURLOPT_REDIR_PROTOCOLS",CURLOPT_REDIR_PROTOCOLS,182,CF_UNKNOWN},
|
||||
{"CURLOPT_REFERER",CURLOPT_REFERER,10016,CF_UNKNOWN},
|
||||
{"CURLOPT_RESUME_FROM",CURLOPT_RESUME_FROM,21,CF_UNKNOWN},
|
||||
{"CURLOPT_RESUME_FROM_LARGE",CURLOPT_RESUME_FROM_LARGE,30116,CF_UNKNOWN},
|
||||
{"CURLOPT_RTSP_CLIENT_CSEQ",CURLOPT_RTSP_CLIENT_CSEQ,193,CF_UNKNOWN},
|
||||
{"CURLOPT_RTSP_REQUEST",CURLOPT_RTSP_REQUEST,189,CF_UNKNOWN},
|
||||
{"CURLOPT_RTSP_SERVER_CSEQ",CURLOPT_RTSP_SERVER_CSEQ,194,CF_UNKNOWN},
|
||||
{"CURLOPT_RTSP_SESSION_ID",CURLOPT_RTSP_SESSION_ID,10190,CF_UNKNOWN},
|
||||
{"CURLOPT_RTSP_STREAM_URI",CURLOPT_RTSP_STREAM_URI,10191,CF_UNKNOWN},
|
||||
{"CURLOPT_RTSP_TRANSPORT",CURLOPT_RTSP_TRANSPORT,10192,CF_UNKNOWN},
|
||||
{"CURLOPT_SEEKDATA",CURLOPT_SEEKDATA,10168,CF_UNKNOWN},
|
||||
{"CURLOPT_SEEKFUNCTION",CURLOPT_SEEKFUNCTION,20167,CF_UNKNOWN},
|
||||
{"CURLOPT_SHARE",CURLOPT_SHARE,10100,CF_UNKNOWN},
|
||||
{"CURLOPT_SOCKOPTDATA",CURLOPT_SOCKOPTDATA,10149,CF_UNKNOWN},
|
||||
{"CURLOPT_SOCKOPTFUNCTION",CURLOPT_SOCKOPTFUNCTION,20148,CF_UNKNOWN},
|
||||
{"CURLOPT_SOCKS5_GSSAPI_NEC",CURLOPT_SOCKS5_GSSAPI_NEC,180,CF_UNKNOWN},
|
||||
{"CURLOPT_SOCKS5_GSSAPI_SERVICE",CURLOPT_SOCKS5_GSSAPI_SERVICE,10179,CF_UNKNOWN},
|
||||
{"CURLOPT_SSH_AUTH_TYPES",CURLOPT_SSH_AUTH_TYPES,151,CF_UNKNOWN},
|
||||
{"CURLOPT_SSH_HOST_PUBLIC_KEY_MD5",CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,10162,CF_UNKNOWN},
|
||||
{"CURLOPT_SSH_KEYDATA",CURLOPT_SSH_KEYDATA,10185,CF_UNKNOWN},
|
||||
{"CURLOPT_SSH_KEYFUNCTION",CURLOPT_SSH_KEYFUNCTION,20184,CF_UNKNOWN},
|
||||
{"CURLOPT_SSH_KNOWNHOSTS",CURLOPT_SSH_KNOWNHOSTS,10183,CF_UNKNOWN},
|
||||
{"CURLOPT_SSH_PRIVATE_KEYFILE",CURLOPT_SSH_PRIVATE_KEYFILE,10153,CF_UNKNOWN},
|
||||
{"CURLOPT_SSH_PUBLIC_KEYFILE",CURLOPT_SSH_PUBLIC_KEYFILE,10152,CF_UNKNOWN},
|
||||
{"CURLOPT_SSLCERT",CURLOPT_SSLCERT,10025,CF_UNKNOWN},
|
||||
{"CURLOPT_SSLCERTTYPE",CURLOPT_SSLCERTTYPE,10086,CF_UNKNOWN},
|
||||
{"CURLOPT_SSL_CIPHER_LIST",CURLOPT_SSL_CIPHER_LIST,10083,CF_UNKNOWN},
|
||||
{"CURLOPT_SSL_CTX_DATA",CURLOPT_SSL_CTX_DATA,10109,CF_UNKNOWN},
|
||||
{"CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,20108,CF_UNKNOWN},
|
||||
{"CURLOPT_SSLENGINE",CURLOPT_SSLENGINE,10089,CF_UNKNOWN},
|
||||
{"CURLOPT_SSLENGINE_DEFAULT",CURLOPT_SSLENGINE_DEFAULT,90,CF_UNKNOWN},
|
||||
{"CURLOPT_SSLKEY",CURLOPT_SSLKEY,10087,CF_UNKNOWN},
|
||||
{"CURLOPT_SSLKEYTYPE",CURLOPT_SSLKEYTYPE,10088,CF_UNKNOWN},
|
||||
{"CURLOPT_SSL_SESSIONID_CACHE",CURLOPT_SSL_SESSIONID_CACHE,150,CF_UNKNOWN},
|
||||
{"CURLOPT_SSL_VERIFYHOST",CURLOPT_SSL_VERIFYHOST,81,CF_UNKNOWN},
|
||||
{"CURLOPT_SSL_VERIFYPEER",CURLOPT_SSL_VERIFYPEER,64,CF_UNKNOWN},
|
||||
{"CURLOPT_SSLVERSION",CURLOPT_SSLVERSION,32,CF_UNKNOWN},
|
||||
{"CURLOPT_STDERR",CURLOPT_STDERR,10037,CF_UNKNOWN},
|
||||
{"CURLOPT_TCP_NODELAY",CURLOPT_TCP_NODELAY,121,CF_UNKNOWN},
|
||||
{"CURLOPT_TELNETOPTIONS",CURLOPT_TELNETOPTIONS,10070,CF_UNKNOWN},
|
||||
{"CURLOPT_TFTP_BLKSIZE",CURLOPT_TFTP_BLKSIZE,178,CF_UNKNOWN},
|
||||
{"CURLOPT_TIMECONDITION",CURLOPT_TIMECONDITION,33,CF_UNKNOWN},
|
||||
{"CURLOPT_TIMEOUT",CURLOPT_TIMEOUT,13,CF_UNKNOWN},
|
||||
{"CURLOPT_TIMEOUT_MS",CURLOPT_TIMEOUT_MS,155,CF_UNKNOWN},
|
||||
{"CURLOPT_TIMEVALUE",CURLOPT_TIMEVALUE,34,CF_UNKNOWN},
|
||||
{"CURLOPT_TRANSFERTEXT",CURLOPT_TRANSFERTEXT,53,CF_UNKNOWN},
|
||||
{"CURLOPT_UNRESTRICTED_AUTH",CURLOPT_UNRESTRICTED_AUTH,105,CF_UNKNOWN},
|
||||
{"CURLOPT_UPLOAD",CURLOPT_UPLOAD,46,CF_UNKNOWN},
|
||||
{"CURLOPT_URL",CURLOPT_URL,10002,CF_UNKNOWN},
|
||||
{"CURLOPT_USERAGENT",CURLOPT_USERAGENT,10018,CF_UNKNOWN},
|
||||
{"CURLOPT_USERNAME",CURLOPT_USERNAME,10173,CF_UNKNOWN},
|
||||
{"CURLOPT_USERPWD",CURLOPT_USERPWD,10005,CF_UNKNOWN},
|
||||
{"CURLOPT_USE_SSL",CURLOPT_USE_SSL,119,CF_UNKNOWN},
|
||||
{"CURLOPT_VERBOSE",CURLOPT_VERBOSE,41,CF_UNKNOWN},
|
||||
{"CURLOPT_WILDCARDMATCH",CURLOPT_WILDCARDMATCH,197,CF_UNKNOWN},
|
||||
{"CURLOPT_WRITEFUNCTION",CURLOPT_WRITEFUNCTION,20011,CF_UNKNOWN},
|
||||
{"CURLOPT_WRITEHEADER",CURLOPT_WRITEHEADER,10029,CF_UNKNOWN},
|
||||
{"CURLOPT_WRITEINFO",CURLOPT_WRITEINFO,10040,CF_UNKNOWN},
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
struct OCCURLFLAG*
|
||||
occurlflagsall(void)
|
||||
{
|
||||
if(nflags == 0) initialize();
|
||||
return oc_allcurlflags;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int touppercase(int c)
|
||||
{
|
||||
if(c >= 'a' && c <= 'z')
|
||||
|
@ -11,12 +11,6 @@
|
||||
/* Mnemonic */
|
||||
#define OPTARG void*
|
||||
|
||||
/* Condition on libcurl version */
|
||||
/* Set up an alias as needed */
|
||||
#ifndef HAVE_CURLOPT_KEYPASSWD
|
||||
#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
|
||||
#endif
|
||||
|
||||
#define NETRCFILETAG "HTTP.NETRC"
|
||||
|
||||
#define CHECK(state,flag,value) {if(check(state,flag,(void*)value) != OC_NOERR) {goto done;}}
|
||||
@ -94,9 +88,10 @@ ocset_curlflag(OCstate* state, int flag)
|
||||
|
||||
switch (flag) {
|
||||
|
||||
case CURLOPT_USERPWD:
|
||||
if(state->creds.userpwd != NULL) {
|
||||
CHECK(state, CURLOPT_USERPWD, state->creds.userpwd);
|
||||
case CURLOPT_USERPWD: /* Does both user and pwd */
|
||||
if(state->creds.user != NULL && state->creds.pwd != NULL) {
|
||||
CHECK(state, CURLOPT_USERNAME, state->creds.user);
|
||||
CHECK(state, CURLOPT_PASSWORD, state->creds.pwd);
|
||||
CHECK(state, CURLOPT_HTTPAUTH, (OPTARG)CURLAUTH_ANY);
|
||||
}
|
||||
break;
|
||||
@ -155,8 +150,9 @@ ocset_curlflag(OCstate* state, int flag)
|
||||
if(state->proxy.host != NULL) {
|
||||
CHECK(state, CURLOPT_PROXY, state->proxy.host);
|
||||
CHECK(state, CURLOPT_PROXYPORT, (OPTARG)(long)state->proxy.port);
|
||||
if(state->proxy.userpwd) {
|
||||
CHECK(state, CURLOPT_PROXYUSERPWD, state->proxy.userpwd);
|
||||
if(state->proxy.user != NULL && state->proxy.pwd != NULL) {
|
||||
CHECK(state, CURLOPT_PROXYUSERNAME, state->proxy.user);
|
||||
CHECK(state, CURLOPT_PROXYPASSWORD, state->proxy.pwd);
|
||||
#ifdef CURLOPT_PROXYAUTH
|
||||
CHECK(state, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
|
||||
#endif
|
||||
@ -340,6 +336,7 @@ oc_curl_protocols(struct OCGLOBALSTATE* state)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
"Inverse" of ocset_curlflag;
|
||||
Given a flag and value, it updates state.
|
||||
@ -352,9 +349,14 @@ ocset_curlstate(OCstate* state, int flag, void* value)
|
||||
|
||||
switch (flag) {
|
||||
|
||||
case CURLOPT_USERPWD:
|
||||
if(state->creds.userpwd != NULL) free(state->creds.userpwd);
|
||||
state->creds.userpwd = strdup((char*)value);
|
||||
case CURLOPT_USERNAME:
|
||||
if(state->creds.user != NULL) free(state->creds.user);
|
||||
state->creds.user = strdup((char*)value);
|
||||
break;
|
||||
|
||||
case CURLOPT_PASSWORD:
|
||||
if(state->creds.pwd != NULL) free(state->creds.pwd);
|
||||
state->creds.pwd = strdup((char*)value);
|
||||
break;
|
||||
|
||||
case CURLOPT_COOKIEJAR: case CURLOPT_COOKIEFILE:
|
||||
@ -443,3 +445,4 @@ ocset_curlstate(OCstate* state, int flag, void* value)
|
||||
done:
|
||||
return stat;
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,15 @@
|
||||
#define _CURLFUNCTION_H_
|
||||
|
||||
|
||||
/* Condition on libcurl version */
|
||||
/* Set up an alias as needed */
|
||||
#ifndef HAVE_CURLOPT_KEYPASSWD
|
||||
#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD
|
||||
#endif
|
||||
#ifndef HAVE_CURLINFO_RESPONSE_CODE
|
||||
#define CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
|
||||
#endif
|
||||
|
||||
extern OCerror ocset_curlopt(OCstate* state, int flag, void* value);
|
||||
|
||||
struct OCCURLFLAG* occurlflagbyflag(int flag);
|
||||
@ -18,7 +27,6 @@ extern OCerror ocset_flags_perfetch(OCstate*);
|
||||
extern OCerror ocset_flags_perlink(OCstate*);
|
||||
|
||||
extern OCerror ocset_curlflag(OCstate*,int);
|
||||
extern OCerror ocset_curlstate(OCstate* state, int flag, void* value);
|
||||
|
||||
extern void oc_curl_debug(OCstate* state);
|
||||
|
||||
|
@ -23,11 +23,7 @@ ocfetchhttpcode(CURL* curl)
|
||||
long httpcode = 200;
|
||||
CURLcode cstat = CURLE_OK;
|
||||
/* Extract the http code */
|
||||
#ifdef HAVE_CURLINFO_RESPONSE_CODE
|
||||
cstat = CURLERR(curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&httpcode));
|
||||
#else
|
||||
cstat = curl_easy_getinfo(curl,CURLINFO_HTTP_CODE,&httpcode);
|
||||
#endif
|
||||
if(cstat != CURLE_OK) httpcode = 0;
|
||||
return httpcode;
|
||||
}
|
||||
|
@ -427,8 +427,10 @@ occlose(OCstate* state)
|
||||
ocfree(state->ssl.cainfo);
|
||||
ocfree(state->ssl.capath);
|
||||
ocfree(state->proxy.host);
|
||||
ocfree(state->proxy.userpwd);
|
||||
ocfree(state->creds.userpwd);
|
||||
ocfree(state->proxy.user);
|
||||
ocfree(state->proxy.pwd);
|
||||
ocfree(state->creds.user);
|
||||
ocfree(state->creds.pwd);
|
||||
if(state->curl != NULL) occurlclose(state->curl);
|
||||
ocfree(state);
|
||||
}
|
||||
@ -606,7 +608,6 @@ ocset_curlproperties(OCstate* state)
|
||||
if(path == NULL) return OC_ENOMEM;
|
||||
occopycat(path,len,3,ocglobalstate.tempdir,"/","occookies");
|
||||
stat = ocmktmp(path,&name);
|
||||
fprintf(stderr,"%s => %s\n",state->uri->uri,name); fflush(stderr);
|
||||
free(path);
|
||||
state->curlflags.cookiejar = name;
|
||||
state->curlflags.createdflags |= COOKIECREATED;
|
||||
|
@ -217,10 +217,12 @@ struct OCstate {
|
||||
struct OCproxy {
|
||||
char *host; /*CURLOPT_PROXY*/
|
||||
int port; /*CURLOPT_PROXYPORT*/
|
||||
char* userpwd; /*CURLOPT_PROXYUSERPWD*/
|
||||
char* user; /*CURLOPT_PROXYUSERNAME*/
|
||||
char* pwd; /*CURLOPT_PROXYPASSWORD*/
|
||||
} proxy;
|
||||
struct OCcredentials {
|
||||
char *userpwd; /*CURLOPT_USERPWD*/
|
||||
char *user; /*CURLOPT_USERNAME*/
|
||||
char *pwd; /*CURLOPT_PASSWORD*/
|
||||
} creds;
|
||||
void* usercurldata;
|
||||
long ddslastmodified;
|
||||
|
104
oc2/ocrc.c
104
oc2/ocrc.c
@ -26,7 +26,6 @@ static OCerror rc_search(const char* prefix, const char* rcfile, char** pathp);
|
||||
|
||||
static int rcreadline(FILE* f, char* more, int morelen);
|
||||
static void rctrim(char* text);
|
||||
static char* combinecredentials(const char* user, const char* pwd);
|
||||
|
||||
static void storedump(char* msg, struct OCTriple*, int ntriples);
|
||||
|
||||
@ -48,17 +47,49 @@ occredentials_in_url(const char *url)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Given form user:pwd, parse into user and pwd
|
||||
and do %xx unescaping
|
||||
*/
|
||||
static OCerror
|
||||
ocextract_credentials(const char *url, char **userpwd, char **result_url)
|
||||
parsecredentials(const char* userpwd, char** userp, char** pwdp)
|
||||
{
|
||||
char* user = NULL;
|
||||
char* pwd = NULL;
|
||||
|
||||
if(userpwd == NULL)
|
||||
return OC_EINVAL;
|
||||
user = strdup(userpwd);
|
||||
if(user == NULL)
|
||||
return NC_ENOMEM;
|
||||
pwd = strchr(user,':');
|
||||
if(pwd == NULL)
|
||||
return OC_EINVAL;
|
||||
*pwd = '\0';
|
||||
pwd++;
|
||||
if(userp)
|
||||
*userp = ncuridecode(user);
|
||||
if(pwdp)
|
||||
*pwdp = ncuridecode(pwd);
|
||||
free(user);
|
||||
return OC_NOERR;
|
||||
}
|
||||
|
||||
static OCerror
|
||||
ocextract_credentials(const char *url, char **user, char** pwd, char **result_url)
|
||||
{
|
||||
NCURI* parsed = NULL;
|
||||
if(ncuriparse(url,&parsed) != NCU_OK)
|
||||
|
||||
if(url == NULL || ncuriparse(url,&parsed) != NCU_OK)
|
||||
return OCTHROW(OC_EBADURL);
|
||||
if(parsed->user != NULL || parsed->password == NULL) {
|
||||
ncurifree(parsed);
|
||||
return OCTHROW(OC_EBADURL);
|
||||
}
|
||||
if(userpwd) *userpwd = combinecredentials(parsed->user,parsed->password);
|
||||
if(user)
|
||||
*user = parsed->user;
|
||||
if(pwd)
|
||||
*pwd = parsed->password;
|
||||
ncurifree(parsed);
|
||||
return OC_NOERR;
|
||||
}
|
||||
@ -85,24 +116,40 @@ occombinehostport(const NCURI* uri)
|
||||
return hp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
Combine user and pwd into the user:pwd form.
|
||||
Note that we must %xx escape the user and the pwd
|
||||
*/
|
||||
static char*
|
||||
combinecredentials(const char* user, const char* pwd)
|
||||
{
|
||||
int userPassSize;
|
||||
char *userPassword;
|
||||
char *escapeduser = NULL;
|
||||
char* escapedpwd = NULL;
|
||||
|
||||
if(user == NULL) user = "";
|
||||
if(pwd == NULL) pwd = "";
|
||||
|
||||
userPassSize = strlen(user) + strlen(pwd) + 2;
|
||||
if(user == NULL || pwd == NULL)
|
||||
return NULL;
|
||||
|
||||
userPassSize = 3*strlen(user) + 3*strlen(pwd) + 2; /* times 3 for escapes */
|
||||
userPassword = malloc(sizeof(char) * userPassSize);
|
||||
if (!userPassword) {
|
||||
nclog(NCLOGERR,"Out of Memory\n");
|
||||
return NULL;
|
||||
}
|
||||
occopycat(userPassword,userPassSize-1,3,user,":",pwd);
|
||||
escapeduser = ncuriencodeuserpwd(user);
|
||||
escapedpwd = ncuriencodeuserpwd(pwd);
|
||||
if(escapeduser == NULL || escapedpwd == NULL) {
|
||||
nclog(NCLOGERR,"Out of Memory\n");
|
||||
return NULL;
|
||||
}
|
||||
occopycat(userPassword,userPassSize-1,3,escapeduser,":",escapedpwd);
|
||||
free(escapeduser);
|
||||
free(escapedpwd);
|
||||
return userPassword;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
rcreadline(FILE* f, char* more, int morelen)
|
||||
@ -158,7 +205,7 @@ ocparseproxy(OCstate* state, char* v)
|
||||
return OC_NOERR; /* nothing there*/
|
||||
if (occredentials_in_url(v)) {
|
||||
char *result_url = NULL;
|
||||
ocextract_credentials(v, &state->proxy.userpwd, &result_url);
|
||||
ocextract_credentials(v, &state->proxy.user, &state->proxy.pwd, &result_url);
|
||||
v = result_url;
|
||||
}
|
||||
/* allocating a bit more than likely needed ... */
|
||||
@ -208,7 +255,7 @@ ocparseproxy(OCstate* state, char* v)
|
||||
if (ocdebug > 1) {
|
||||
nclog(NCLOGNOTE,"host name: %s", state->proxy.host);
|
||||
#ifdef INSECURE
|
||||
nclog(NCLOGNOTE,"user+pwd: %s", state->proxy.userpwd);
|
||||
nclog(NCLOGNOTE,"user+pwd: %s+%s", state->proxy.user,state->proxy.pwd);
|
||||
#endif
|
||||
nclog(NCLOGNOTE,"port number: %d", state->proxy.port);
|
||||
}
|
||||
@ -373,8 +420,8 @@ ocrc_load(void)
|
||||
/* locate the configuration files in the following order:
|
||||
1. specified by set_rcfile
|
||||
2. set by DAPRCFILE env variable
|
||||
3. '.'
|
||||
4. $HOME
|
||||
3. '.'/<rcfile>
|
||||
4. $HOME/<rcfile>
|
||||
*/
|
||||
if(ocglobalstate.rc.rcfile != NULL) { /* always use this */
|
||||
path = strdup(ocglobalstate.rc.rcfile);
|
||||
@ -416,7 +463,6 @@ ocrc_process(OCstate* state)
|
||||
OCerror stat = OC_NOERR;
|
||||
char* value = NULL;
|
||||
NCURI* uri = state->uri;
|
||||
char* url_userpwd = NULL;
|
||||
char* url_hostport = NULL;
|
||||
|
||||
if(!ocglobalstate.initialized)
|
||||
@ -428,7 +474,6 @@ ocrc_process(OCstate* state)
|
||||
to getinfo e.g. user:pwd from url
|
||||
*/
|
||||
|
||||
url_userpwd = combinecredentials(uri->user,uri->password);
|
||||
url_hostport = occombinehostport(uri);
|
||||
if(url_hostport == NULL)
|
||||
return OC_ENOMEM;
|
||||
@ -545,21 +590,28 @@ ocrc_process(OCstate* state)
|
||||
|
||||
{ /* Handle various cases for user + password */
|
||||
/* First, see if the user+pwd was in the original url */
|
||||
char* userpwd = NULL;
|
||||
char* user = NULL;
|
||||
char* pwd = NULL;
|
||||
if(url_userpwd != NULL)
|
||||
userpwd = url_userpwd;
|
||||
else {
|
||||
if(uri->user != NULL && uri->password != NULL) {
|
||||
user = uri->user;
|
||||
pwd = uri->password;
|
||||
} else {
|
||||
user = ocrc_lookup("HTTP.CREDENTIALS.USER",url_hostport);
|
||||
pwd = ocrc_lookup("HTTP.CREDENTIALS.PASSWORD",url_hostport);
|
||||
userpwd = ocrc_lookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
|
||||
}
|
||||
if(userpwd == NULL && user != NULL && pwd != NULL) {
|
||||
userpwd = combinecredentials(user,pwd);
|
||||
state->creds.userpwd = userpwd;
|
||||
} else if(userpwd != NULL)
|
||||
state->creds.userpwd = strdup(userpwd);
|
||||
if(user != NULL && pwd != NULL) {
|
||||
state->creds.user = strdup(user);
|
||||
state->creds.pwd = strdup(pwd);
|
||||
} else {
|
||||
/* Could not get user and pwd, so try USERPASSWORD */
|
||||
const char* userpwd = ocrc_lookup("HTTP.CREDENTIALS.USERPASSWORD",url_hostport);
|
||||
if(userpwd != NULL) {
|
||||
stat = parsecredentials(userpwd,&user,&pwd);
|
||||
if(stat) goto done;
|
||||
state->creds.user = user;
|
||||
state->creds.pwd = pwd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
@ -624,7 +676,7 @@ storedump(char* msg, struct OCTriple* triples, int ntriples)
|
||||
if(ntriples < 0 ) ntriples= ocrc->ntriples;
|
||||
for(i=0;i<ntriples;i++) {
|
||||
fprintf(stderr,"\t%s\t%s\t%s\n",
|
||||
(strlen(triples[i].host)==0?"--":triples[i].host),
|
||||
(triples[i].host == NULL || strlen(triples[i].host)==0?"--":triples[i].host),
|
||||
triples[i].key,
|
||||
triples[i].value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user