mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
Merge branch 'master' into cleanncgen.dmh
This commit is contained in:
commit
c9d1589c39
31
.travis.yml
31
.travis.yml
@ -11,33 +11,30 @@ services:
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-signed
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-signed
|
||||
# Ubuntu
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' USECP=FALSE CURHOST=docker-gcc-x64-signed
|
||||
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-signed
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-signed
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' USECP=FALSE CURHOST=docker-gcc-x86-signed
|
||||
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests --enable-cdf5' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' USECP=FALSE CURHOST=docker-gcc-x64-unsigned
|
||||
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-netcdf-4 --disable-dap-remote-tests' COPTS='-DENABLE_NETCDF_4=OFF -DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' USECP=FALSE CURHOST=docker-gcc-x86-unsigned
|
||||
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-signed
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-signed
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' USECP=FALSE CURHOST=docker-gcc-x64-signed
|
||||
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-signed
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-signed
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-fsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-fsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' USECP=FALSE CURHOST=docker-gcc-x86-signed
|
||||
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-gcc-x64-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' CURHOST=docker-clang-x64-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests --enable-cdf5' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=TRUE' USECP=FALSE CURHOST=docker-gcc-x64-unsigned
|
||||
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-gcc-x86-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=clang AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' CURHOST=docker-clang-x86-unsigned
|
||||
- DOCKIMG=unidata/nctests:serial32 USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='CFLAGS=-funsigned-char --disable-dap-remote-tests' COPTS='-DCMAKE_C_FLAGS=-funsigned-char -DENABLE_DAP_REMOTE_TESTS=OFF -DENABLE_CDF5=OFF' USECP=FALSE CURHOST=docker-gcc-x86-unsigned
|
||||
|
||||
# Centos, Fedora
|
||||
- DOCKIMG=unidata/nctests:serial.centos USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='--disable-dap-remote-tests' COPTS='-DENABLE_DAP_REMOTE_TESTS=OFF' USECP=TRUE CURHOST=docker-gcc-x64-centos
|
||||
- DOCKIMG=unidata/nctests:serial.fedora USECMAKE=TRUE USEAC=TRUE DISTCHECK=TRUE USE_CC=gcc AC_COPTS='--disable-dap-remote-tests' COPTS='-DENABLE_DAP_REMOTE_TESTS=OFF' USECP=TRUE CURHOST=docker-gcc-x64-fedora
|
||||
|
||||
before_install:
|
||||
- docker pull $DOCKIMG > /dev/null
|
||||
|
||||
script:
|
||||
|
||||
- docker run --rm -it -h "$CURHOST" -e USEDASH=FALSE -e RUNF=OFF -e RUNCXX=OFF -e RUNP=OFF -e RUNNCO=OFF -e USECMAKE=$USECMAKE -e USEAC=$USEAC -e DISTCHECK=$DISTCHECK -e COPTS="$COPTS" -e AC_OPTS="$AC_OPTS" -e CTEST_OUTPUT_ON_FAILURE=1 -v $(pwd):/netcdf-c -e TESTPROC=100 $DOCKIMG
|
||||
- docker run --rm -it -h "$CURHOST" -e USEDASH=FALSE -e RUNF=OFF -e RUNCXX=OFF -e RUNP=OFF -e RUNNCO=OFF -e USECMAKE=$USECMAKE -e USEAC=$USEAC -e DISTCHECK=$DISTCHECK -e COPTS="$COPTS" -e AC_OPTS="$AC_OPTS" -e CTEST_OUTPUT_ON_FAILURE=1 -v $(pwd):/netcdf-c -e USE_LOCAL_CP=$USECP -e TESTPROC=100 $DOCKIMG
|
||||
|
@ -199,7 +199,7 @@ OPTION(NC_FIND_SHARED_LIBS "Find dynamically-built versions of dependent librari
|
||||
|
||||
##
|
||||
# We've had a request to allow for non-versioned shared libraries.
|
||||
# This seems reasonable enough to accomodate. See
|
||||
# This seems reasonable enough to accommodate. See
|
||||
# https://github.com/Unidata/netcdf-c/issues/228 for more info.
|
||||
##
|
||||
OPTION(ENABLE_SHARED_LIBRARY_VERSION "Encode the library SO version in the file name of the generated library file." ON)
|
||||
@ -588,7 +588,7 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
|
||||
# as a shared library, we will use hdf5 as a shared
|
||||
# library. If we are building netcdf statically,
|
||||
# we will use a static library. This can be toggled
|
||||
# by explicitely modifying NC_FIND_SHARED_LIBS.
|
||||
# by explicitly modifying NC_FIND_SHARED_LIBS.
|
||||
##
|
||||
IF(NC_FIND_SHARED_LIBS)
|
||||
SET(NC_HDF5_LINK_TYPE "shared")
|
||||
@ -686,6 +686,8 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
|
||||
ENDIF()
|
||||
ENDIF(HDF5_C_LIBRARY AND HDF5_HL_LIBRARY AND HDF5_INCLUDE_DIR)
|
||||
|
||||
FIND_PACKAGE(Threads)
|
||||
|
||||
# There is a missing case in the above code so default it
|
||||
IF(NOT HDF5_C_LIBRARY_HDF5 OR "${HDF5_C_LIBRARY_hdf5}" STREQUAL "" )
|
||||
SET(HDF5_C_LIBRARY_hdf5 "${HDF5_C_LIBRARY}")
|
||||
@ -1030,7 +1032,7 @@ IF(ENABLE_PNETCDF)
|
||||
ENDIF(NOT PNETCDF)
|
||||
ENDIF()
|
||||
|
||||
# Options to enable use of fill values for elements casuing NC_ERANGE
|
||||
# Options to enable use of fill values for elements causing NC_ERANGE
|
||||
SET(STATUS_ERANGE_FILL "OFF")
|
||||
OPTION(ENABLE_ERANGE_FILL "Enable use of fill value when out-of-range type conversion causes NC_ERANGE error." OF)
|
||||
IF(ENABLE_ERANGE_FILL)
|
||||
@ -1361,9 +1363,12 @@ MACRO(ADD_EXTRA_DIST files)
|
||||
ENDMACRO()
|
||||
|
||||
# A basic script used to convert m4 files
|
||||
FIND_PROGRAM(NC_M4 NAMES m4)
|
||||
FIND_PROGRAM(NC_M4 NAMES m4 m4.exe)
|
||||
IF(NC_M4)
|
||||
SET(HAVE_M4 TRUE)
|
||||
MESSAGE(STATUS "Found m4: ${NC_M4}")
|
||||
SET(HAVE_M4 TRUE)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "m4 not found.")
|
||||
ENDIF()
|
||||
|
||||
MACRO(GEN_m4 filename)
|
||||
@ -1552,12 +1557,24 @@ ENDMACRO()
|
||||
# Determine if 'bash' is on the system.
|
||||
##
|
||||
|
||||
FIND_PROGRAM(HAVE_BASH NAMES bash)
|
||||
IF(HAVE_BASH)
|
||||
MESSAGE(STATUS "Found bash: ${HAVE_BASH}")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Bash shell not found; disabling shell script tests.")
|
||||
ENDIF()
|
||||
OPTION(ENABLE_BASH_SCRIPT_TESTING "Detection is typically automatic, but this option can be used to force enable/disable bash-script based tests." ON)
|
||||
|
||||
IF(ENABLE_BASH_SCRIPT_TESTING)
|
||||
FIND_PROGRAM(HAVE_BASH bash)
|
||||
IF(HAVE_BASH)
|
||||
STRING(COMPARE EQUAL "${HAVE_BASH}" "C:/Windows/System32/bash.exe" IS_BASH_EXE)
|
||||
IF(NOT IS_BASH_EXE)
|
||||
MESSAGE(STATUS "Found bash: ${HAVE_BASH}")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Ignoring ${HAVE_BASH}")
|
||||
SET(HAVE_BASH "")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Bash shell not found; disabling shell script tests.")
|
||||
ENDIF()
|
||||
ELSE(ENABLE_BASH_SCRIPT_TESTING)
|
||||
SET(HAVE_BASH "")
|
||||
ENDIF(ENABLE_BASH_SCRIPT_TESTING)
|
||||
|
||||
MACRO(add_sh_test prefix F)
|
||||
IF(HAVE_BASH)
|
||||
@ -1632,6 +1649,7 @@ ENDIF(USE_PNETCDF)
|
||||
|
||||
IF(USE_HDF5)
|
||||
add_subdirectory(libsrc4)
|
||||
add_subdirectory(libhdf5)
|
||||
ENDIF(USE_HDF5)
|
||||
|
||||
IF(USE_HDF4)
|
||||
@ -1700,7 +1718,7 @@ ENDIF()
|
||||
ADD_SUBDIRECTORY(docs)
|
||||
|
||||
##
|
||||
# Brute force, grab all of the dlls from the depency directory,
|
||||
# Brute force, grab all of the dlls from the dependency directory,
|
||||
# install them in the binary dir. Grab all of the .libs, put them
|
||||
# in the libdir.
|
||||
##
|
||||
|
@ -7,9 +7,6 @@
|
||||
|
||||
# Ed Hartnett, Ward Fisher
|
||||
|
||||
|
||||
|
||||
|
||||
# This directory stores libtool macros, put there by aclocal.
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
@ -45,6 +42,7 @@ endif
|
||||
if USE_NETCDF4
|
||||
H5_TEST_DIR = h5_test
|
||||
LIBSRC4_DIR = libsrc4
|
||||
LIBHDF5 = libhdf5
|
||||
NC_TEST4 = nc_test4
|
||||
endif
|
||||
|
||||
@ -86,8 +84,9 @@ endif
|
||||
# and run. ncgen must come before ncdump, because their tests
|
||||
# depend on it.
|
||||
SUBDIRS = include $(H5_TEST_DIR) libdispatch libsrc $(LIBSRC4_DIR) \
|
||||
$(LIBSRCP) $(LIBHDF4) $(OCLIB) $(DAP2) ${DAP4} liblib $(NCGEN3) \
|
||||
$(NCGEN) $(NCDUMP) ${PLUGIN_DIR} $(TESTDIRS) docs $(EXAMPLES)
|
||||
$(LIBSRCP) $(LIBHDF4) $(LIBHDF5) $(OCLIB) $(DAP2) ${DAP4} liblib \
|
||||
$(NCGEN3) $(NCGEN) $(NCDUMP) ${PLUGIN_DIR} $(TESTDIRS) docs \
|
||||
$(EXAMPLES)
|
||||
|
||||
# Remove these generated files, for a distclean.
|
||||
DISTCLEANFILES = VERSION comps.txt test_prog libnetcdf.settings \
|
||||
|
@ -7,6 +7,7 @@ This file contains a high-level description of this package's evolution. Release
|
||||
|
||||
## 4.7.0 - TBD
|
||||
|
||||
* [Enhancement] Expanded the capabilities of `NC_INMEMORY` to support writing and accessing the final modified memory. See [GitHub #879](https://github.com/Unidata/netcdf-c/pull/879) for more information.
|
||||
* [Enhancement] Made CDF5 support enabled by default. See [Github #931](https://github.com/Unidata/netcdf-c/issues/931) for more information.
|
||||
* [Bug Fix] Corrected a number of memory issues identified in `ncgen`. See [GitHub #558 for more information](https://github.com/Unidata/netcdf-c/pull/558).
|
||||
|
||||
|
44
appveyor.yml
Normal file
44
appveyor.yml
Normal file
@ -0,0 +1,44 @@
|
||||
image: Visual Studio 2017
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- TARGET_ARCH: x64
|
||||
CONDA_INSTALL_LOCN: C:\\Miniconda-x64
|
||||
MSYS2_INSTALL_LOCN: C:\msys64
|
||||
MSYS2_BIN_LOCN: C:\msys64\usr\bin
|
||||
CMAKE_GENERATOR: "Visual Studio 15 Win64"
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
branches:
|
||||
except:
|
||||
- /.*[.]dmh/
|
||||
- /.*[.]wif/
|
||||
|
||||
# Do not build feature branch with open Pull Requests
|
||||
skip_branch_with_pr: true
|
||||
|
||||
install:
|
||||
- cmd: set SRC_DIR=%cd%
|
||||
- cmd: set INSTALL_LOC=%SRC_DIR%\install
|
||||
- cmd: set PATH=%PATH%;%MSYS2_BIN_LOCN%;%INSTALL_LOC%\bin;%INSTALL_LOC%\lib
|
||||
- cmd: call %CONDA_INSTALL_LOCN%\Scripts\activate.bat
|
||||
- cmd: conda config --set always_yes yes --set changeps1 no --set show_channel_urls true
|
||||
- cmd: conda update conda
|
||||
- cmd: conda install hdf5=1.8.18 curl hdf4
|
||||
|
||||
configuration: Release
|
||||
|
||||
build: off
|
||||
|
||||
# Run a custom script.
|
||||
build_script:
|
||||
- cmd: mkdir build
|
||||
- cmd: cd build
|
||||
- cmd: cmake .. -G "%CMAKE_GENERATOR%" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%INSTALL_LOC% -DENABLE_BASH_SCRIPT_TESTING=OFF -DENABLE_TESTS=OFF
|
||||
- cmd: if errorlevel 1 exit 1
|
||||
- cmd: cmake --build . --config Release -- /maxcpucount:4
|
||||
|
||||
test_script:
|
||||
- cmd: cmake --build . --config Release --target install -- /maxcpucount:4
|
6
cf
6
cf
@ -106,20 +106,18 @@ FLAGS="$FLAGS --enable-extreme-numbers"
|
||||
#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 --enable-internal-docs"
|
||||
#FLAGS="$FLAGS --enable-doxygen --enable-internal-docs"
|
||||
FLAGS="$FLAGS --enable-logging"
|
||||
#FLAGS="$FLAGS --disable-diskless"
|
||||
#FLAGS="$FLAGS --enable-mmap"
|
||||
#FLAGS="$FLAGS --with-udunits"
|
||||
#FLAGS="$FLAGS --with-libcf"
|
||||
#valgrind => not shared
|
||||
#FLAGS="$FLAGS --enable-valgrind-tests"
|
||||
#FLAGS="$FLAGS --enable-jna"
|
||||
#FLAGS="$FLAGS --disable-properties-attribute"
|
||||
#FLAGS="$FLAGS --disable-silent-rules"
|
||||
#FLAGS="$FLAGS --with-testservers=remotestserver.localhost:8083"
|
||||
#FLAGS="$FLAGS --disable-filter-testing"
|
||||
#FLAGS="$FLAGS --enable-metadata-perf"
|
||||
FLAGS="$FLAGS --enable-metadata-perf"
|
||||
|
||||
if test "x$PAR4" != x1 ; then
|
||||
FLAGS="$FLAGS --disable-parallel4"
|
||||
|
32
cf.cmake
32
cf.cmake
@ -36,19 +36,32 @@ FLAGS="-DCMAKE_PREFIX_PATH=c:/tools/nccmake"
|
||||
fi
|
||||
FLAGS="$FLAGS -DCMAKE_INSTALL_PREFIX=/tmp/netcdf"
|
||||
|
||||
if test "x$DAP" = x ; then FLAGS="$FLAGS -DENABLE_DAP=false"; fi
|
||||
if test "x$NC4" = x ; then FLAGS="$FLAGS -DENABLE_NETCDF_4=false"; fi
|
||||
if test "x$CDF5" != x ; then FLAGS="$FLAGS -DENABLE_CDF5=true"; fi
|
||||
if test "x$HDF4" != x ; then FLAGS="$FLAGS -DENABLE_HDF4=true"; fi
|
||||
FLAGS="$FLAGS -DENABLE_CONVERSION_WARNINGS=false"
|
||||
if test "x$DAP" = x ; then
|
||||
FLAGS="$FLAGS -DENABLE_DAP=false"
|
||||
fi
|
||||
if test "x$NC4" = x ; then
|
||||
FLAGS="$FLAGS -DENABLE_NETCDF_4=false"
|
||||
fi
|
||||
if test "x$CDF5" != x ; then
|
||||
FLAGS="$FLAGS -DENABLE_CDF5=true"
|
||||
fi
|
||||
if test "x$HDF4" != x ; then
|
||||
FLAGS="$FLAGS -DENABLE_HDF4=true"
|
||||
fi
|
||||
|
||||
# Enables
|
||||
FLAGS="$FLAGS -DENABLE_DAP_REMOTE_TESTS=true"
|
||||
FLAGS="$FLAGS -DENABLE_TESTS=true"
|
||||
FLAGS="$FLAGS -DENABLE_EXAMPLES=false"
|
||||
FLAGS="$FLAGS -DENABLE_DYNAMIC_LOADING=false"
|
||||
FLAGS="$FLAGS -DENABLE_WINSOCK2=false"
|
||||
FLAGS="$FLAGS -DENABLE_LOGGING=true"
|
||||
#FLAGS="$FLAGS -DENABLE_DOXYGEN=true -DENABLE_INTERNAL_DOCS=true"
|
||||
#FLAGS="$FLAGS -DENABLE_LARGE_FILE_TESTS=true"
|
||||
FLAGS="$FLAGS -DENABLE_FILTER_TESTING=true"
|
||||
|
||||
# Disables
|
||||
FLAGS="$FLAGS -DENABLE_EXAMPLES=false"
|
||||
FLAGS="$FLAGS -DENABLE_CONVERSION_WARNINGS=false"
|
||||
#FLAGS="$FLAGS -DENABLE_TESTS=false"
|
||||
#FLAGS="$FLAGS -DENABLE_DISKLESS=false"
|
||||
|
||||
rm -fr build
|
||||
mkdir build
|
||||
cd build
|
||||
@ -56,6 +69,7 @@ cd build
|
||||
NCLIB=`pwd`
|
||||
|
||||
if test "x$VS" != x ; then
|
||||
|
||||
# Visual Studio
|
||||
CFG="Release"
|
||||
NCLIB="${NCLIB}/liblib"
|
||||
|
22
conda.recipe/bld.bat
Normal file
22
conda.recipe/bld.bat
Normal file
@ -0,0 +1,22 @@
|
||||
set PATH=%PATH%;C:\msys64\usr\bin
|
||||
|
||||
mkdir %SRC_DIR%\build
|
||||
cd %SRC_DIR%\build
|
||||
|
||||
cmake -G "Visual Studio 15 Win64" ^
|
||||
-D CMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% ^
|
||||
-D BUILD_SHARED_LIBS=ON ^
|
||||
-D ENABLE_TESTS=ON ^
|
||||
-D ENABLE_HDF4=ON ^
|
||||
-D CMAKE_PREFIX_PATH=%LIBRARY_PREFIX% ^
|
||||
-D ZLIB_LIBRARY=%LIBRARY_LIB%\zlib.lib ^
|
||||
-D ZLIB_INCLUDE_DIR=%LIBRARY_INC% ^
|
||||
-D CMAKE_BUILD_TYPE=Release ^
|
||||
%SRC_DIR%
|
||||
if errorlevel 1 exit 1
|
||||
|
||||
cmake --build . --config Release || exit 1
|
||||
|
||||
ctest || exit 1
|
||||
|
||||
nmake install || exit 1
|
33
conda.recipe/meta.yaml
Normal file
33
conda.recipe/meta.yaml
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
{% set version = "dev" %}
|
||||
|
||||
package:
|
||||
name: netcdf-c
|
||||
version: {{ version }}
|
||||
|
||||
source:
|
||||
path: ../
|
||||
|
||||
build:
|
||||
features:
|
||||
- vc9 # [win and py27]
|
||||
- vc14 # [win and py>=35]
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- python # Here only to activate the `vc`s.
|
||||
- msinttypes
|
||||
- curl
|
||||
- zlib 1.2.*
|
||||
- hdf4
|
||||
- hdf5 1.8.20
|
||||
- vc 15 # [win and py>=35]
|
||||
run:
|
||||
- curl
|
||||
- zlib 1.2.*
|
||||
- hdf4
|
||||
- hdf5 1.8.20
|
||||
- vc 15 # [win and py>=35]
|
||||
|
||||
test:
|
||||
commands:
|
15
configure.ac
15
configure.ac
@ -180,6 +180,7 @@ AC_MSG_CHECKING([whether we should build netCDF-4])
|
||||
AC_ARG_ENABLE([netcdf-4], [AS_HELP_STRING([--disable-netcdf-4],
|
||||
[do not build with netcdf-4 (else HDF5 and zlib required)])])
|
||||
test "x$enable_netcdf_4" = xno || enable_netcdf_4=yes
|
||||
enable_hdf5=enable_netcdf_4
|
||||
|
||||
# Synonym
|
||||
AC_ARG_ENABLE([netcdf4], [AS_HELP_STRING([--disable-netcdf4],
|
||||
@ -371,7 +372,7 @@ fi
|
||||
AC_MSG_RESULT($enable_dap_auth_tests)
|
||||
|
||||
# Control if groups are supported in [netcdf4]dap2 code
|
||||
AC_MSG_CHECKING([whether [netcdf4] group names for DAP2 hould be enabled (default on)])
|
||||
AC_MSG_CHECKING([whether [netcdf4] group names for DAP2 should be enabled (default on)])
|
||||
AC_ARG_ENABLE([dap-groups],
|
||||
[AS_HELP_STRING([--disable-dap-groups],
|
||||
[disable [netcdf4] DAP2 group names])])
|
||||
@ -786,7 +787,7 @@ fi
|
||||
|
||||
# Setup the diskless and mmap conditionals
|
||||
if test "x$enable_diskless" = xyes ; then
|
||||
AC_DEFINE([USE_DISKLESS], [1], [if true, include NC_DISKLESS code])
|
||||
AC_DEFINE([USE_DISKLESS], [1], [if true, include NC_DISKLESS and NC_INMEMORY code])
|
||||
if test "x$enable_mmap" = xyes; then
|
||||
AC_DEFINE([USE_MMAP], [1], [if true, use mmap for in-memory files])
|
||||
fi
|
||||
@ -909,6 +910,7 @@ AC_CHECK_LIB([m], [floor], [],
|
||||
|
||||
if test "x$enable_netcdf_4" = xyes; then
|
||||
|
||||
AC_DEFINE([USE_HDF5], [1], [if true, use HDF5])
|
||||
AC_DEFINE([USE_NETCDF4], [1], [if true, build netCDF-4])
|
||||
AC_DEFINE([H5_USE_16_API], [1], [use HDF5 1.6 API])
|
||||
|
||||
@ -1202,6 +1204,7 @@ AM_CONDITIONAL(USE_PNETCDF_DIR, [test ! "x$PNETCDFDIR" = x])
|
||||
AM_CONDITIONAL(USE_LOGGING, [test "x$enable_logging" = xyes])
|
||||
AM_CONDITIONAL(CROSS_COMPILING, [test "x$cross_compiling" = xyes])
|
||||
AM_CONDITIONAL(USE_NETCDF4, [test x$enable_netcdf_4 = xyes])
|
||||
AM_CONDITIONAL(USE_HDF5, [test x$enable_hdf5 = xyes])
|
||||
AM_CONDITIONAL(USE_HDF4, [test x$enable_hdf4 = xyes])
|
||||
AM_CONDITIONAL(USE_HDF4_FILE_TESTS, [test x$enable_hdf4_file_tests = xyes])
|
||||
AM_CONDITIONAL(USE_RENAMEV3, [test x$enable_netcdf_4 = xyes -o x$enable_dap = xyes])
|
||||
@ -1335,6 +1338,7 @@ 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_HDF5,[$enable_hdf5])
|
||||
AC_SUBST(HAS_PNETCDF,[$enable_pnetcdf])
|
||||
AC_SUBST(HAS_HDF5,[$enable_netcdf_4])
|
||||
AC_SUBST(HAS_LOGGING, [$enable_logging])
|
||||
@ -1440,14 +1444,15 @@ AC_MSG_NOTICE([generating header files and makefiles])
|
||||
AC_CONFIG_FILES([Makefile
|
||||
nc-config
|
||||
netcdf.pc
|
||||
libnetcdf.settings
|
||||
postinstall.sh
|
||||
include/netcdf_meta.h
|
||||
libnetcdf.settings
|
||||
postinstall.sh
|
||||
include/netcdf_meta.h
|
||||
include/Makefile
|
||||
h5_test/Makefile
|
||||
hdf4_test/Makefile
|
||||
libsrc/Makefile
|
||||
libsrc4/Makefile
|
||||
libhdf5/Makefile
|
||||
libsrcp/Makefile
|
||||
ncdump/Makefile
|
||||
ncgen3/Makefile
|
||||
|
@ -74,6 +74,16 @@ 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 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)
|
||||
# Should match list in Makefile.am
|
||||
SET(CUR_EXTRA_DIST ${CUR_EXTRA_DIST}
|
||||
netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html
|
||||
mainpage.dox tutorial.dox guide.dox types.dox cdl.dox
|
||||
architecture.dox internal.dox windows-binaries.md
|
||||
building-with-cmake.md CMakeLists.txt groups.dox install.md notes.md
|
||||
install-fortran.md all-error-codes.md credits.md auth.md
|
||||
obsolete/fan_utils.html bestpractices.md filters.md indexing.md
|
||||
inmemory.md DAP4.dox OPeNDAP.dox attribute_conventions.md FAQ.md
|
||||
file_format_specifications.md known_problems.md
|
||||
COPYRIGHT.dox)
|
||||
|
||||
ADD_EXTRA_DIST("${CUR_EXTRA_DIST}")
|
||||
|
@ -1105,7 +1105,7 @@ HTML_STYLESHEET =
|
||||
# defined cascading style sheet that is included after the standard style sheets
|
||||
# created by doxygen. Using this option one can overrule certain style aspects.
|
||||
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
||||
# standard style sheet and is therefor more robust against future updates.
|
||||
# standard style sheet and is therefore more robust against future updates.
|
||||
# Doxygen will copy the style sheet file to the output directory. For an example
|
||||
# see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
@ -757,7 +757,9 @@ INPUT = \
|
||||
@abs_top_srcdir@/docs/DAP4.dox \
|
||||
@abs_top_srcdir@/docs/attribute_conventions.md \
|
||||
@abs_top_srcdir@/docs/file_format_specifications.md \
|
||||
@abs_top_srcdir@/docs/tutorial.dox \
|
||||
@abs_top_srcdir@/docs/auth.md \
|
||||
@abs_top_srcdir@/docs/filters.md \
|
||||
@abs_top_srcdir@/docs/inmemory.md \
|
||||
@abs_top_srcdir@/docs/notes.md \
|
||||
@abs_top_srcdir@/docs/auth.md \
|
||||
@abs_top_srcdir@/docs/filters.md \
|
||||
@ -767,6 +769,7 @@ INPUT = \
|
||||
@abs_top_srcdir@/docs/COPYRIGHT.dox \
|
||||
@abs_top_srcdir@/docs/credits.md \
|
||||
@abs_top_srcdir@/docs/bestpractices.md \
|
||||
@abs_top_srcdir@/docs/tutorial.dox \
|
||||
@abs_top_srcdir@/include/netcdf.h \
|
||||
@abs_top_srcdir@/include/netcdf_mem.h \
|
||||
@abs_top_srcdir@/include/netcdf_par.h \
|
||||
@ -1049,7 +1052,7 @@ USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
|
||||
# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the
|
||||
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
|
||||
# cost of reduced performance. This can be particularly helpful with template
|
||||
# rich C++ code for which doxygen's built-in parser lacks the necessary type
|
||||
# information.
|
||||
@ -1163,7 +1166,7 @@ HTML_STYLESHEET =
|
||||
# defined cascading style sheet that is included after the standard style sheets
|
||||
# created by doxygen. Using this option one can overrule certain style aspects.
|
||||
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
||||
# standard style sheet and is therefor more robust against future updates.
|
||||
# standard style sheet and is therefore more robust against future updates.
|
||||
# Doxygen will copy the style sheet file to the output directory. For an example
|
||||
# see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
@ -9,7 +9,10 @@ mainpage.dox tutorial.dox guide.dox types.dox cdl.dox \
|
||||
architecture.dox internal.dox windows-binaries.md \
|
||||
building-with-cmake.md CMakeLists.txt groups.dox install.md notes.md \
|
||||
install-fortran.md all-error-codes.md credits.md auth.md \
|
||||
obsolete/fan_utils.html bestpractices.md filters.md indexing.dox
|
||||
obsolete/fan_utils.html bestpractices.md filters.md indexing.dox \
|
||||
inmemory.md DAP4.dox OPeNDAP.dox attribute_conventions.md FAQ.md \
|
||||
file_format_specifications.md known_problems.md \
|
||||
COPYRIGHT.dox
|
||||
|
||||
# Turn off parallel builds in this directory.
|
||||
.NOTPARALLEL:
|
||||
|
@ -675,7 +675,7 @@ follows.
|
||||
Related CURL Flags: CURLOPT_KEYPASSWORD
|
||||
HTTP.SSL.CAPATH
|
||||
Type: String representing directory
|
||||
Description: Path to a directory containing trusted certificates for validating server sertificates.
|
||||
Description: Path to a directory containing trusted certificates for validating server certificates.
|
||||
Related CURL Flags: CURLOPT_CAPATH
|
||||
HTTP.SSL.VALIDATE
|
||||
Type: boolean ("1"/"0")
|
||||
|
@ -165,7 +165,7 @@ specifies the password for accessing the HTTP.SSL.CERTIFICAT/HTTP.SSL.key file.
|
||||
<p>
|
||||
HTTP.SSL.CAPATH
|
||||
specifies the path to a directory containing
|
||||
trusted certificates for validating server sertificates.
|
||||
trusted certificates for validating server certificates.
|
||||
<p>
|
||||
HTTP.SSL.VALIDATE
|
||||
is a boolean (1/0) value that if true (1)
|
||||
|
@ -188,7 +188,7 @@ specifies the password for accessing the HTTP.SSL.CERTIFICAT/HTTP.SSL.key file.
|
||||
|
||||
HTTP.SSL.CAPATH
|
||||
specifies the path to a directory containing
|
||||
trusted certificates for validating server sertificates.
|
||||
trusted certificates for validating server certificates.
|
||||
See reference #2 for more info.
|
||||
|
||||
HTTP.SSL.VALIDATE
|
||||
@ -512,9 +512,10 @@ what you changed to the author so this document can be updated.
|
||||
done
|
||||
exit
|
||||
|
||||
## Provenance
|
||||
## Point of Contact
|
||||
|
||||
__Author__: Dennis Heimbigner<br>
|
||||
__Email__: dmh at ucar dot edu
|
||||
__Initial Version__: 11/21/2014<br>
|
||||
__Last Revised__: 08/24/2017
|
||||
|
||||
|
@ -44,7 +44,7 @@ double slash characters '//' on any line.
|
||||
A CDL description for a classic model file consists of three optional
|
||||
parts: dimensions, variables, and data. The variable part may contain
|
||||
variable declarations and attribute assignments. For the enhanced
|
||||
model supported by netCDF-4, a CDL decription may also includes
|
||||
model supported by netCDF-4, a CDL description may also include
|
||||
groups, subgroups, and user-defined types.
|
||||
|
||||
A dimension is used to define the shape of one or more of the
|
||||
@ -160,8 +160,8 @@ NetCDF-4 supports the additional primitive types:
|
||||
- ubyte Unsigned eight-bit integers.
|
||||
- ushort Unsigned 16-bit integers.
|
||||
- uint Unsigned 32-bit integers.
|
||||
- int64 64-bit singed integers.
|
||||
- uint64 Unsigned 64-bit singed integers.
|
||||
- int64 64-bit signed integers.
|
||||
- uint64 Unsigned 64-bit signed integers.
|
||||
- string Variable-length string of characters
|
||||
|
||||
Except for the added data-type byte, CDL supports the same primitive
|
||||
|
@ -445,7 +445,7 @@ document. For more information about HDF5, see the HDF5 web site:
|
||||
http://hdf.ncsa.uiuc.edu/HDF5/.
|
||||
|
||||
The specification that follows is sufficient to allow HDF5 users to
|
||||
create files that will be accessable from netCDF-4.
|
||||
create files that will be accessible from netCDF-4.
|
||||
|
||||
\subsection creation_order Creation Order
|
||||
|
||||
@ -735,7 +735,7 @@ Starting with version 4.1, the netCDF libraries can read HDF4 SD
|
||||
created with the Scientific Dataset API. Access is read-only.
|
||||
|
||||
Dataset types are translated between HDF4 and netCDF in a
|
||||
straighforward manner.
|
||||
straightforward manner.
|
||||
- DFNT_CHAR = NC_CHAR
|
||||
- DFNT_UCHAR, DFNT_UINT8 = NC_UBYTE
|
||||
- DFNT_INT8 = NC_BYTE
|
||||
|
@ -1,8 +1,8 @@
|
||||
Filter Support in netCDF-4 (Enhanced)
|
||||
NetCDF-4 Filter Support
|
||||
============================
|
||||
<!-- double header is needed to workaround doxygen bug -->
|
||||
|
||||
Filter Support in netCDF-4 (Enhanced) {#compress}
|
||||
NetCDF-4 Filter Support {#compress}
|
||||
=================================
|
||||
|
||||
[TOC]
|
||||
@ -84,7 +84,7 @@ 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 filter id will 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
|
||||
@ -434,8 +434,15 @@ Test for Machine Endianness
|
||||
static const unsigned char b[4] = {0x0,0x0,0x0,0x1}; /* value 1 in big-endian*/
|
||||
int endianness = (1 == *(unsigned int*)b); /* 1=>big 0=>little endian
|
||||
````
|
||||
References {#References}
|
||||
========================
|
||||
|
||||
Provenance
|
||||
1. https://support.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters/HDF5DynamicallyLoadedFilters.pdf
|
||||
2. https://support.hdfgroup.org/HDF5/doc/TechNotes/TechNote-HDF5-CompressionTroubleshooting.pdf
|
||||
3. https://portal.hdfgroup.org/display/support/Contributions#Contributions-filters
|
||||
4. https://support.hdfgroup.org/services/contributions.html#filters
|
||||
|
||||
Point of Contact
|
||||
================
|
||||
|
||||
__Author__: Dennis Heimbigner<br>
|
||||
@ -443,10 +450,3 @@ __Email__: dmh at ucar dot edu
|
||||
__Initial Version__: 1/10/2018<br>
|
||||
__Last Revised__: 2/5/2018
|
||||
|
||||
References {#References}
|
||||
==========
|
||||
|
||||
1. https://support.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters/HDF5DynamicallyLoadedFilters.pdf
|
||||
2. https://support.hdfgroup.org/HDF5/doc/TechNotes/TechNote-HDF5-CompressionTroubleshooting.pdf
|
||||
3. https://portal.hdfgroup.org/display/support/Contributions#Contributions-filters
|
||||
4. https://support.hdfgroup.org/services/contributions.html#filters
|
||||
|
@ -671,7 +671,7 @@ The extended CDL syntax for the enhanced data model supported by
|
||||
netCDF-4 allows optional type specifications, including user-defined
|
||||
types, for attributes of user-defined types. See ncdump output or the
|
||||
reference documentation for ncgen for details of the extended CDL
|
||||
systax.
|
||||
syntax.
|
||||
|
||||
In the netCDF example (see \ref data_model), units is an attribute for
|
||||
the variable lat that has a 13-character array value
|
||||
@ -996,7 +996,7 @@ through the netCDF C or Fortran interfaces, support for parallel I/O
|
||||
on netCDF classic and 64-bit offset files using the parallel-netcdf
|
||||
(formerly pnetcdf) library from Argonne/Northwestern, a new nc-config
|
||||
utility to help compile and link programs that use netCDF, inclusion
|
||||
of the UDUNITS library for hadling “units” attributes, and inclusion
|
||||
of the UDUNITS library for handling “units” attributes, and inclusion
|
||||
of libcf to assist in creating data compliant with the Climate and
|
||||
Forecast (CF) metadata conventions.
|
||||
|
||||
@ -1796,7 +1796,7 @@ double slash characters '//' on any line.
|
||||
A CDL description for a classic model file consists of three optional
|
||||
parts: dimensions, variables, and data. The variable part may contain
|
||||
variable declarations and attribute assignments. For the enhanced
|
||||
model supported by netCDF-4, a CDL decription may also includes
|
||||
model supported by netCDF-4, a CDL description may also include
|
||||
groups, subgroups, and user-defined types.
|
||||
|
||||
A dimension is used to define the shape of one or more of the
|
||||
@ -1912,8 +1912,8 @@ NetCDF-4 supports the additional primitive types:
|
||||
- ubyte - Unsigned eight-bit integers.
|
||||
- ushort - Unsigned 16-bit integers.
|
||||
- uint - Unsigned 32-bit integers.
|
||||
- int64 - 64-bit singed integers.
|
||||
- uint64 - Unsigned 64-bit singed integers.
|
||||
- int64 - 64-bit signed integers.
|
||||
- uint64 - Unsigned 64-bit signed integers.
|
||||
- string - Variable-length string of characters
|
||||
|
||||
Except for the added numeric data-types byte and ubyte, CDL supports
|
||||
|
215
docs/inmemory.md
Normal file
215
docs/inmemory.md
Normal file
@ -0,0 +1,215 @@
|
||||
NetCDF In-Memory Support
|
||||
====================================
|
||||
|
||||
<!-- double header is needed to workaround doxygen bug -->
|
||||
|
||||
NetCDF In-Memory Support {#inmemory}
|
||||
====================================
|
||||
|
||||
[TOC]
|
||||
|
||||
Introduction {#inmemory_intro}
|
||||
--------------
|
||||
|
||||
It can be convenient to operate on a netcdf file whose
|
||||
content is held in memory instead of in a disk file.
|
||||
The netcdf API has been modified in a number of ways
|
||||
to support this capability.
|
||||
|
||||
Actually, three distinct but related capabilities are provided.
|
||||
|
||||
1. DISKLESS -- Read a file into memory, operate on it, and optionally
|
||||
write it back out to disk when nc_close() is called.
|
||||
2. INMEMORY -- Tell the netcdf-c library to treat a provided block
|
||||
of memory as if it were a netcdf file. At close, it is possible to ask
|
||||
for the final contents of the memory chunk. Be warned that there is
|
||||
some complexity to this as described below.
|
||||
4. MMAP -- Tell the netcdf-c library to use the *mmap()* operating
|
||||
system functionality to access a file.
|
||||
|
||||
The first two capabilities are intertwined in the sense that the *diskless*
|
||||
capability makes use internally of the *inmemory* capability. But, the
|
||||
*inmemory* capability can be used independently of the *diskless* capability.
|
||||
|
||||
The *mmap()* capability provides a capability similar to *diskless* but
|
||||
using special capabilities of the underlying operating system.
|
||||
|
||||
Note also that *diskless* and *inmemory* can be used for both
|
||||
*netcdf-3* (classic) and *netcdf-4* (enhanced) data. The *mmap*
|
||||
capability can only be used with *netcdf-3*.
|
||||
|
||||
Enabling Diskless File Access {#Enable_Diskless}
|
||||
--------------
|
||||
The *diskless* capability can be used relatively transparently
|
||||
using the *NC_DISKLESS* mode flag.
|
||||
|
||||
Note that since the file is stored in memory, size limitations apply.
|
||||
If you are on using a 32-bit pointer then the file size must be less than 2^32
|
||||
bytes in length. On a 64-bit machine, the size must be less than 2^64 bytes.
|
||||
|
||||
### Diskless File Open
|
||||
Calling *nc_open()* using the mode flag *NC_DISKLESS* will cause
|
||||
the file being opened to be read into memory. When calling *nc_close()*,
|
||||
the file will optionally be re-written (aka "persisted") to disk. This
|
||||
persist capability will be invoked if and only if *NC_WRITE* is specified
|
||||
in the mode flags at the call to *nc_open()*.
|
||||
|
||||
### Diskless File Create
|
||||
Calling *nc_create()* using the mode flag *NC_DISKLESS* will cause
|
||||
the file to initially be created and kept in memory.
|
||||
When calling *nc_close()*, the file will be written
|
||||
to disk.
|
||||
Note that if it is desired to create the file in memory,
|
||||
but not write to a disk file, then one can either set
|
||||
the NC_NOCLOBBER mode flag or one can call *nc_abort()*
|
||||
instead of *nc_close()*.
|
||||
|
||||
Enabling Inmemory File Access {#Enable_Inmemory}
|
||||
--------------
|
||||
|
||||
The netcdf API has been extended to support the inmemory capability.
|
||||
The relevant API is defined in the file `netcdf_mem.h`.
|
||||
|
||||
The important data structure to use is `NC_memio`.
|
||||
````
|
||||
typedef struct NC_memio {
|
||||
size_t size;
|
||||
void* memory;
|
||||
int flags;
|
||||
} NC_memio;
|
||||
|
||||
````
|
||||
An instance of this data structure is used when providing or
|
||||
retrieving a block of data. It specifies the memory and its size
|
||||
and also some relevant flags that define how to manage the memory.
|
||||
|
||||
Current only one flag is defined -- *NC_MEMIO_LOCKED*.
|
||||
This tells the netcdf library that it should never try to
|
||||
*realloc()* the memory nor to *free()* the memory. Note
|
||||
that this does not mean that the memory cannot be modified, but
|
||||
only that the modifications will be within the confines of the provided
|
||||
memory. If doing such modifications is impossible without
|
||||
reallocating the memory, then the modification will fail.
|
||||
|
||||
### In-Memory API
|
||||
|
||||
The new API consists of the following functions.
|
||||
````
|
||||
int nc_open_mem(const char* path, int mode, size_t size, void* memory, int* ncidp);
|
||||
|
||||
int nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp);
|
||||
|
||||
int nc_open_memio(const char* path, int mode, NC_memio* info, int* ncidp);
|
||||
|
||||
int nc_close_memio(int ncid, NC_memio* info);
|
||||
|
||||
````
|
||||
### The **nc_open_mem** Function
|
||||
|
||||
The *nc_open_mem()* function is actually a convenience
|
||||
function that internally invokes *nc_open_memio()*.
|
||||
It essentially provides simple read-only access to a chunk of memory
|
||||
of some specified size.
|
||||
|
||||
### The **nc_open_memio** Function
|
||||
|
||||
This function provides a more general read/write capability with respect
|
||||
to a chunk of memory. It has a number of constraints and its
|
||||
semantics are somewhat complex. This is primarily due to limitations
|
||||
imposed by the underlying HDF5 library.
|
||||
|
||||
The constraints are as follows.
|
||||
|
||||
1. If the *NC_MEMIO_LOCKED* flag is set, then the netcdf library will
|
||||
make no attempt to reallocate or free the provided memory.
|
||||
If the caller invokes the *nc_close_memio()* function to retrieve the
|
||||
final memory block, it should be the same
|
||||
memory block as was provided when *nc_open_memio* was called.
|
||||
Note that it is still possible to modify the in-memory file if the NC_WRITE
|
||||
mode flag was set. However, failures can occur if an operation
|
||||
cannot complete because the memory needs to be expanded.
|
||||
2. If the *NC_MEMIO_LOCKED* flag is <b>not</b> set, then
|
||||
the netcdf library will take control of the incoming memory
|
||||
and will feel free to reallocate the provided
|
||||
memory block to obtain a larger block when an attempt to modify
|
||||
the in-memory file requires more space. Note that implicit in this
|
||||
is that the old block -- the one originally provided -- may be
|
||||
free'd as a side effect of re-allocating the memory using the
|
||||
*realloc()* function.
|
||||
If the caller invokes the *nc_close_memio()* function to retrieve the
|
||||
final memory block, the returned block must always be freed
|
||||
by the caller and that the original block should not be freed.
|
||||
|
||||
### The **nc_create_mem** Function
|
||||
|
||||
This function allows a user to create an in-memory file, write to it,
|
||||
and then retrieve the final memory using *nc_close_memio()*.
|
||||
The *initialsize* argument to *nc_create_mem()* tells the library
|
||||
how much initial memory to allocate. Technically, this is advisory only
|
||||
because it may be ignored by the underlying HDF5 library.
|
||||
It is used, however, for netcdf-3 files.
|
||||
|
||||
### The **nc_close_memio** Function
|
||||
|
||||
The ordinary *nc_close()* function can be called to close an in-memory file.
|
||||
However, it is often desirable to obtain the final size and memory block
|
||||
for the in-memory file when that file has been modified.
|
||||
The *nc_close_memio()* function provides a means to do this.
|
||||
Its second argument is a pointer to an *NC_memio* object
|
||||
into which the final memory and size are stored. WARNING,
|
||||
the returned memory is owned by the caller and so the caller
|
||||
is responsible for calling *free()* on that returned memory.
|
||||
|
||||
### Support for Writing with *NC_MEMIO_LOCKED*
|
||||
|
||||
When the NC_MEMIO_LOCKED flag is set in the *NC_memio* object
|
||||
passed to *nc_open_memio()*, it is still possible to modify
|
||||
the opened in-memory file (using the NC_WRITE mode flag).
|
||||
|
||||
The big problem is that any changes must fit into the memory provided
|
||||
by the caller via the *NC_memio* object. This problem can be
|
||||
mitigated, however, by using the "trick" of overallocating
|
||||
the caller supplied memory. That is, if the original file is, say, 300 bytes,
|
||||
then it is possible to allocate, say, 65000 bytes and copy the original file
|
||||
into the first 300 bytes of the larger memory block. This will allow
|
||||
the netcdf-c library to add to the file up to that 65000 byte limit.
|
||||
In this way, it is possible to avoid memory reallocation while still
|
||||
allowing modifications to the file. You will still need to call
|
||||
*nc_close_memio()* to obtain the size of the final, modified, file.
|
||||
|
||||
Enabling MMAP File Access {#Enable_MMAP}
|
||||
--------------
|
||||
|
||||
Some operating systems provide a capability called MMAP.
|
||||
This allows disk files to automatically be mapped to chunks of memory.
|
||||
It operates in a fashion somewhat similar to operating system virtual
|
||||
memory, except with respect to a file.
|
||||
|
||||
By setting mode flag NC_MMAP, it is possible to do the equivalent
|
||||
of NC_DISKLESS but using the operating system's mmap capabilities.
|
||||
|
||||
Currently, MMAP support is only available when using netcdf-3 or cdf5
|
||||
files.
|
||||
|
||||
Known Bugs {#Inmemory_Bugs}
|
||||
--------------
|
||||
|
||||
1. If you are modifying a locked memory chunk (using
|
||||
NC_MEMIO_LOCKED) and are accessing it as a netcdf-4 file, and
|
||||
you overrun the available space, then the HDF5 library will
|
||||
fail with a segmentation fault.
|
||||
|
||||
References {#Inmemory_References}
|
||||
--------------
|
||||
|
||||
1. https://support.hdfgroup.org/HDF5/doc1.8/Advanced/FileImageOperations/HDF5FileImageOperations.pdf
|
||||
|
||||
Point of Contact
|
||||
--------------
|
||||
|
||||
__Author__: Dennis Heimbigner<br>
|
||||
__Email__: dmh at ucar dot edu
|
||||
__Initial Version__: 2/3/2018<br>
|
||||
__Last Revised__: 2/5/2018
|
||||
|
||||
|
@ -79,6 +79,8 @@ Requirements {#netcdf_requirements}
|
||||
* zlib 1.2.5 or later (for netCDF-4 compression)
|
||||
* curl 7.18.0 or later (for DAP remote access client support)
|
||||
|
||||
> **Important Note**: When building netCDF-C library versions older than 4.4.1, use only HDF5 1.8.x versions. Combining older netCDF-C versions with newer HDF5 1.10 versions will create superblock 3 files that are not readable by lots of older software. See <a href="http://www.unidata.ucar.edu/blogs/news/entry/netcdf-4-4-1">this announcement</a> for more details.
|
||||
|
||||
|
||||
CMake and Windows support {#sub}
|
||||
--------------------------------
|
||||
@ -102,9 +104,9 @@ the HDF5 library is built with szip support. The netcdf build will then
|
||||
inherit szip support from the HDF5 library.
|
||||
If you intend to write files with szip compression, then we suggest that you
|
||||
use [libaec](https://gitlab.dkrz.de/k202009/libaec.git)
|
||||
to avoid patent problems. That library can be used as a
|
||||
to avoid patent problems. That library can be used as a
|
||||
drop-in replacement for the standard szip library.
|
||||
If you plan to use the standard szip library,
|
||||
If you plan to use the standard szip library,
|
||||
then determine whether license restrictions on the use of szip apply to your situation. See the <a href="http://www.hdfgroup.org/doc_resource/SZIP/">web page on szip compression in HDF products</a>.
|
||||
|
||||
If `make check` fails for either `zlib` or `HDF5`, the problem must be resolved before the netCDF-4 installation can continue. For HDF5 problems, see the <a href="http://www.hdfgroup.org/services/support.html">HDF5 help services</a>.
|
||||
@ -475,4 +477,3 @@ or
|
||||
## See Also {#cmake_see_also}
|
||||
|
||||
For further information regarding netCDF and CMake, see \ref cmake_faq.
|
||||
|
||||
|
@ -1316,7 +1316,7 @@ $ nc2text -f '%0.1f' vec.nc v
|
||||
</strong>
|
||||
</pre>
|
||||
<p>The first value (<tt><b>-999</b></tt>) is treated as missing because (even
|
||||
after conversion to Celsius) it is less than the valid mininum of <tt><b>-273.2</b></tt>.
|
||||
after conversion to Celsius) it is less than the valid minimum of <tt><b>-273.2</b></tt>.
|
||||
The second value (32<33>F) is converted to 0<>C. The third value (<tt><b>1e9</b></tt>)
|
||||
is treated as missing because it matches the input missing value specified by
|
||||
<tt><b>-m 1e9</b></tt>.</p>
|
||||
|
@ -3034,7 +3034,7 @@ This example is from libsrc4/tst_vars.c.
|
||||
|
||||
...
|
||||
|
||||
/* Open the file and make sure nc_inq_varids yeilds correct
|
||||
/* Open the file and make sure nc_inq_varids yields correct
|
||||
* result. */
|
||||
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
|
||||
@ -3108,7 +3108,7 @@ This example is from libsrc4/tst_dims.c.
|
||||
|
||||
...
|
||||
|
||||
/* Open the file and make sure nc_inq_dimids yeilds correct
|
||||
/* Open the file and make sure nc_inq_dimids yields correct
|
||||
* result. */
|
||||
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
|
||||
@ -11764,7 +11764,7 @@ programmers.
|
||||
|
||||
Fortran compilers do not always agree as to how data should be laid
|
||||
out in memory. This makes handling compound and variable length array
|
||||
types compiler and platform dependant.
|
||||
types compiler and platform dependent.
|
||||
|
||||
(This is also true for C, but the clever HDF5 configuration has solved
|
||||
this problem for C. Alas, not for Fortran.)
|
||||
|
@ -918,7 +918,7 @@ used with NF_NETCDF4, this flag ensures that the resulting
|
||||
netCDF-4/HDF5 file may never contain any new constructs from the
|
||||
enhanced data model. That is, it cannot contain groups, user defined
|
||||
types, multiple unlimited dimensions, or new atomic types. The
|
||||
advantage of this restriction is that such files are guarenteed to
|
||||
advantage of this restriction is that such files are guaranteed to
|
||||
work with existing netCDF software.
|
||||
|
||||
A zero value (defined for convenience as NF_CLOBBER) specifies the
|
||||
|
@ -1728,7 +1728,7 @@ after all.
|
||||
Why not take the easy way out if you can?
|
||||
|
||||
Many Linux systems contain package management programs which allow
|
||||
netCDF to be installed easily. This is the prefered installation
|
||||
netCDF to be installed easily. This is the preferred installation
|
||||
method for netCDF.
|
||||
|
||||
Precompiled binaries for some platforms can be found at
|
||||
|
@ -95,6 +95,9 @@
|
||||
<li>
|
||||
<a href="#Gfdnavi" >Gfdnavi (Geophysical fluid data navigator)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#gliderscope" >Gliderscope</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#GMT">GMT (Generic Mapping Tools)</a>
|
||||
</li>
|
||||
@ -200,6 +203,9 @@
|
||||
<li>
|
||||
<a href="#ncvtk" >ncvtk</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#netcdf_ninja" >NetCDF Ninja</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#netcdf_tools" >netcdf tools</a>
|
||||
</li>
|
||||
@ -575,7 +581,7 @@
|
||||
Mathematical functions (sqrt, exp, log, sin, cos, ...)
|
||||
</li>
|
||||
<li>
|
||||
Comparision (eq, ne, le, lt, ge, gt, ...)
|
||||
Comparison (eq, ne, le, lt, ge, gt, ...)
|
||||
</li>
|
||||
<li>
|
||||
Conditions (ifthen, ifnotthen, ifthenc, ifnotthenc)
|
||||
@ -927,6 +933,36 @@ or using ECMWF reanalysis on a reduced grid
|
||||
</p>
|
||||
<p></p>
|
||||
|
||||
<h2><a id="gliderscope" name="gliderscope">Gliderccope</a></h2>
|
||||
<p>
|
||||
Dr L. Mun Woo <mun.woo@uwa.edu.au>
|
||||
at ANFOG (Australian National Facility for Ocean Gliders)
|
||||
has developed
|
||||
<a href="http://imos.org.au/facilities/oceangliders/glider-data/gliderscope/">Gliderscope</a>.
|
||||
Gliderscope is an IMOS (Integrated Marine Observing System)
|
||||
oceanographic software package allow users quick easy visualisation
|
||||
of ocean glider data, via a convenient graphical user interface.
|
||||
Originally developed for use with ANFOG NetCDF data, it has now
|
||||
been expanded to handle NetCDF data files from IOOS (U.S.
|
||||
Integrated Ocean Observing System) and EGO (Everyone's Gliding
|
||||
Observatories) also.
|
||||
</p><p>
|
||||
Being interactive, Gliderscope speaks to users via an onscreen dialogue
|
||||
box, helping the user decide what to do. With a few simple clicks of
|
||||
the mouse, users can choose and extract segments of data, filter out the
|
||||
bad data, perform calculations (e.g. for water density, sound velocity
|
||||
in water, light attenuation, 1% photic depth) and apply a variety of
|
||||
high level graphical data visualisation techniques to produce elegant
|
||||
three/four-dimensional plots of water properties, interpolated contour
|
||||
charts, vertical profile plots, water properties comparison charts
|
||||
etc. Additionally, users can also export their data to text or NetCDF
|
||||
files for easy access in other applications. Gliderscope is available
|
||||
on Windows and Macintosh platforms, as standalone executable software
|
||||
as well as an App for use within Matlab.
|
||||
</p>
|
||||
|
||||
<p></p>
|
||||
|
||||
<h2><a id="GMT" name="GMT">GMT</a></h2>
|
||||
<p>
|
||||
<a href="http://gmt.soest.hawaii.edu/">GMT</a> (Generic Mapping Tools) is
|
||||
@ -1730,7 +1766,7 @@ or using ECMWF reanalysis on a reduced grid
|
||||
<h2><a id="NCL" name="NCL">NCL</a></h2>
|
||||
<p>
|
||||
The <a href="http://www.ncl.ucar.edu/" >NCAR Command Language
|
||||
(NCL)</a> is an intepreted programming
|
||||
(NCL)</a> is an interpreted programming
|
||||
language for scientific data analysis and visualization developed and
|
||||
maintained in
|
||||
NCAR's <a href="http://www.cisl.ucar.edu/">Computational and Information Systems
|
||||
@ -1965,6 +2001,21 @@ or using ECMWF reanalysis on a reduced grid
|
||||
|
||||
<p></p>
|
||||
|
||||
<h2><a id="netcdf_ninja" name="netcdf_ninja">netCDF Ninja</a></h2>
|
||||
<p>
|
||||
Dr L. Mun Woo of University of Western Australia <mun.woo@uwa.edu.au>
|
||||
has developed
|
||||
<a href="http://imos.org.au/facilities/oceangliders/glider-data/netcdfninja/">NetCDF Ninja</a>,
|
||||
a graphical user interface that allows users to browse all
|
||||
the metadata contained in NetCDF files, scrutinise the data using an
|
||||
interactive graphical plot and even make small alterations or export
|
||||
the data in text format without having any knowledge of coding. NetCDF
|
||||
Ninja is available on Windows and Macintosh platforms, as standalone
|
||||
executable software as well as an App for use within Matlab.
|
||||
</p>
|
||||
|
||||
<p></p>
|
||||
|
||||
<h2><a id="netcdf_tools" name="netcdf_tools">Ivan Shmakov's netcdf tools</a></h2>
|
||||
|
||||
<p>
|
||||
@ -2276,7 +2327,7 @@ or using ECMWF reanalysis on a reduced grid
|
||||
</li>
|
||||
<li>
|
||||
Export animations as AVI or MOV video or as a collection of
|
||||
invididual frame images.
|
||||
individual frame images.
|
||||
</li>
|
||||
<li>
|
||||
Explore remote THREDDS and OpenDAP catalogs and open datasets served from them.
|
||||
@ -2728,7 +2779,7 @@ or using ECMWF reanalysis on a reduced grid
|
||||
Forecast (CF) conventions and ISO 19115 metadata.
|
||||
</p>
|
||||
<p>
|
||||
SIS is under developement as an Apache project. Release 0.3 is
|
||||
SIS is under development as an Apache project. Release 0.3 is
|
||||
currently available for download.
|
||||
</p>
|
||||
<p></p>
|
||||
@ -2998,10 +3049,23 @@ or using ECMWF reanalysis on a reduced grid
|
||||
<p></p>
|
||||
|
||||
<h2><a id="Agrimetsoft" name="Agrimetsoft">AgriMetSoft Netcdf-Extractor</a></h2>
|
||||
There are different software packages or various codes that may be used for manipulating or displaying NetCDF data. Some of them such as MATLAB programming language needs to enough information about provide codes in MATLAB as well as to know run codes and statements. Furthermore, user should have to pay for MATLAB programming and install it in her/his system. Also, another of them are related to other programming languages such as R, NCL (NCAR Command Language), and etc. It has been mentioned before that working by many of this methods to extract NetCDF files are so rough and complicated for users. Therefore, it is essential that users can extract their NC files in a user-friendly tool without any concerns. The NetCDF Extractor software is an easy tool for all users to extract their aim region from the main files. This tool is flexible to run for various datasets such as CMIP5 models, AgMERRA datasets, Aphrodite, CRU, CORDEX, and etc. Finally, this tool is NETCDF EXTRACTOR, NETCDF FILE VIEWER, and NETCDF CONVERTER. <a href="http://www.agrimetsoft.com/Netcdf-Extractor.aspx">NetCDF-Extractor website.</A>
|
||||
<p>
|
||||
|
||||
|
||||
NetCDF Extractor is a windows software for view, convert, merge, and
|
||||
extract data from .nc and .nc4 files. It can extract several nc files,
|
||||
simultaneously. When a user wants to extract several files of nc format
|
||||
simultaneously, he/she requires to load them at a same time with together,
|
||||
loading the files one by one will be a time consuming and tedious process
|
||||
and prone to error. By this software the user can save his/her time, and
|
||||
quickly do the extract process. Also, it has a calculator tool. In this
|
||||
calculator by entering latitude and longitude of the desirable region, the
|
||||
user can view of the grid number of that region. In the latest version of
|
||||
NetCDF Extractor, Agrimetsoft has added two options: Sum” and “Average”.
|
||||
So, the user can easily calculate the average and sum values of the
|
||||
selected area (grids). Data is shown in an organized table, and you can
|
||||
choose to export everything to Excel. This tool is flexible to run for
|
||||
various datasets such as CMIP5 models, AgMERRA, Aphrodite, CRU, and etc.
|
||||
Agrimetsoft support all the users until they can extract the data.
|
||||
</p>
|
||||
<p></p>
|
||||
|
||||
<h2><a id="ViewNcDap" name="ViewNcDap">ASA ViewNcDap</a></h2>
|
||||
@ -3522,7 +3586,7 @@ or using ECMWF reanalysis on a reduced grid
|
||||
which includes features such as Mercator projection, Polar Stereographic projection,
|
||||
color or gray scale area-fill contour plotting, and support for many devices:
|
||||
X-windows, PostScript, HP, Tektronix, and others. This powerful and flexible package
|
||||
recognizes netCDF data format, and it can extract axis lables and graph titles
|
||||
recognizes netCDF data format, and it can extract axis labels and graph titles
|
||||
from the data files. The user can customize a plots, or combine several plots
|
||||
into a composite. Plots are of publication quality. The PPLUS graphics package
|
||||
is used for all the TAO workstation displays, including the animations. The animations
|
||||
|
@ -353,7 +353,7 @@
|
||||
<li>
|
||||
The Woods Hole Field Center of the U.S.G.S. Marine and Coastal Geology Program
|
||||
uses netCDF to access a variety of scientific data sets, including output
|
||||
from circulation and sediment tranport models, sonar imagery, digital elevation
|
||||
from circulation and sediment transport models, sonar imagery, digital elevation
|
||||
models, and environmental sensor data. They also make available the <a
|
||||
href="http://crusty.er.usgs.gov/~cdenham/MexCDF/nc4ml5.html">NetCDF Toolbox for
|
||||
Matlab-5</a>
|
||||
|
4
dods.m4
4
dods.m4
@ -202,7 +202,7 @@
|
||||
# fi
|
||||
#
|
||||
# dnl Find the lib directory (which is named according to machine type).
|
||||
# dnl The test was using -z; I changed it to -n to fix a problem withthe
|
||||
# dnl The test was using -z; I changed it to -n to fix a problem with the
|
||||
# dnl matlab server build. The build did not find the libraries with the
|
||||
# dnl env var MATLAB_LIB was not set. 04/12/04 jhrg
|
||||
# AC_MSG_CHECKING(for matlab library dir)
|
||||
@ -301,7 +301,7 @@
|
||||
# AC_MSG_CHECKING(for the IDL root directory)
|
||||
# if test -z "$IDL_ROOT"
|
||||
# then
|
||||
# # Find IDL's root directory by looking at the exectuable and then
|
||||
# # Find IDL's root directory by looking at the executable and then
|
||||
# # finding where that symbolic link points.
|
||||
# # !!! Doesn't work if idl isn't a symbolic link - erd !!!
|
||||
# # I think that the following 'if' fixes the symbolic link problem.
|
||||
|
@ -12,7 +12,7 @@
|
||||
* global_ny == NY and
|
||||
* global_nx == (NX * number of MPI processes).
|
||||
* The data partitioning pattern is a column-wise partitioning across all
|
||||
* proceses. Each process writes a subarray of size ny * nx.
|
||||
* processes. Each process writes a subarray of size ny * nx.
|
||||
*
|
||||
* To compile:
|
||||
* mpicc -O2 parallel_vara.c -o parallel_vara -lnetcdf -lpnetcdf
|
||||
|
@ -57,7 +57,7 @@ main()
|
||||
temp_out[lat][lon] = 12.5;
|
||||
}
|
||||
|
||||
/* These are the latitudes and longitudes which corespond with
|
||||
/* These are the latitudes and longitudes which correspond with
|
||||
* ticks on the dimension axes. */
|
||||
for (lat = 0; lat < LAT_LEN; lat++)
|
||||
latitude[lat] = 40. + lat * 2.5;
|
||||
|
@ -61,7 +61,7 @@ main()
|
||||
if ((retval = nc_def_dim(ncid, "y", NY, &y_dimid)))
|
||||
ERR(retval);
|
||||
|
||||
/* Set up variabe data. */
|
||||
/* Set up variable data. */
|
||||
dimids[0] = x_dimid;
|
||||
dimids[1] = y_dimid;
|
||||
chunks[0] = NX/4;
|
||||
|
@ -7,9 +7,11 @@ FOREACH(F ${CDL_EXAMPLE_TESTS})
|
||||
add_sh_test(cdl ${F})
|
||||
ENDFOREACH()
|
||||
|
||||
SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_tests_simple_xy_wr)
|
||||
SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_tests_sfc_pres_temp_wr)
|
||||
SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_test_pres_temp_4D_wr)
|
||||
IF(HAVE_BASH)
|
||||
SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_tests_simple_xy_wr)
|
||||
SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_tests_sfc_pres_temp_wr)
|
||||
SET_TESTS_PROPERTIES(cdl_do_comps PROPERTIES DEPENDS C_test_pres_temp_4D_wr)
|
||||
ENDIF(HAVE_BASH)
|
||||
|
||||
SET(CLEANFILES simple_xy.nc sfc_pres_temp.nc pres_temp_4D.nc)
|
||||
SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEANFILES}")
|
||||
|
@ -104,7 +104,7 @@ main()
|
||||
H5T_NATIVE_DOUBLE) < 0) ERR;
|
||||
if (H5Tcommit(grpid, S1_TYPE_NAME, s1_typeid) < 0) ERR;
|
||||
|
||||
/* Create a vlen type. Its a vlen of stuct s1. */
|
||||
/* Create a vlen type. Its a vlen of struct s1. */
|
||||
if ((vlen_typeid = H5Tvlen_create(s1_typeid)) < 0) ERR;
|
||||
if (H5Tcommit(grpid, VLEN_TYPE_NAME, vlen_typeid) < 0) ERR;
|
||||
|
||||
|
@ -102,7 +102,7 @@ main()
|
||||
H5T_NATIVE_DOUBLE) < 0) ERR;
|
||||
if (H5Tcommit(grpid, S1_TYPE_NAME, s1_typeid) < 0) ERR;
|
||||
|
||||
/* Create a vlen type. Its a vlen of stuct s1. */
|
||||
/* Create a vlen type. Its a vlen of struct s1. */
|
||||
if ((vlen_typeid = H5Tvlen_create(s1_typeid)) < 0) ERR;
|
||||
if (H5Tcommit(grpid, VLEN_TYPE_NAME, vlen_typeid) < 0) ERR;
|
||||
|
||||
|
@ -512,7 +512,7 @@ main()
|
||||
lon_spaceid, H5P_DEFAULT)) < 0) ERR;
|
||||
if (H5DSset_scale(lon_scaleid, LON_NAME) < 0) ERR;
|
||||
|
||||
/* Create a space coresponding to these three dimensions. */
|
||||
/* Create a space corresponding to these three dimensions. */
|
||||
dims[TIME_DIM] = 0;
|
||||
dims[LAT_DIM] = LAT_LEN;
|
||||
dims[LON_DIM] = LON_LEN;
|
||||
@ -720,7 +720,7 @@ main()
|
||||
distance_spaceid, H5P_DEFAULT)) < 0) ERR;
|
||||
if (H5DSset_scale(distance_scaleid, DISTANCE_NAME) < 0) ERR;
|
||||
|
||||
/* Create a space coresponding to these three dimensions. */
|
||||
/* Create a space corresponding to these three dimensions. */
|
||||
dims[TIME_DIM] = 0;
|
||||
dims[SMELLINESS_DIM] = 0;
|
||||
dims[DISTANCE_DIM] = DISTANCE_LEN;
|
||||
|
@ -79,7 +79,7 @@ main()
|
||||
H5P_DEFAULT)) < 0) ERR;
|
||||
if ((grpid = H5Gcreate(fileid, GRP2_NAME, 0)) < 0) ERR;
|
||||
|
||||
/* Create a space coresponding to these three dimensions. */
|
||||
/* Create a space corresponding to these three dimensions. */
|
||||
dims[0] = 0;
|
||||
dims[1] = LAT_LEN;
|
||||
dims[2] = LON_LEN;
|
||||
|
@ -342,7 +342,7 @@ main()
|
||||
ERR;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
/* I cant get this to work, I don't think it's allowed in HDF5. - Ed 7/12/7 */
|
||||
/* I can't get this to work, I don't think it's allowed in HDF5. - Ed 7/12/7 */
|
||||
/* printf("*** Checking HDF5 scalar variable compession..."); */
|
||||
|
||||
/* #define MAX_NAME_LEN 50 */
|
||||
|
@ -17,7 +17,7 @@ getfile() {
|
||||
|
||||
for try in 1 2 3 4 ; do # try 4 times
|
||||
|
||||
# signal sucess/failure
|
||||
# signal success/failure
|
||||
if wget -c $Q --passive-ftp $FTPFILE ; then
|
||||
return 0 # got it
|
||||
fi
|
||||
|
@ -7,10 +7,8 @@
|
||||
#include <config.h>
|
||||
#include <unistd.h>
|
||||
#include <nc_tests.h>
|
||||
#include "err_macros.h"
|
||||
#include <hdf5.h>
|
||||
#include <H5DSpublic.h>
|
||||
#include "mfhdf.h"
|
||||
#include "err_macros.h"
|
||||
|
||||
#define DIM1 5
|
||||
#define DIM0 5
|
||||
@ -18,151 +16,117 @@
|
||||
#define FILENAME "tst_h4_lendian.h4"
|
||||
#define SDSNAME "data"
|
||||
|
||||
int read_hdf_file(int dtype) {
|
||||
/* Read the file. Return -1 if endianness is not little. */
|
||||
int read_hdf_file(int dtype)
|
||||
{
|
||||
int ncid = 0;
|
||||
int le_int16_varid = 0;
|
||||
int ed = 0;
|
||||
|
||||
int ncid = 0;
|
||||
int le_int16_varid = 0;
|
||||
int retval = 0;
|
||||
int ed = 0;
|
||||
if (nc_open(FILENAME, NC_NETCDF4 | NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_varid(ncid,SDSNAME,&le_int16_varid)) ERR;
|
||||
if (nc_inq_var_endian(ncid,le_int16_varid,&ed)) ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
|
||||
if (ed != NC_ENDIAN_LITTLE)
|
||||
return -1;
|
||||
|
||||
printf("\to Reading hdf4 file with a little-endian datatype %d\n",dtype);
|
||||
|
||||
printf("\t\to Opening file....\t\t\t\t\t");
|
||||
retval = nc_open(FILENAME, NC_NETCDF4 | NC_NOWRITE, &ncid);
|
||||
if(retval) {printf("Failure [%d]\n",retval); return retval;}
|
||||
else {printf("Success\n");}
|
||||
|
||||
printf("\t\to Getting varid....\t\t\t\t\t");
|
||||
retval = nc_inq_varid(ncid,SDSNAME,&le_int16_varid);
|
||||
if(retval) {printf("Failure [%d]\n",retval); return retval;}
|
||||
else {printf("Success\n");}
|
||||
|
||||
printf("\t\to Querying endianness of the variable....\t\t");
|
||||
retval = nc_inq_var_endian(ncid,le_int16_varid,&ed);
|
||||
if(retval) {printf("Failure [%d]\n",retval); return retval;}
|
||||
else {printf("Success\n");}
|
||||
|
||||
printf("\t\to Checking that endianness is NC_ENDIAN_LITTLE....\t");
|
||||
if (ed == NC_ENDIAN_LITTLE) printf("Success\n");
|
||||
else {printf("Failure [%d]\n\n",ed); nc_close(ncid); return -1;}
|
||||
|
||||
printf("\t\to Closing file....\t\t\t\t\t");
|
||||
retval = nc_close(ncid);
|
||||
if(retval) {printf("Failure [%d]\n\n",retval); return retval;}
|
||||
else {printf("Success\n\n");}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_hdf_file(int dtype) {
|
||||
/* Create a HDF4 file with one dataset of type dtype. */
|
||||
int create_hdf_file(int dtype)
|
||||
{
|
||||
int32 sd_id, sds_id;
|
||||
int32 start[2] = {0, 0}, edges[2] = {DIM1, DIM0};
|
||||
int16 array_data[DIM0][DIM1];
|
||||
int32 array_data_int32[DIM0][DIM1];
|
||||
float32 array_data_float32[DIM0][DIM1];
|
||||
float64 array_data_float64[DIM0][DIM1];
|
||||
void *data;
|
||||
intn i, j, count;
|
||||
|
||||
int32 sd_id, sds_id, istat, sd_index;
|
||||
int32 dims[2], start[2], edges[2], rank;
|
||||
int16 array_data[DIM0][DIM1];
|
||||
intn i, j, count;
|
||||
|
||||
start[0] = 0;
|
||||
start[1] = 0;
|
||||
edges[0] = DIM1;
|
||||
edges[1] = DIM0;
|
||||
|
||||
/* populate data array */
|
||||
count = 0;
|
||||
for (j = 0; j < DIM0; j++)
|
||||
/* Populate data arrays. */
|
||||
count = 0;
|
||||
for (j = 0; j < DIM0; j++)
|
||||
{
|
||||
for (i = 0; i < DIM1; i++)
|
||||
{
|
||||
for (i = 0; i < DIM1; i++)
|
||||
array_data[j][i] = count++;
|
||||
array_data[j][i] = count;
|
||||
array_data_int32[j][i] = count;
|
||||
array_data_float32[j][i] = count;
|
||||
array_data_float64[j][i] = count++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\to Creating hdf4 file with little-endian datatype %d....\t",dtype);
|
||||
/* Point to the correct data. */
|
||||
switch(dtype)
|
||||
{
|
||||
case DFNT_LINT8:
|
||||
case DFNT_LUINT8:
|
||||
case DFNT_LINT16:
|
||||
case DFNT_LUINT16:
|
||||
data = array_data;
|
||||
break;
|
||||
case DFNT_LINT32:
|
||||
case DFNT_LUINT32:
|
||||
data = array_data_int32;
|
||||
break;
|
||||
case DFNT_LFLOAT32:
|
||||
data = array_data_float32;
|
||||
break;
|
||||
case DFNT_LFLOAT64:
|
||||
data = array_data_float64;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
sd_id = SDstart(FILENAME, DFACC_CREATE);
|
||||
/* sds_id = SDcreate(sd_id, SDSNAME, DFNT_LITEND|dtype, RANK, edges); */
|
||||
sds_id = SDcreate(sd_id, SDSNAME, dtype, RANK, edges);
|
||||
if ((sd_id = SDstart(FILENAME, DFACC_CREATE)) == -1) ERR;
|
||||
if ((sds_id = SDcreate(sd_id, SDSNAME, dtype, RANK, edges)) == -1) ERR;
|
||||
if (SDwritedata(sds_id, start, NULL, edges, data)) ERR;
|
||||
if (SDend(sd_id)) ERR;
|
||||
|
||||
istat = SDendaccess(sds_id);
|
||||
if(istat) {printf("Failure %d\n", istat); SDend(sd_id); return istat;}
|
||||
|
||||
istat = SDend(sd_id);
|
||||
if(istat) {printf("Failure %d\n", istat); SDend(sd_id); return istat;}
|
||||
|
||||
sd_id = SDstart(FILENAME, DFACC_WRITE);
|
||||
|
||||
sd_index = 0;
|
||||
sds_id = SDselect(sd_id, sd_index);
|
||||
|
||||
istat = SDwritedata(sds_id, start, NULL, edges, (VOIDP)array_data);
|
||||
if(istat) {printf("Failure %d\n", istat); SDend(sd_id); return istat;}
|
||||
|
||||
istat = SDendaccess(sds_id);
|
||||
if(istat) {printf("Failure %d\n", istat); SDend(sd_id); return istat;}
|
||||
|
||||
istat = SDend(sd_id);
|
||||
if(istat) {printf("Failure %d\n", istat); return istat;}
|
||||
|
||||
printf("Success\n");
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int test_read_write(int dtype) {
|
||||
|
||||
int res = 0;
|
||||
|
||||
res = create_hdf_file(dtype);
|
||||
if(res) {unlink(FILENAME); return res;}
|
||||
|
||||
res = read_hdf_file(dtype);
|
||||
|
||||
unlink(FILENAME);
|
||||
return res;
|
||||
/* Create and then read the HDF4 test file. */
|
||||
int test_read_write(int dtype)
|
||||
{
|
||||
if (create_hdf_file(dtype))
|
||||
return -1;
|
||||
return read_hdf_file(dtype);
|
||||
}
|
||||
|
||||
/*! Standard main function.
|
||||
*
|
||||
*/
|
||||
int main() {
|
||||
int main()
|
||||
{
|
||||
printf("\n***Test reading from an hdf4 file with a little-endian datatype...\n");
|
||||
printf("*** testing reading...");
|
||||
{
|
||||
if (test_read_write(DFNT_LINT8)) ERR;
|
||||
if (test_read_write(DFNT_LUINT8)) ERR;
|
||||
if (test_read_write(DFNT_LINT16)) ERR;
|
||||
if (test_read_write(DFNT_LUINT16)) ERR;
|
||||
if (test_read_write(DFNT_LINT32)) ERR;
|
||||
if (test_read_write(DFNT_LUINT32)) ERR;
|
||||
if (test_read_write(DFNT_LFLOAT32)) ERR;
|
||||
/* if (test_read_write(DFNT_LFLOAT64)) ERR; */
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
|
||||
int res = 0;
|
||||
printf("*** testing for True Negatives. these will return error...");
|
||||
{
|
||||
/* True Negatives. */
|
||||
if (test_read_write(DFNT_INT8) != -1) ERR;
|
||||
if (test_read_write(DFNT_UINT8) != -1) ERR;
|
||||
if (test_read_write(DFNT_INT16) != -1) ERR;
|
||||
if (test_read_write(DFNT_UINT16) != -1) ERR;
|
||||
if (test_read_write(DFNT_INT32) != -1) ERR;
|
||||
if (test_read_write(DFNT_UINT32) != -1) ERR;
|
||||
if (test_read_write(DFNT_FLOAT32) != -1) ERR;
|
||||
if (test_read_write(DFNT_FLOAT64) != -1) ERR;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
|
||||
printf("Test reading from an hdf4 file with a little-endian datatype.\n");
|
||||
|
||||
/* True Positives. */
|
||||
res = test_read_write(DFNT_LINT8);
|
||||
res = test_read_write(DFNT_LUINT8);
|
||||
res = test_read_write(DFNT_LINT16);
|
||||
res = test_read_write(DFNT_LUINT16);
|
||||
res = test_read_write(DFNT_LINT32);
|
||||
res = test_read_write(DFNT_LUINT32);
|
||||
res = test_read_write(DFNT_LFLOAT32);
|
||||
res = test_read_write(DFNT_LFLOAT64);
|
||||
|
||||
/* True Negatives. */
|
||||
printf("\t**** Testing for True Negatives. THESE SHOULD FAIL.****\n\n");
|
||||
res = test_read_write(DFNT_INT8);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
res = test_read_write(DFNT_UINT8);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
res = test_read_write(DFNT_INT16);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
res = test_read_write(DFNT_UINT16);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
res = test_read_write(DFNT_INT32);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
res = test_read_write(DFNT_UINT32);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
res = test_read_write(DFNT_FLOAT32);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
res = test_read_write(DFNT_FLOAT64);
|
||||
if(!res) {printf("Should have failed. Error!\n"); return -1;}
|
||||
|
||||
printf("Finished.\n");
|
||||
return 0;
|
||||
FINAL_RESULTS;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
/* This is part of the netCDF package. Copyright 2005-2011,
|
||||
/* This is part of the netCDF package. Copyright 2005-2018,
|
||||
University Corporation for Atmospheric Research/Unidata. See
|
||||
COPYRIGHT file for conditions of use.
|
||||
|
||||
Test that NetCDF-4 can read HDF4 files.
|
||||
Ed Hartnett
|
||||
Ed Hartnett, Ward Fisher
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <nc_tests.h>
|
||||
@ -30,12 +30,12 @@ create_hdf4_file()
|
||||
int test_val = 42;
|
||||
int i, j;
|
||||
int count = 0;
|
||||
|
||||
|
||||
/* Create some data. */
|
||||
for (i = 0; i < LAT_LEN; i++)
|
||||
for (j = 0; j < LON_LEN; j++)
|
||||
data_out[i][j] = count++;
|
||||
|
||||
|
||||
/* Create a file with one SDS, containing our phony data. */
|
||||
sd_id = SDstart(FILE_NAME, DFACC_CREATE);
|
||||
sds_id = SDcreate(sd_id, PRES_NAME, DFNT_INT32, NDIMS2, dim_size);
|
||||
@ -58,16 +58,17 @@ main(int argc, char **argv)
|
||||
|
||||
/* Create our test file. */
|
||||
if (create_hdf4_file()) ERR;
|
||||
|
||||
|
||||
printf("*** testing data conversion...");
|
||||
{
|
||||
int ncid;
|
||||
size_t start[NDIMS2] = {0, 0}, count[NDIMS2] = {LAT_LEN, LON_LEN};
|
||||
int data_int[LAT_LEN * LON_LEN];
|
||||
short data_short[LAT_LEN * LON_LEN];
|
||||
int data_int2[LAT_LEN * LON_LEN];
|
||||
float data_float[LAT_LEN * LON_LEN];
|
||||
double data_double[LAT_LEN * LON_LEN];
|
||||
int data_int[LAT_LEN * LON_LEN];
|
||||
short data_short[LAT_LEN * LON_LEN];
|
||||
int data_int2[LAT_LEN * LON_LEN];
|
||||
float data_float[LAT_LEN * LON_LEN];
|
||||
double data_double[LAT_LEN * LON_LEN];
|
||||
int i = 0;
|
||||
|
||||
/* Open HDF4 file with netCDF. */
|
||||
if (nc_open(FILE_NAME, 0, &ncid)) ERR;
|
||||
@ -79,27 +80,27 @@ main(int argc, char **argv)
|
||||
|
||||
/* Read data as short. */
|
||||
if (nc_get_vara_short(ncid, 0, start, count, data_short)) ERR;
|
||||
for (int i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
for (i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
if (data_short[i] != (short)i) ERR;
|
||||
|
||||
/* Read data as int. */
|
||||
if (nc_get_vara_int(ncid, 0, start, count, data_int)) ERR;
|
||||
for (int i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
for (i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
if (data_int[i] != i) ERR;
|
||||
|
||||
/* NULL count is treated as meaing entire variable. */
|
||||
if (nc_get_vara_int(ncid, 0, start, NULL, data_int2)) ERR;
|
||||
for (int i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
for (i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
if (data_int2[i] != i) ERR;
|
||||
|
||||
/* Read data as float. */
|
||||
if (nc_get_vara_float(ncid, 0, start, count, data_float)) ERR;
|
||||
for (int i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
for (i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
if (data_float[i] != (float)i) ERR;
|
||||
|
||||
/* Read data as double. */
|
||||
if (nc_get_vara_double(ncid, 0, start, count, data_double)) ERR;
|
||||
for (int i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
for (i = 0; i < LAT_LEN * LON_LEN; i++)
|
||||
if (data_double[i] != (double)i) ERR;
|
||||
|
||||
/* Close the file. */
|
||||
|
@ -80,7 +80,7 @@ extern int
|
||||
NC3_abort(int ncid);
|
||||
|
||||
extern int
|
||||
NC3_close(int ncid);
|
||||
NC3_close(int ncid,void*);
|
||||
|
||||
extern int
|
||||
NC3_set_fill(int ncid, int fillmode, int *old_modep);
|
||||
|
@ -46,7 +46,7 @@ extern int
|
||||
NC4_abort(int ncid);
|
||||
|
||||
extern int
|
||||
NC4_close(int ncid);
|
||||
NC4_close(int ncid,void*);
|
||||
|
||||
extern int
|
||||
NC4_set_fill(int ncid, int fillmode, int *old_modep);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "ncdimscale.h"
|
||||
#include "nc_logging.h"
|
||||
#include "netcdf_mem.h"
|
||||
#include "ncindex.h"
|
||||
|
||||
#ifdef USE_PARALLEL
|
||||
@ -326,6 +327,17 @@ typedef struct NC_HDF5_FILE_INFO
|
||||
void *format_file_info;
|
||||
#endif /* USE_HDF4 */
|
||||
struct NCFILEINFO* fileinfo;
|
||||
struct NC4_Memio {
|
||||
NC_memio memio;
|
||||
int locked; /* do not copy and do not release */
|
||||
int persist; /* Should file be persisted out on close? */
|
||||
int inmemory;
|
||||
int diskless;
|
||||
unsigned int flags; /* for H5LTopen_file_image */
|
||||
int fapl;
|
||||
size_t initialsize;
|
||||
int created; /* 1 => create, 0 => open */
|
||||
} mem;
|
||||
} NC_HDF5_FILE_INFO_T;
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@ char *nulldup(const char* s);
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#include <basetsd.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#define HAVE_SSIZE_T 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -5,8 +5,13 @@
|
||||
Includes for some HDF5 stuff needed by tests.
|
||||
*/
|
||||
|
||||
#ifndef _NCDIMSCALE_H_
|
||||
#define _NCDIMSCALE_H_
|
||||
|
||||
typedef struct hdf5_objid
|
||||
{
|
||||
unsigned long fileno[2]; /* file number */
|
||||
haddr_t objno[2]; /* object number */
|
||||
} HDF5_OBJID_T;
|
||||
|
||||
#endif
|
||||
|
@ -105,11 +105,6 @@ typedef struct NC_MPI_INFO {
|
||||
MPI_Info info;
|
||||
} NC_MPI_INFO;
|
||||
|
||||
typedef struct NC_MEM_INFO {
|
||||
size_t size;
|
||||
void* memory;
|
||||
} NC_MEM_INFO;
|
||||
|
||||
/* Define known dispatch tables and initializers */
|
||||
|
||||
/*Forward*/
|
||||
@ -211,7 +206,7 @@ int (*redef)(int);
|
||||
int (*_enddef)(int,size_t,size_t,size_t,size_t);
|
||||
int (*sync)(int);
|
||||
int (*abort)(int);
|
||||
int (*close)(int);
|
||||
int (*close)(int,void*);
|
||||
int (*set_fill)(int,int,int*);
|
||||
int (*inq_base_pe)(int,int*);
|
||||
int (*set_base_pe)(int,int);
|
||||
|
@ -35,7 +35,7 @@ typedef struct NCRCglobalstate {
|
||||
int initialized;
|
||||
char* tempdir; /* track a usable temp dir */
|
||||
char* home; /* track $HOME for use in creating $HOME/.oc dir */
|
||||
NCRCinfo rcinfo; /* Currenly only one rc file per session */
|
||||
NCRCinfo rcinfo; /* Currently only one rc file per session */
|
||||
} NCRCglobalstate;
|
||||
|
||||
extern NCRCglobalstate ncrc_globalstate; /* singleton instance */
|
||||
|
@ -154,7 +154,7 @@ Use this in mode flags for both nc_create() and nc_open(). */
|
||||
Use this in mode flags for both nc_create() and nc_open(). */
|
||||
#define NC_MPIPOSIX 0x4000 /**< \deprecated As of libhdf5 1.8.13. */
|
||||
|
||||
#define NC_INMEMORY 0x8000 /**< Read from memory. Mode flag for nc_open() or nc_create(). */
|
||||
#define NC_INMEMORY 0x8000 /**< Read from memory. Mode flag for nc_open() or nc_create() => NC_DISKLESS */
|
||||
|
||||
#define NC_PNETCDF (NC_MPIIO) /**< Use parallel-netcdf library; alias for NC_MPIIO. */
|
||||
|
||||
@ -459,7 +459,8 @@ by the desired type. */
|
||||
#define NC_EFILTER (-132) /**< Filter operation failed. */
|
||||
#define NC_ERCFILE (-133) /**< RC file failure */
|
||||
#define NC_ENULLPAD (-134) /**< Header Bytes not Null-Byte padded */
|
||||
#define NC4_LAST_ERROR (-135) /**< @internal All netCDF errors > this. */
|
||||
#define NC_EINMEMORY (-135) /**< In-memory file error */
|
||||
#define NC4_LAST_ERROR (-136) /**< @internal All netCDF errors > this. */
|
||||
|
||||
/** @internal This is used in netCDF-4 files for dimensions without
|
||||
* coordinate vars. */
|
||||
|
@ -14,12 +14,30 @@
|
||||
|
||||
#include <netcdf.h>
|
||||
|
||||
typedef struct NC_memio {
|
||||
size_t size;
|
||||
void* memory;
|
||||
#define NC_MEMIO_LOCKED 1 /* Do not try to realloc or free provided memory */
|
||||
int flags;
|
||||
} NC_memio;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Treate a memory block as a file; read-only */
|
||||
EXTERNL int nc_open_mem(const char* path, int mode, size_t size, void* memory, int* ncidp);
|
||||
|
||||
EXTERNL int nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp);
|
||||
|
||||
/* Alternative to nc_open_mem with extended capabilites
|
||||
See docs/inmemory.md
|
||||
*/
|
||||
EXTERNL int nc_open_memio(const char* path, int mode, NC_memio* info, int* ncidp);
|
||||
|
||||
/* Close memory file and return the final memory state */
|
||||
EXTERNL int nc_close_memio(int ncid, NC_memio* info);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -9,7 +9,7 @@
|
||||
* include this file unless you want to probe the capabilities
|
||||
* of libnetcdf. This should ideally only happen when configuring
|
||||
* a project which depends on libnetcdf. At configure time,
|
||||
* the dependant project can set its own macros which can be used
|
||||
* the dependent project can set its own macros which can be used
|
||||
* in conditionals.
|
||||
*
|
||||
* Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
|
@ -381,7 +381,7 @@ iscacheableconstraint(DCEconstraint* con)
|
||||
int i;
|
||||
if(con == NULL) return 1;
|
||||
if(con->selections != NULL && nclistlength(con->selections) > 0)
|
||||
return 0; /* cant deal with selections */
|
||||
return 0; /* can't deal with selections */
|
||||
for(i=0;i<nclistlength(con->projections);i++) {
|
||||
if(!iscacheableprojection((DCEprojection*)nclistget(con->projections,i)))
|
||||
return 0;
|
||||
|
@ -538,7 +538,7 @@ fprintf(stderr,"fixprojection: list = %s\n",dumpprojections(list));
|
||||
for(i=0;i<nclistlength(list);i++) {
|
||||
DCEprojection* p1 = (DCEprojection*)nclistget(list,i);
|
||||
if(p1 == NULL) continue;
|
||||
if(p1->discrim != CES_VAR) continue; /* dont try to unify functions */
|
||||
if(p1->discrim != CES_VAR) continue; /* don't try to unify functions */
|
||||
for(j=i;j<nclistlength(list);j++) {
|
||||
DCEprojection* p2 = (DCEprojection*)nclistget(list,j);
|
||||
if(p2 == NULL) continue;
|
||||
@ -560,7 +560,7 @@ fprintf(stderr,"fixprojection: list = %s\n",dumpprojections(list));
|
||||
for(i=0;i<nclistlength(list);i++) {
|
||||
DCEprojection* p1 = (DCEprojection*)nclistget(list,i);
|
||||
if(p1 == NULL) continue;
|
||||
if(p1->discrim != CES_VAR) continue; /* dont try to unify functions */
|
||||
if(p1->discrim != CES_VAR) continue; /* don't try to unify functions */
|
||||
if(!iscontainer((CDFnode*)p1->var->annotation))
|
||||
continue;
|
||||
for(j=i;j<nclistlength(list);j++) {
|
||||
@ -589,7 +589,7 @@ next: continue;
|
||||
CDFnode* leaf;
|
||||
if(target == NULL) continue;
|
||||
if(target->discrim != CES_VAR)
|
||||
continue; /* dont try to unify functions */
|
||||
continue; /* don't try to unify functions */
|
||||
leaf = (CDFnode*)target->var->annotation;
|
||||
ASSERT(leaf != NULL);
|
||||
if(iscontainer(leaf)) {/* capture container */
|
||||
|
@ -341,7 +341,7 @@ makeocpathstring(OClink conn, OCddsnode node, const char* sep)
|
||||
NCbytes* pathname = NULL;
|
||||
|
||||
/* If we are asking for the dataset path only,
|
||||
then nclude it, otherwise elide it
|
||||
then include it, otherwise elide it
|
||||
*/
|
||||
oc_dds_type(conn,node,&octype);
|
||||
if(octype == OC_Dataset) {
|
||||
|
@ -226,7 +226,7 @@ NCD2_sync(int ncid)
|
||||
static int
|
||||
NCD2_abort(int ncid)
|
||||
{
|
||||
return NCD2_close(ncid);
|
||||
return NCD2_close(ncid,NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -597,13 +597,13 @@ fprintf(stderr,"ncdap3: final constraint: %s\n",dapcomm->oc.url->query);
|
||||
return ncstat;
|
||||
|
||||
done:
|
||||
if(drno != NULL) NCD2_close(drno->ext_ncid);
|
||||
if(drno != NULL) NCD2_close(drno->ext_ncid,NULL);
|
||||
if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
|
||||
return THROW(ncstat);
|
||||
}
|
||||
|
||||
int
|
||||
NCD2_close(int ncid)
|
||||
NCD2_close(int ncid, void* ignore)
|
||||
{
|
||||
NC* drno;
|
||||
NCDAPCOMMON* dapcomm;
|
||||
@ -692,7 +692,7 @@ builddims(NCDAPCOMMON* dapcomm)
|
||||
#if 0
|
||||
nc3sub = (NC3_INFO*)&ncsub->dispatchdata;
|
||||
/* Set the effective size of UNLIMITED;
|
||||
note that this cannot easily be done thru the normal API.*/
|
||||
note that this cannot easily be done through the normal API.*/
|
||||
NC_set_numrecs(nc3sub,unlimited->dim.declsize);
|
||||
#endif
|
||||
|
||||
@ -1450,7 +1450,7 @@ addstringdims(NCDAPCOMMON* dapcomm)
|
||||
if(dimsize == 0)
|
||||
sdim = dapcomm->cdf.globalstringdim; /* use default */
|
||||
else {
|
||||
/* create a psuedo dimension for the charification of the string*/
|
||||
/* create a pseudo dimension for the charification of the string*/
|
||||
if(var->dodsspecial.dimname != NULL) {
|
||||
strncpy(dimname,var->dodsspecial.dimname,sizeof(dimname));
|
||||
dimname[sizeof(dimname)-1] = '\0';
|
||||
|
@ -50,7 +50,7 @@ NCD2_open(const char *path, int mode,
|
||||
struct NC_Dispatch* dispatch, NC* ncp);
|
||||
|
||||
extern int
|
||||
NCD2_close(int ncid);
|
||||
NCD2_close(int ncid,void*);
|
||||
|
||||
extern int
|
||||
NCD2_inq_format_extended(int ncid, int* formatp, int* modep);
|
||||
|
@ -341,7 +341,7 @@ NCD4_abort(int ncid)
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* Auxilliary routines */
|
||||
/* Auxiliary routines */
|
||||
/**************************************************/
|
||||
|
||||
static void
|
||||
|
@ -245,7 +245,7 @@ done:
|
||||
}
|
||||
|
||||
int
|
||||
NCD4_close(int ncid)
|
||||
NCD4_close(int ncid, void* ignore)
|
||||
{
|
||||
int ret = NC_NOERR;
|
||||
NC* nc;
|
||||
@ -278,7 +278,7 @@ done:
|
||||
int
|
||||
NCD4_abort(int ncid)
|
||||
{
|
||||
return NCD4_close(ncid);
|
||||
return NCD4_close(ncid,NULL);
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
|
@ -415,7 +415,7 @@ done:
|
||||
/**************************************************/
|
||||
/*
|
||||
Walk the (toplevel) var's data to get to the count'th instance.
|
||||
For effiency, it can be supplied with a previous case.
|
||||
For efficiency, it can be supplied with a previous case.
|
||||
Assumes it is called after byte swapping and offsetting.
|
||||
Assumes that var is not fixed size.
|
||||
*/
|
||||
|
@ -133,7 +133,7 @@ NCD4_fetchurl(CURL* curl, const char* url, NCbytes* buf, long* filetime)
|
||||
/* Null terminate the buffer*/
|
||||
len = ncbyteslength(buf);
|
||||
ncbytesappend(buf, '\0');
|
||||
ncbytessetlength(buf, len); /* dont count null in buffer size*/
|
||||
ncbytessetlength(buf, len); /* don't count null in buffer size*/
|
||||
#ifdef D4DEBUG
|
||||
nclog(NCLOGNOTE,"buffersize: %lu bytes",(d4size_t)ncbyteslength(buf));
|
||||
#endif
|
||||
|
@ -424,7 +424,7 @@ buildAttributes(NCD4meta* builder, NCD4node* varorgroup)
|
||||
NCD4node* group;
|
||||
int varid;
|
||||
|
||||
/* Supress all UCARTAG attributes */
|
||||
/* Suppress all UCARTAG attributes */
|
||||
if(strncmp(attr->name,UCARTAG,strlen(UCARTAG)) == 0)
|
||||
continue;
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "ezxml.h"
|
||||
|
||||
/*
|
||||
The primary purpose of this code is to recursivly traverse
|
||||
The primary purpose of this code is to recursively traverse
|
||||
the incoming data to get the endianness correct.
|
||||
*/
|
||||
|
||||
|
@ -750,7 +750,7 @@ void ezxml_free(ezxml_t xml)
|
||||
ezxml_free(xml->ordered);
|
||||
|
||||
if (! xml->parent) { /* free root tag allocations*/
|
||||
for (i = 10; root->ent[i]; i += 2) /* 0 - 9 are default entites (<>&"')*/
|
||||
for (i = 10; root->ent[i]; i += 2) /* 0 - 9 are default entities (<>&"')*/
|
||||
if ((s = root->ent[i + 1]) < root->s || s > root->e) free(s);
|
||||
free(root->ent); /* free list of general entities*/
|
||||
|
||||
|
@ -93,7 +93,7 @@ ezxml_t ezxml_idx(ezxml_t xml, int idx);
|
||||
/* returns the value of the requested tag attribute, or NULL if not found*/
|
||||
const char *ezxml_attr(ezxml_t xml, const char *attr);
|
||||
|
||||
/* Traverses the ezxml sturcture to retrieve a specific subtag. Takes a*/
|
||||
/* Traverses the ezxml structure to retrieve a specific subtag. Takes a*/
|
||||
/* variable length list of tag names and indexes. The argument list must be*/
|
||||
/* terminated by either an index of -1 or an empty string tag name. Example: */
|
||||
/* title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1);*/
|
||||
|
@ -21,7 +21,7 @@ NCD4_open(const char *path, int mode,
|
||||
struct NC_Dispatch* dispatch, NC* ncp);
|
||||
|
||||
extern int
|
||||
NCD4_close(int ncid);
|
||||
NCD4_close(int ncid,void*);
|
||||
|
||||
extern int
|
||||
NCD4_abort(int ncid);
|
||||
|
@ -48,7 +48,7 @@ case where memory must be explicitly released.
|
||||
\returns ::NC_ENOTATT Can't find attribute.
|
||||
\returns ::NC_ECHAR Can't convert to or from NC_CHAR.
|
||||
\returns ::NC_ENOMEM Out of memory.
|
||||
\returns ::NC_ERANGE Data convertion went out of range.
|
||||
\returns ::NC_ERANGE Data conversion went out of range.
|
||||
|
||||
<h1>Example</h1>
|
||||
|
||||
@ -107,7 +107,7 @@ function works with any type of data, including user defined types.
|
||||
|
||||
\note The netCDF library reads all attributes into memory when the
|
||||
file is opened with nc_open(). Getting an attribute copies the value
|
||||
from the in-memory store, and does not incure any file I/O penalties.
|
||||
from the in-memory store, and does not incur any file I/O penalties.
|
||||
|
||||
\param ncid NetCDF or group ID, from a previous call to nc_open(),
|
||||
nc_create(), nc_def_grp(), or associated inquiry functions such as
|
||||
@ -132,7 +132,7 @@ the attribute.
|
||||
\returns ::NC_ENOTATT Can't find attribute.
|
||||
\returns ::NC_ECHAR Can't convert to or from NC_CHAR.
|
||||
\returns ::NC_ENOMEM Out of memory.
|
||||
\returns ::NC_ERANGE Data convertion went out of range.
|
||||
\returns ::NC_ERANGE Data conversion went out of range.
|
||||
|
||||
<h1>Example</h1>
|
||||
|
||||
@ -353,7 +353,7 @@ the attribute.
|
||||
\returns ::NC_ENOTATT Can't find attribute.
|
||||
\returns ::NC_ECHAR Can't convert to or from NC_CHAR.
|
||||
\returns ::NC_ENOMEM Out of memory.
|
||||
\returns ::NC_ERANGE Data convertion went out of range.
|
||||
\returns ::NC_ERANGE Data conversion went out of range.
|
||||
|
||||
\section nc_get_att_string_example Example
|
||||
|
||||
|
@ -262,9 +262,11 @@ const char *nc_strerror(int ncerr1)
|
||||
case NC_EMPI: return "NetCDF: MPI operation failed.";
|
||||
case NC_ERCFILE:
|
||||
return "NetCDF: RC File Failure.";
|
||||
case NC_ENULLPAD:
|
||||
return "NetCDF: File fails strict Null-Byte Header check.";
|
||||
default:
|
||||
case NC_ENULLPAD:
|
||||
return "NetCDF: File fails strict Null-Byte Header check.";
|
||||
case NC_EINMEMORY:
|
||||
return "NetCDF: In-memory File operation failed.";
|
||||
default:
|
||||
#ifdef USE_PNETCDF
|
||||
/* The behavior of ncmpi_strerror here is to return
|
||||
NULL, not a string. This causes problems in (at least)
|
||||
|
@ -181,10 +181,10 @@ NC_check_file_type(const char *path, int flags, void *parameters,
|
||||
int status = NC_NOERR;
|
||||
|
||||
int diskless = ((flags & NC_DISKLESS) == NC_DISKLESS);
|
||||
int inmemory = (!diskless && ((flags & NC_INMEMORY) == NC_INMEMORY));
|
||||
#ifdef USE_PARALLEL
|
||||
int use_parallel = ((flags & NC_MPIIO) == NC_MPIIO);
|
||||
#endif /* USE_PARALLEL */
|
||||
int inmemory = (diskless && ((flags & NC_INMEMORY) == NC_INMEMORY));
|
||||
struct MagicFile file;
|
||||
|
||||
*model = 0;
|
||||
@ -194,7 +194,7 @@ NC_check_file_type(const char *path, int flags, void *parameters,
|
||||
file.path = path; /* do not free */
|
||||
file.parameters = parameters;
|
||||
if(inmemory && parameters == NULL)
|
||||
{status = NC_EDISKLESS; goto done;}
|
||||
{status = NC_EINMEMORY; goto done;}
|
||||
if(inmemory) {
|
||||
file.inmemory = inmemory;
|
||||
goto next;
|
||||
@ -263,8 +263,8 @@ and attributes.
|
||||
NC_64BIT_DATA (Alias NC_CDF5) (create CDF-5 file),
|
||||
NC_NETCDF4 (create netCDF-4/HDF5 file),
|
||||
NC_CLASSIC_MODEL (enforce netCDF classic mode on netCDF-4/HDF5 files),
|
||||
NC_DISKLESS (store data only in memory),
|
||||
NC_MMAP (use MMAP for NC_DISKLESS),
|
||||
NC_DISKLESS (store data in memory),
|
||||
NC_MMAP (use MMAP for NC_DISKLESS instead of NC_INMEMORY),
|
||||
and NC_WRITE.
|
||||
See discussion below.
|
||||
|
||||
@ -278,7 +278,10 @@ aspects of how it may be used.
|
||||
|
||||
Setting NC_NOCLOBBER means you do not want to clobber (overwrite) an
|
||||
existing dataset; an error (NC_EEXIST) is returned if the specified
|
||||
dataset already exists.
|
||||
dataset already exists. As a slight variation on this, if you
|
||||
specify NC_DISKLESS and NC_NOCLOBBER, the file will be created
|
||||
in-memory, but no attempt will be made to persiste the in-memory
|
||||
data to a disk file.
|
||||
|
||||
The NC_SHARE flag is appropriate when one process may be writing the
|
||||
dataset and one or more other processes reading the dataset
|
||||
@ -456,7 +459,7 @@ nc_create(const char *path, int cmode, int *ncidp)
|
||||
|
||||
/**
|
||||
* Create a netCDF file with some extra parameters controlling classic
|
||||
* file cacheing.
|
||||
* file caching.
|
||||
*
|
||||
* Like nc_create(), this function creates a netCDF file.
|
||||
*
|
||||
@ -528,6 +531,58 @@ nc__create(const char *path, int cmode, size_t initialsz,
|
||||
chunksizehintp, 0, NULL, ncidp);
|
||||
|
||||
}
|
||||
|
||||
/** \ingroup datasets
|
||||
Create a netCDF file with the contents stored in memory.
|
||||
|
||||
\param path Must be non-null, but otherwise only used to set the dataset name.
|
||||
|
||||
\param mode the mode flags; Note that this procedure uses a limited set of flags because it forcibly sets NC_INMEMORY.
|
||||
|
||||
\param initialsize (advisory) size to allocate for the created file
|
||||
|
||||
\param ncidp Pointer to location where returned netCDF ID is to be
|
||||
stored.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
|
||||
\returns ::NC_ENOMEM Out of memory.
|
||||
|
||||
\returns ::NC_EDISKLESS diskless io is not enabled for fails.
|
||||
|
||||
\returns ::NC_EINVAL, etc. other errors also returned by nc_open.
|
||||
|
||||
<h1>Examples</h1>
|
||||
|
||||
In this example we use nc_create_mem() to create a classic netCDF dataset
|
||||
named foo.nc. The initial size is set to 4096.
|
||||
|
||||
@code
|
||||
#include <netcdf.h>
|
||||
...
|
||||
int status = NC_NOERR;
|
||||
int ncid;
|
||||
int mode = 0;
|
||||
size_t initialsize = 4096;
|
||||
...
|
||||
status = nc_create_mem("foo.nc", mode, initialsize, &ncid);
|
||||
if (status != NC_NOERR) handle_error(status);
|
||||
@endcode
|
||||
*/
|
||||
|
||||
int
|
||||
nc_create_mem(const char* path, int mode, size_t initialsize, int* ncidp)
|
||||
{
|
||||
#ifdef USE_DISKLESS
|
||||
if(mode & (NC_MPIIO|NC_MPIPOSIX|NC_MMAP))
|
||||
return NC_EINVAL;
|
||||
mode |= (NC_INMEMORY|NC_NOCLOBBER); /* Specifically, do not set NC_DISKLESS */
|
||||
return NC_create(path, mode, initialsize, 0, NULL, 0, NULL, ncidp);
|
||||
#else
|
||||
return NC_EDISKLESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Create a file with special (deprecated) Cray settings.
|
||||
*
|
||||
@ -740,7 +795,7 @@ Open a netCDF file with the contents taken from a block of memory.
|
||||
|
||||
\param path Must be non-null, but otherwise only used to set the dataset name.
|
||||
|
||||
\param mode the mode flags; Note that this procedure uses a limited set of flags because it forcibly sets NC_NOWRITE|NC_DISKLESS|NC_INMEMORY.
|
||||
\param mode the mode flags; Note that this procedure uses a limited set of flags because it forcibly sets NC_INMEMORY.
|
||||
|
||||
\param size The length of the block of memory being passed.
|
||||
|
||||
@ -784,22 +839,89 @@ int
|
||||
nc_open_mem(const char* path, int mode, size_t size, void* memory, int* ncidp)
|
||||
{
|
||||
#ifdef USE_DISKLESS
|
||||
NC_MEM_INFO meminfo;
|
||||
NC_memio meminfo;
|
||||
|
||||
/* Sanity checks */
|
||||
if(memory == NULL || size < MAGIC_NUMBER_LEN || path == NULL)
|
||||
return NC_EINVAL;
|
||||
if(mode & (NC_WRITE|NC_MPIIO|NC_MPIPOSIX|NC_MMAP))
|
||||
return NC_EINVAL;
|
||||
mode |= (NC_INMEMORY|NC_DISKLESS);
|
||||
mode |= (NC_INMEMORY); /* DO not set NC_DISKLESS */
|
||||
meminfo.size = size;
|
||||
meminfo.memory = memory;
|
||||
meminfo.flags = NC_MEMIO_LOCKED;
|
||||
return NC_open(path, mode, 0, NULL, 0, &meminfo, ncidp);
|
||||
#else
|
||||
return NC_EDISKLESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \ingroup datasets
|
||||
Open a netCDF file with the contents taken from a block of memory.
|
||||
Similar to nc_open_mem, but with parameters. Warning: if you do
|
||||
specify that the provided memory is locked, then <b>never</b>
|
||||
pass in non-heap allocated memory. Additionally, if not locked,
|
||||
then do not assume that the memory returned by nc_close_mem
|
||||
is the same as passed to nc_open_memio. You <b>must</b> check
|
||||
before attempting to free the original memory.
|
||||
|
||||
\param path Must be non-null, but otherwise only used to set the dataset name.
|
||||
|
||||
\param mode the mode flags; Note that this procedure uses a limited set of flags because it forcibly sets NC_INMEMORY.
|
||||
|
||||
\param params controlling parameters
|
||||
|
||||
\param ncidp Pointer to location where returned netCDF ID is to be
|
||||
stored.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
|
||||
\returns ::NC_ENOMEM Out of memory.
|
||||
|
||||
\returns ::NC_EDISKLESS diskless io is not enabled for fails.
|
||||
|
||||
\returns ::NC_EINVAL, etc. other errors also returned by nc_open.
|
||||
|
||||
<h1>Examples</h1>
|
||||
|
||||
Here is an example using nc_open_memio() to open an existing netCDF dataset
|
||||
named foo.nc for read-only, non-shared access. It differs from the nc_open_mem()
|
||||
example in that it uses a parameter block.
|
||||
|
||||
@code
|
||||
#include <netcdf.h>
|
||||
#include <netcdf_mem.h>
|
||||
...
|
||||
int status = NC_NOERR;
|
||||
int ncid;
|
||||
NC_memio params;
|
||||
...
|
||||
params.size = <compute file size of foo.nc in bytes>;
|
||||
params.memory = malloc(size);
|
||||
params.flags = <see netcdf_mem.h>
|
||||
...
|
||||
status = nc_open_memio("foo.nc", 0, ¶ms, &ncid);
|
||||
if (status != NC_NOERR) handle_error(status);
|
||||
@endcode
|
||||
*/
|
||||
int
|
||||
nc_open_memio(const char* path, int mode, NC_memio* params, int* ncidp)
|
||||
{
|
||||
#ifdef USE_DISKLESS
|
||||
/* Sanity checks */
|
||||
if(path == NULL || params == NULL)
|
||||
return NC_EINVAL;
|
||||
if(params->memory == NULL || params->size < MAGIC_NUMBER_LEN)
|
||||
return NC_EINVAL;
|
||||
if(mode & (NC_MPIIO|NC_MPIPOSIX|NC_MMAP))
|
||||
return NC_EINVAL;
|
||||
mode |= (NC_INMEMORY);
|
||||
return NC_open(path, mode, 0, NULL, 0, params, ncidp);
|
||||
#else
|
||||
return NC_EINMEMORY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Open a netCDF file with extra parameters for Cray.
|
||||
*
|
||||
@ -1263,8 +1385,7 @@ nc_close(int ncid)
|
||||
if(ncp->refcount <= 0)
|
||||
#endif
|
||||
{
|
||||
|
||||
stat = ncp->dispatch->close(ncid);
|
||||
stat = ncp->dispatch->close(ncid,NULL);
|
||||
/* Remove from the nc list */
|
||||
if (!stat)
|
||||
{
|
||||
@ -1275,6 +1396,75 @@ nc_close(int ncid)
|
||||
return stat;
|
||||
}
|
||||
|
||||
/** \ingroup datasets
|
||||
Do a normal close (see nc_close()) on an in-memory dataset,
|
||||
then return a copy of the final memory contents of the dataset.
|
||||
|
||||
\param ncid NetCDF ID, from a previous call to nc_open() or nc_create().
|
||||
|
||||
\param memio a pointer to an NC_memio object into which the final valid memory
|
||||
size and memory will be returned.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
|
||||
\returns ::NC_EBADID Invalid id passed.
|
||||
|
||||
\returns ::NC_ENOMEM Out of memory.
|
||||
|
||||
\returns ::NC_EDISKLESS if the file was not created as an inmemory file.
|
||||
|
||||
\returns ::NC_EBADGRPID ncid did not contain the root group id of this
|
||||
file. (NetCDF-4 only).
|
||||
|
||||
<h1>Example</h1>
|
||||
|
||||
Here is an example using nc_close_mem to finish the definitions of a new
|
||||
netCDF dataset named foo.nc, return the final memory,
|
||||
and release its netCDF ID:
|
||||
|
||||
\code
|
||||
#include <netcdf.h>
|
||||
...
|
||||
int status = NC_NOERR;
|
||||
int ncid;
|
||||
NC_memio finalmem;
|
||||
size_t initialsize = 65000;
|
||||
...
|
||||
status = nc_create_mem("foo.nc", NC_NOCLOBBER, initialsize, &ncid);
|
||||
if (status != NC_NOERR) handle_error(status);
|
||||
... create dimensions, variables, attributes
|
||||
status = nc_close_memio(ncid,&finalmem);
|
||||
if (status != NC_NOERR) handle_error(status);
|
||||
\endcode
|
||||
|
||||
*/
|
||||
int
|
||||
nc_close_memio(int ncid, NC_memio* memio)
|
||||
{
|
||||
#ifdef USE_DISKLESS
|
||||
NC* ncp;
|
||||
int stat = NC_check_id(ncid, &ncp);
|
||||
if(stat != NC_NOERR) return stat;
|
||||
|
||||
#ifdef USE_REFCOUNT
|
||||
ncp->refcount--;
|
||||
if(ncp->refcount <= 0)
|
||||
#endif
|
||||
{
|
||||
stat = ncp->dispatch->close(ncid,memio);
|
||||
/* Remove from the nc list */
|
||||
if (!stat)
|
||||
{
|
||||
del_from_NCList(ncp);
|
||||
free_NC(ncp);
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
#else
|
||||
return NC_EINMEMORY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \ingroup datasets
|
||||
Change the fill-value mode to improve write performance.
|
||||
|
||||
@ -1774,7 +1964,7 @@ NC_create(const char *path0, int cmode, size_t initialsz,
|
||||
}
|
||||
|
||||
#ifndef USE_DISKLESS
|
||||
cmode &= (~ NC_DISKLESS); /* Force off */
|
||||
cmode &= (~ (NC_DISKLESS|NC_INMEMORY)); /* Force off */
|
||||
#endif
|
||||
|
||||
#ifdef WINPATH
|
||||
@ -1964,13 +2154,12 @@ NC_open(const char *path0, int cmode, int basepe, size_t *chunksizehintp,
|
||||
|
||||
#ifndef USE_DISKLESS
|
||||
/* Clean up cmode */
|
||||
cmode &= (~ NC_DISKLESS);
|
||||
cmode &= (~ (NC_DISKLESS|NC_INMEMORY));
|
||||
#endif
|
||||
|
||||
inmemory = ((cmode & NC_INMEMORY) == NC_INMEMORY);
|
||||
diskless = ((cmode & NC_DISKLESS) == NC_DISKLESS);
|
||||
|
||||
|
||||
#ifdef WINPATH
|
||||
path = NCpathcvt(path0);
|
||||
#else
|
||||
@ -2195,7 +2384,7 @@ openmagic(struct MagicFile* file)
|
||||
int status = NC_NOERR;
|
||||
if(file->inmemory) {
|
||||
/* Get its length */
|
||||
NC_MEM_INFO* meminfo = (NC_MEM_INFO*)file->parameters;
|
||||
NC_memio* meminfo = (NC_memio*)file->parameters;
|
||||
file->filelen = (long long)meminfo->size;
|
||||
goto done;
|
||||
}
|
||||
@ -2260,7 +2449,7 @@ readmagic(struct MagicFile* file, long pos, char* magic)
|
||||
memset(magic,0,MAGIC_NUMBER_LEN);
|
||||
if(file->inmemory) {
|
||||
char* mempos;
|
||||
NC_MEM_INFO* meminfo = (NC_MEM_INFO*)file->parameters;
|
||||
NC_memio* meminfo = (NC_memio*)file->parameters;
|
||||
if((pos + MAGIC_NUMBER_LEN) > meminfo->size)
|
||||
{status = NC_EDISKLESS; goto done;}
|
||||
mempos = ((char*)meminfo->memory) + pos;
|
||||
|
@ -157,7 +157,7 @@ NC_RO_rename_var(int ncid, int varid, const char *name)
|
||||
*
|
||||
* @param ncid File ID.
|
||||
* @param varid Variable ID.
|
||||
* @param startp Array of start indicies.
|
||||
* @param startp Array of start indices.
|
||||
* @param countp Array of counts.
|
||||
* @param op pointer that gets the data.
|
||||
* @param memtype The type of these data in memory.
|
||||
|
@ -169,9 +169,9 @@ NC_readfile(const char* filename, NCbytes* content)
|
||||
char part[1024];
|
||||
|
||||
#ifdef _MSC_VER
|
||||
stream = NCfopen(filename,"r");
|
||||
#else
|
||||
stream = NCfopen(filename,"rb");
|
||||
#else
|
||||
stream = NCfopen(filename,"r");
|
||||
#endif
|
||||
if(stream == NULL) {ret=errno; goto done;}
|
||||
for(;;) {
|
||||
|
@ -471,7 +471,7 @@ nctypelen(nc_type type)
|
||||
|
||||
/** \internal
|
||||
\ingroup variables
|
||||
Find the length of a type. Redunant over nctypelen() above. */
|
||||
Find the length of a type. Redundant over nctypelen() above. */
|
||||
size_t
|
||||
NC_atomictypelen(nc_type xtype)
|
||||
{
|
||||
@ -769,7 +769,7 @@ nc_free_string(size_t len, char **data)
|
||||
* or any functions which writes data to the file.
|
||||
*
|
||||
* Deflation and shuffline require chunked data. If this function is
|
||||
* called on a variable with contigious data, then the data is changed
|
||||
* called on a variable with contiguous data, then the data is changed
|
||||
* to chunked data, with default chunksizes. Use nc_def_var_chunking()
|
||||
* to tune performance with user-defined chunksizes.
|
||||
*
|
||||
@ -871,7 +871,7 @@ nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, int deflate_le
|
||||
* or any functions which writes data to the file.
|
||||
*
|
||||
* Checksums require chunked data. If this function is called on a
|
||||
* variable with contigious data, then the data is changed to chunked
|
||||
* variable with contiguous data, then the data is changed to chunked
|
||||
* data, with default chunksizes. Use nc_def_var_chunking() to tune
|
||||
* performance with user-defined chunksizes.
|
||||
*
|
||||
|
@ -30,7 +30,7 @@ struct GETodometer {
|
||||
*
|
||||
* @param odom Pointer to odometer.
|
||||
* @param rank
|
||||
* @param start Start indicies.
|
||||
* @param start Start indices.
|
||||
* @param edges Counts.
|
||||
* @param stride Strides.
|
||||
*
|
||||
|
@ -274,7 +274,7 @@ function will write a 1 if the deflate filter is turned on for this
|
||||
variable, and a 0 otherwise. \ref ignored_if_null.
|
||||
|
||||
\param deflate_levelp If the deflate filter is in use for this
|
||||
variable, the deflate_level will be writen here. \ref ignored_if_null.
|
||||
variable, the deflate_level will be written here. \ref ignored_if_null.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
\returns ::NC_ENOTNC4 Not a netCDF-4 file.
|
||||
|
@ -23,7 +23,7 @@ struct PUTodometer {
|
||||
*
|
||||
* @param odom Pointer to odometer.
|
||||
* @param rank
|
||||
* @param start Start indicies.
|
||||
* @param start Start indices.
|
||||
* @param edges Counts.
|
||||
* @param stride Strides.
|
||||
*
|
||||
|
@ -134,7 +134,7 @@ Fortran APIs.
|
||||
\param ncid \ref ncid
|
||||
\param typeid1 Typeid of the VLEN.
|
||||
\param vlen_element Pointer to the element of the VLEN.
|
||||
\param len Lenth of the VLEN element.
|
||||
\param len Length of the VLEN element.
|
||||
\param data VLEN data.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
@ -163,7 +163,7 @@ Fortran APIs.
|
||||
\param ncid \ref ncid
|
||||
\param typeid1 Typeid of the VLEN.
|
||||
\param vlen_element Pointer to the element of the VLEN.
|
||||
\param len Lenth of the VLEN element.
|
||||
\param len Length of the VLEN element.
|
||||
\param data VLEN data.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
|
@ -6,8 +6,7 @@
|
||||
# Ed Hartnett
|
||||
|
||||
# The source files for the HDF4 dispatch layer.
|
||||
SET(libhdf4_SOURCES hdf4attr.c hdf4dim.c hdf4dispatch.c hdf4file.c hdf4func.c
|
||||
hdf4grp.c hdf4type.c hdf4var.c)
|
||||
SET(libhdf4_SOURCES hdf4dispatch.c hdf4file.c hdf4func.c hdf4var.c)
|
||||
|
||||
# Build the HDF4 dispatch layer as a library that will be included in
|
||||
# the netCDF library.
|
||||
|
@ -13,8 +13,7 @@ libnetcdf4_la_CPPFLAGS = ${AM_CPPFLAGS}
|
||||
noinst_LTLIBRARIES = libnchdf4.la
|
||||
|
||||
# The source files.
|
||||
libnchdf4_la_SOURCES = hdf4dispatch.c hdf4attr.c hdf4dim.c hdf4file.c \
|
||||
hdf4grp.c hdf4type.c hdf4var.c hdf4func.c
|
||||
libnchdf4_la_SOURCES = hdf4dispatch.c hdf4file.c hdf4var.c hdf4func.c
|
||||
|
||||
# Package this for cmake build.
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
@ -1,69 +0,0 @@
|
||||
/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying
|
||||
* and redistribution conditions.*/
|
||||
/**
|
||||
* @file
|
||||
* @internal This file handles the HDF4 attribute functions.
|
||||
*
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
|
||||
#include "nc4internal.h"
|
||||
#include "nc.h"
|
||||
#include "hdf4dispatch.h"
|
||||
#include "ncdispatch.h"
|
||||
|
||||
int nc4typelen(nc_type type);
|
||||
|
||||
/**
|
||||
* @internal Not allowed for HDF4.
|
||||
*
|
||||
* @param ncid Ignored.
|
||||
* @param varid Ignored.
|
||||
* @param name Ignored.
|
||||
* @param newname Ignored.
|
||||
*
|
||||
* @return ::NC_EPERM Not allowed for HDF4.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_rename_att(int ncid, int varid, const char *name, const char *newname)
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Not allowed for HDF4.
|
||||
*
|
||||
* @param ncid Ignored.
|
||||
* @param varid Ignored.
|
||||
* @param name Ignored.
|
||||
*
|
||||
* @return ::NC_EPERM Not allowed with HDF4.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_del_att(int ncid, int varid, const char *name)
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Not allowed for HDF4.
|
||||
*
|
||||
* @param ncid Ignored.
|
||||
* @param varid Ignored.
|
||||
* @param name Ignored.
|
||||
* @param file_type Ignored.
|
||||
* @param len Ignored.
|
||||
* @param data Ignored.
|
||||
* @param memtype Ignored.
|
||||
*
|
||||
* @return ::NC_EPERM Not allowed with HDF4.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_put_att(int ncid, int varid, const char *name, nc_type file_type,
|
||||
size_t len, const void *data, nc_type mem_type)
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying
|
||||
* and redistribution conditions.*/
|
||||
/**
|
||||
* @file
|
||||
* @internal This file handles the HDF4 dimension functions.
|
||||
*
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
|
||||
#include "nc4internal.h"
|
||||
#include "nc4dispatch.h"
|
||||
|
||||
/**
|
||||
* @internal Dims cannot be defined for HDF4 files.
|
||||
*
|
||||
* @param ncid Ignored.
|
||||
* @param name Ignored.
|
||||
* @param len Ignored.
|
||||
* @param idp Ignored.
|
||||
*
|
||||
* @return ::NC_EPERM Can't define dims.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_def_dim(int ncid, const char *name, size_t len, int *idp)
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Not allowed for HDF4.
|
||||
*
|
||||
* @param ncid Ignored.
|
||||
* @param dimid Ignored.
|
||||
* @param name Ignored.
|
||||
*
|
||||
* @return ::NC_NEPERM Can't write to HDF4 file.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_rename_dim(int ncid, int dimid, const char *name)
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying
|
||||
* and redistribution conditions.*/
|
||||
/**
|
||||
* @file @internal This file handles groups for the HDF4 dispatch
|
||||
* layer. All functions return ::NC_ENOTNC4.
|
||||
*
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
#include "nc4internal.h"
|
||||
#include "hdf4dispatch.h"
|
||||
|
||||
/**
|
||||
* @internal Create a group. Its ncid is returned in the new_ncid
|
||||
* pointer.
|
||||
*
|
||||
* @param parent_ncid Parent group.
|
||||
* @param name Name of new group.
|
||||
* @param new_ncid Pointer that gets ncid for new group.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_ESTRICTNC3 Classic model in use for this file.
|
||||
* @return ::NC_ENOTNC4 Not a netCDF-4 file.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_def_grp(int parent_ncid, const char *name, int *new_ncid)
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Rename a group.
|
||||
*
|
||||
* @param grpid Group ID.
|
||||
* @param name New name for group.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_ENOTNC4 Not a netCDF-4 file.
|
||||
* @return ::NC_EPERM File opened read-only.
|
||||
* @return ::NC_EBADGRPID Renaming root forbidden.
|
||||
* @return ::NC_EHDFERR HDF5 function returned error.
|
||||
* @return ::NC_ENOMEM Out of memory.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_rename_grp(int grpid, const char *name)
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
||||
|
||||
|
@ -1,309 +0,0 @@
|
||||
/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying
|
||||
* and redistribution conditions.*/
|
||||
/**
|
||||
* @file @internal This file contains the type functions for the HDF4
|
||||
* dispatch layer.
|
||||
*
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
#include "nc4internal.h"
|
||||
#include "nc4dispatch.h"
|
||||
|
||||
#define NUM_ATOMIC_TYPES 13 /**< Number of netCDF atomic types. */
|
||||
|
||||
/* The sizes of types may vary from platform to platform, but within
|
||||
* netCDF files, type sizes are fixed. */
|
||||
#define NC_CHAR_LEN sizeof(char) /**< @internal Size of char. */
|
||||
#define NC_STRING_LEN sizeof(char *) /**< @internal Size of char *. */
|
||||
#define NC_BYTE_LEN 1 /**< @internal Size of byte. */
|
||||
#define NC_SHORT_LEN 2 /**< @internal Size of short. */
|
||||
#define NC_INT_LEN 4 /**< @internal Size of int. */
|
||||
#define NC_FLOAT_LEN 4 /**< @internal Size of float. */
|
||||
#define NC_DOUBLE_LEN 8 /**< @internal Size of double. */
|
||||
#define NC_INT64_LEN 8 /**< @internal Size of int64. */
|
||||
|
||||
/**
|
||||
* @internal Create a compound type.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param size Gets size in bytes of one element of type.
|
||||
* @param name Name of the type.
|
||||
* @param typeidp Gets the type ID.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EMAXNAME Name is too long.
|
||||
* @return ::NC_EBADNAME Name breaks netCDF name rules.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Insert a named field into a compound type.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param name Name of the type.
|
||||
* @param offset Offset of field.
|
||||
* @param field_typeid Field type ID.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EMAXNAME Name is too long.
|
||||
* @return ::NC_EBADNAME Name breaks netCDF name rules.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_insert_compound(int ncid, nc_type typeid1, const char *name, size_t offset,
|
||||
nc_type field_typeid)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Insert a named array into a compound type.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param name Name of the array field.
|
||||
* @param offset Offset in bytes.
|
||||
* @param field_typeid Type of field.
|
||||
* @param ndims Number of dims for field.
|
||||
* @param dim_sizesp Array of dim sizes.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EMAXNAME Name is too long.
|
||||
* @return ::NC_EBADNAME Name breaks netCDF name rules.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
extern int
|
||||
HDF4_insert_array_compound(int ncid, int typeid1, const char *name,
|
||||
size_t offset, nc_type field_typeid,
|
||||
int ndims, const int *dim_sizesp)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Given the ncid, typeid and fieldid, get info about the
|
||||
* field.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param fieldid Field ID.
|
||||
* @param name Gets name of field.
|
||||
* @param offsetp Gets offset of field.
|
||||
* @param field_typeidp Gets field type ID.
|
||||
* @param ndimsp Gets number of dims for this field.
|
||||
* @param dim_sizesp Gets the dim sizes for this field.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name,
|
||||
size_t *offsetp, nc_type *field_typeidp, int *ndimsp,
|
||||
int *dim_sizesp)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Given the typeid and the name, get the fieldid.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param name Name of field.
|
||||
* @param fieldidp Pointer that gets new field ID.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EBADTYPE Type not found.
|
||||
* @return ::NC_EBADFIELD Field not found.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/* Opaque type. */
|
||||
|
||||
/**
|
||||
* @internal Create an opaque type. Provide a size and a name.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param datum_size Size in bytes of a datum.
|
||||
* @param name Name of new vlen type.
|
||||
* @param typeidp Pointer that gets new type ID.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EMAXNAME Name is too long.
|
||||
* @return ::NC_EBADNAME Name breaks netCDF name rules.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_def_opaque(int ncid, size_t datum_size, const char *name,
|
||||
nc_type *typeidp)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Define a variable length type.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param name Name of new vlen type.
|
||||
* @param base_typeid Base type of vlen.
|
||||
* @param typeidp Pointer that gets new type ID.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EMAXNAME Name is too long.
|
||||
* @return ::NC_EBADNAME Name breaks netCDF name rules.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_def_vlen(int ncid, const char *name, nc_type base_typeid,
|
||||
nc_type *typeidp)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Create an enum type. Provide a base type and a name. At
|
||||
* the moment only ints are accepted as base types.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param base_typeid Base type of vlen.
|
||||
* @param name Name of new vlen type.
|
||||
* @param typeidp Pointer that gets new type ID.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EMAXNAME Name is too long.
|
||||
* @return ::NC_EBADNAME Name breaks netCDF name rules.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_def_enum(int ncid, nc_type base_typeid, const char *name,
|
||||
nc_type *typeidp)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal Get enum name from enum value. Name size will be <=
|
||||
* NC_MAX_NAME.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param xtype Type ID.
|
||||
* @param value Value of enum.
|
||||
* @param identifier Gets the identifier for this enum value.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EBADTYPE Type not found.
|
||||
* @return ::NC_EINVAL Invalid type data.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Get information about an enum member: an identifier and
|
||||
* value. Identifier size will be <= NC_MAX_NAME.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param idx Enum member index.
|
||||
* @param identifier Gets the identifier.
|
||||
* @param value Gets the enum value.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EBADTYPE Type not found.
|
||||
* @return ::NC_EINVAL Bad idx.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier,
|
||||
void *value)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Insert a identifier value into an enum type. The value
|
||||
* must fit within the size of the enum type, the identifier size must
|
||||
* be <= NC_MAX_NAME.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param identifier Name of this enum value.
|
||||
* @param value Value of enum.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @return ::NC_EBADTYPE Type not found.
|
||||
* @return ::NC_ETYPDEFINED Type already defined.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_insert_enum(int ncid, nc_type typeid1, const char *identifier,
|
||||
const void *value)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Insert one element into an already allocated vlen array
|
||||
* element.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param vlen_element The VLEN element to insert.
|
||||
* @param len Length of element in bytes.
|
||||
* @param data Element data.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_put_vlen_element(int ncid, int typeid1, void *vlen_element,
|
||||
size_t len, const void *data)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Insert one element into an already allocated vlen array
|
||||
* element.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param typeid1 Type ID.
|
||||
* @param vlen_element The VLEN element to insert.
|
||||
* @param len Length of element in bytes.
|
||||
* @param data Element data.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
HDF4_get_vlen_element(int ncid, int typeid1, const void *vlen_element,
|
||||
size_t *len, void *data)
|
||||
{
|
||||
return NC_ENOTNC4;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
*
|
||||
* @param ncid File ID.
|
||||
* @param varid Variable ID.
|
||||
* @param startp Array of start indicies.
|
||||
* @param startp Array of start indices.
|
||||
* @param countp Array of counts.
|
||||
* @param ip pointer that gets the data.
|
||||
* @param memtype The type of these data after it is read into memory.
|
||||
|
18
libhdf5/CMakeLists.txt
Normal file
18
libhdf5/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
## This is a CMake file, part of Unidata's netCDF package.
|
||||
# Copyright 2018, see the COPYRIGHT file for more information.
|
||||
#
|
||||
# This builds the HDF5 dispatch layer.
|
||||
#
|
||||
# Ed Hartnett
|
||||
|
||||
# The source files for the HDF5 dispatch layer.
|
||||
SET(libnchdf5_SOURCES nc4hdf.c nc4info.c hdf5file.c)
|
||||
# SET(libnchdf5_SOURCES hdf5file.c nc4hdf.c hdf5attr.c hdf5dispatch.c
|
||||
# hdf5var.c hdf5type.c hdf5internal.c hdf5dim.c hdf5grp.c nc4info.c)
|
||||
|
||||
# Build the HDF4 dispatch layer as a library that will be included in
|
||||
# the netCDF library.
|
||||
add_library(netcdfhdf5 OBJECT ${libnchdf5_SOURCES})
|
||||
|
||||
# Remember to package this file for CMake builds.
|
||||
ADD_EXTRA_DIST(${libnchdf5_SOURCES} CMakeLists.txt)
|
27
libhdf5/Makefile.am
Normal file
27
libhdf5/Makefile.am
Normal file
@ -0,0 +1,27 @@
|
||||
# This is part of Unidata's netCDF package. Copyright 2018, see the
|
||||
# COPYRIGHT file for more information.
|
||||
|
||||
# Build the HDF5 dispatch layer.
|
||||
|
||||
# Ed Hartnett
|
||||
|
||||
# Get AM_CPPFLAGS.
|
||||
include $(top_srcdir)/lib_flags.am
|
||||
libnetcdf4_la_CPPFLAGS = ${AM_CPPFLAGS}
|
||||
|
||||
# This is our output. The HDF5 convenience library.
|
||||
noinst_LTLIBRARIES = libnchdf5.la
|
||||
|
||||
# The source files.
|
||||
libnchdf5_la_SOURCES = nc4hdf.c nc4info.c hdf5file.c
|
||||
# libnchdf5_la_SOURCES = nc4hdf.c nc4info.c hdf5file.c hdf5attr.c \
|
||||
# hdf5dispatch.c hdf5var.c hdf5type.c hdf5internal.c hdf5dim.c \
|
||||
# hdf5grp.c
|
||||
|
||||
# Package this for cmake build.
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -16,10 +16,18 @@
|
||||
#include "nc.h"
|
||||
#include "nc4internal.h"
|
||||
#include "nc4dispatch.h"
|
||||
#include <H5DSpublic.h> /* must be after nc4internal.h */
|
||||
#include <H5Fpublic.h>
|
||||
#include "netcdf_mem.h"
|
||||
#ifdef USE_HDF4
|
||||
#include <mfhdf.h>
|
||||
#endif
|
||||
#include <hdf5_hl.h>
|
||||
|
||||
extern int nc4_vararray_add(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var);
|
||||
|
||||
/* From nc4mem.c */
|
||||
extern int NC4_open_image_file(NC_HDF5_FILE_INFO_T* h5);
|
||||
extern int NC4_create_image_file(NC_HDF5_FILE_INFO_T* h5, size_t);
|
||||
extern int NC4_extract_file_image(NC_HDF5_FILE_INFO_T* h5);
|
||||
|
||||
/** @internal When we have open objects at file close, should
|
||||
we log them or print to stdout. Default is to log. */
|
||||
@ -28,7 +36,7 @@
|
||||
#define CD_NELEMS_ZLIB 1 /**< Number of parameters needed for ZLIB filter. */
|
||||
|
||||
/**
|
||||
* @internal Wrap HDF5 allocated memory free operations
|
||||
* @internal Wrap HDF5 allocated memory free operations
|
||||
*
|
||||
* @param memory Pointer to memory to be freed.
|
||||
*
|
||||
@ -102,7 +110,7 @@ NC_findreserved(const char* name)
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Given an HDF5 type, set a pointer to netcdf type.
|
||||
* @internal Given an HDF5 type, set a pointer to netcdf type.
|
||||
*
|
||||
* @param h5 Pointer to HDF5 file info struct.
|
||||
* @param native_typeid HDF5 type ID.
|
||||
@ -490,7 +498,7 @@ exit:
|
||||
static const int ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_64BIT_OFFSET);
|
||||
|
||||
/** @internal These flags may not be set for create. */
|
||||
static const int ILLEGAL_CREATE_FLAGS = (NC_NOWRITE|NC_MMAP|NC_INMEMORY|NC_64BIT_OFFSET|NC_CDF5);
|
||||
static const int ILLEGAL_CREATE_FLAGS = (NC_NOWRITE|NC_MMAP|NC_64BIT_OFFSET|NC_CDF5);
|
||||
|
||||
extern void reportopenobjects(int log, hid_t);
|
||||
|
||||
@ -524,7 +532,7 @@ static void dumpopenobjects(NC_HDF5_FILE_INFO_T* h5);
|
||||
|
||||
/**
|
||||
* @internal This function will write all changed metadata, and
|
||||
* (someday) reread all metadata from the file.
|
||||
* (someday) reread all metadata from the file.
|
||||
*
|
||||
* @param h5 Pointer to HDF5 file info struct.
|
||||
*
|
||||
@ -581,16 +589,17 @@ sync_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
|
||||
/**
|
||||
* @internal This function will free all allocated metadata memory,
|
||||
* and close the HDF5 file. The group that is passed in must be the
|
||||
* root group of the file.
|
||||
* root group of the file.
|
||||
*
|
||||
* @param h5 Pointer to HDF5 file info struct.
|
||||
* @param abort True if this is an abort.
|
||||
* @param extractmem True if we need to extract and save final inmemory
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
static int
|
||||
close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort)
|
||||
close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort, int extractmem)
|
||||
{
|
||||
int retval = NC_NOERR;
|
||||
|
||||
@ -628,9 +637,19 @@ close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort)
|
||||
MPI_Info_free(&h5->info);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if(h5->fileinfo) free(h5->fileinfo);
|
||||
|
||||
|
||||
/* Check to see if this is an in-memory file and we want to get its
|
||||
final content
|
||||
*/
|
||||
if(extractmem) {
|
||||
/* File must be read/write */
|
||||
if(!h5->no_write) {
|
||||
retval = NC4_extract_file_image(h5);
|
||||
}
|
||||
}
|
||||
|
||||
if (H5Fclose(h5->hdfid) < 0)
|
||||
{
|
||||
dumpopenobjects(h5);
|
||||
@ -647,7 +666,7 @@ static void
|
||||
dumpopenobjects(NC_HDF5_FILE_INFO_T* h5)
|
||||
{
|
||||
int nobjs;
|
||||
|
||||
|
||||
nobjs = H5Fget_obj_count(h5->hdfid, H5F_OBJ_ALL);
|
||||
/* Apparently we can get an error even when nobjs == 0 */
|
||||
if(nobjs < 0) {
|
||||
@ -706,9 +725,9 @@ static const char* NC_RESERVED_ATT_LIST[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* @internal Define the subset of the reserved list that is readable
|
||||
* by name only
|
||||
* by name only
|
||||
*/
|
||||
static const char* NC_RESERVED_SPECIAL_LIST[] = {
|
||||
ISNETCDF4ATT,
|
||||
@ -749,8 +768,8 @@ static const int nc_type_size_g[NUM_TYPES] = {sizeof(char), sizeof(char), sizeof
|
||||
|
||||
/**
|
||||
* Set chunk cache size. Only affects files opened/created *after* it
|
||||
* is called.
|
||||
*
|
||||
* is called.
|
||||
*
|
||||
* @param size Size in bytes to set cache.
|
||||
* @param nelems Number of elements to hold in cache.
|
||||
* @param preemption Premption stragety (between 0 and 1).
|
||||
@ -772,7 +791,7 @@ nc_set_chunk_cache(size_t size, size_t nelems, float preemption)
|
||||
|
||||
/**
|
||||
* Get chunk cache size. Only affects files opened/created *after* it
|
||||
* is called.
|
||||
* is called.
|
||||
*
|
||||
* @param sizep Pointer that gets size in bytes to set cache.
|
||||
* @param nelemsp Pointer that gets number of elements to hold in cache.
|
||||
@ -877,8 +896,8 @@ nc4typelen(nc_type type)
|
||||
*
|
||||
* @param path The file name of the new file.
|
||||
* @param cmode The creation mode flag.
|
||||
* @param comm MPI communicator (parallel IO only).
|
||||
* @param info MPI info (parallel IO only).
|
||||
* @param initialsz The proposed initial file size (advisory)
|
||||
* @param parameters extra parameter info (like MPI communicator)
|
||||
* @param nc Pointer to an instance of NC.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
@ -889,25 +908,47 @@ nc4typelen(nc_type type)
|
||||
* @author Ed Hartnett, Dennis Heimbigner
|
||||
*/
|
||||
static int
|
||||
nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
NC *nc)
|
||||
nc4_create_file(const char *path, int cmode, size_t initialsz, void* parameters, NC *nc)
|
||||
{
|
||||
hid_t fcpl_id, fapl_id = -1;
|
||||
unsigned flags;
|
||||
FILE *fp;
|
||||
int retval = NC_NOERR;
|
||||
NC_HDF5_FILE_INFO_T* nc4_info = NULL;
|
||||
|
||||
#ifdef USE_PARALLEL4
|
||||
NC_MPI_INFO* mpiinfo = NULL;
|
||||
MPI_Comm comm;
|
||||
MPI_Info info;
|
||||
int comm_duped = 0; /* Whether the MPI Communicator was duplicated */
|
||||
int info_duped = 0; /* Whether the MPI Info object was duplicated */
|
||||
#else /* !USE_PARALLEL4 */
|
||||
int persist = 0; /* Should diskless try to persist its data into file?*/
|
||||
#endif
|
||||
#endif /* !USE_PARALLEL4 */
|
||||
|
||||
assert(nc && path);
|
||||
LOG((3, "%s: path %s mode 0x%x", __func__, path, cmode));
|
||||
|
||||
if(cmode & NC_DISKLESS)
|
||||
/* Add necessary structs to hold netcdf-4 file data. */
|
||||
if ((retval = nc4_nc4f_list_add(nc, path, (NC_WRITE | cmode))))
|
||||
BAIL(retval);
|
||||
|
||||
nc4_info = NC4_DATA(nc);
|
||||
assert(nc4_info && nc4_info->root_grp);
|
||||
|
||||
nc4_info->mem.inmemory = (cmode & NC_INMEMORY) == NC_INMEMORY;
|
||||
nc4_info->mem.diskless = (cmode & NC_DISKLESS) == NC_DISKLESS;
|
||||
nc4_info->mem.created = 1;
|
||||
nc4_info->mem.initialsize = initialsz;
|
||||
|
||||
if(nc4_info->mem.inmemory && parameters)
|
||||
nc4_info->mem.memio = *(NC_memio*)parameters;
|
||||
#ifdef USE_PARALLEL4
|
||||
else if(parameters) {
|
||||
mpiinfo = (NC_MPI_INFO *)parameters;
|
||||
comm = mpiinfo->comm;
|
||||
info = mpiinfo->info;
|
||||
}
|
||||
#endif
|
||||
if(nc4_info->mem.diskless)
|
||||
flags = H5F_ACC_TRUNC;
|
||||
else if(cmode & NC_NOCLOBBER)
|
||||
flags = H5F_ACC_EXCL;
|
||||
@ -915,25 +956,19 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
flags = H5F_ACC_TRUNC;
|
||||
|
||||
/* If this file already exists, and NC_NOCLOBBER is specified,
|
||||
return an error. */
|
||||
if (cmode & NC_DISKLESS) {
|
||||
#ifndef USE_PARALLEL4
|
||||
if(cmode & NC_WRITE)
|
||||
persist = 1;
|
||||
#endif
|
||||
return an error (unless diskless|inmemory) */
|
||||
if (nc4_info->mem.diskless) {
|
||||
if((cmode & NC_WRITE) && (cmode & NC_NOCLOBBER) == 0)
|
||||
nc4_info->mem.persist = 1;
|
||||
} else if (nc4_info->mem.inmemory) {
|
||||
/* ok */
|
||||
} else if ((cmode & NC_NOCLOBBER) && (fp = fopen(path, "r"))) {
|
||||
fclose(fp);
|
||||
return NC_EEXIST;
|
||||
}
|
||||
|
||||
/* Add necessary structs to hold netcdf-4 file data. */
|
||||
if ((retval = nc4_nc4f_list_add(nc, path, (NC_WRITE | cmode))))
|
||||
BAIL(retval);
|
||||
nc4_info = NC4_DATA(nc);
|
||||
assert(nc4_info && nc4_info->root_grp);
|
||||
|
||||
/* Need this access plist to control how HDF5 handles open objects
|
||||
* on file close. (Setting H5F_CLOSE_SEMI will cause H5Fclose to
|
||||
* on file close. Setting H5F_CLOSE_SEMI will cause H5Fclose to
|
||||
* fail if there are any open objects in the file. */
|
||||
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
@ -943,8 +978,7 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
#ifdef USE_PARALLEL4
|
||||
/* If this is a parallel file create, set up the file creation
|
||||
property list. */
|
||||
if ((cmode & NC_MPIIO) || (cmode & NC_MPIPOSIX))
|
||||
{
|
||||
if ((cmode & NC_MPIIO) || (cmode & NC_MPIPOSIX)) {
|
||||
nc4_info->parallel = NC_TRUE;
|
||||
if (cmode & NC_MPIIO) /* MPI/IO */
|
||||
{
|
||||
@ -986,7 +1020,7 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
}
|
||||
#else /* only set cache for non-parallel... */
|
||||
if(cmode & NC_DISKLESS) {
|
||||
if (H5Pset_fapl_core(fapl_id, 4096, persist))
|
||||
if (H5Pset_fapl_core(fapl_id, 4096, nc4_info->mem.persist))
|
||||
BAIL(NC_EDISKLESS);
|
||||
}
|
||||
if (H5Pset_cache(fapl_id, 0, nc4_chunk_cache_nelems, nc4_chunk_cache_size,
|
||||
@ -1029,7 +1063,21 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
|
||||
H5Pset_coll_metadata_write(fapl_id, 1);
|
||||
#endif
|
||||
|
||||
if ((nc4_info->hdfid = H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0)
|
||||
if(nc4_info->mem.inmemory) {
|
||||
#if 0
|
||||
if(nc4_info->mem.memio.size == 0)
|
||||
nc4_info->memio.size = DEFAULT_CREATE_MEMSIZE; /* last ditch fix */
|
||||
if(nc4_info->memio.memory == NULL) { /* last ditch fix */
|
||||
nc4_info->memio.memory = malloc(nc4_info->memio.size);
|
||||
if(nc4_info->memio.memory == NULL)
|
||||
BAIL(NC_ENOMEM);
|
||||
}
|
||||
assert(nc4_info->memio.size > 0 && nc4_info->memio.memory != NULL);
|
||||
#endif
|
||||
retval = NC4_create_image_file(nc4_info,initialsz);
|
||||
if(retval)
|
||||
BAIL(retval);
|
||||
} else if ((nc4_info->hdfid = H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0)
|
||||
/*Change the return error from NC_EFILEMETADATA to
|
||||
System error EACCES because that is the more likely problem */
|
||||
BAIL(EACCES);
|
||||
@ -1058,7 +1106,7 @@ exit: /*failure exit*/
|
||||
#endif
|
||||
if (fapl_id != H5P_DEFAULT) H5Pclose(fapl_id);
|
||||
if(!nc4_info) return retval;
|
||||
close_netcdf4_file(nc4_info,1); /* treat like abort */
|
||||
close_netcdf4_file(nc4_info,1,0); /* treat like abort */
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -1086,22 +1134,12 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
|
||||
size_t *chunksizehintp, int use_parallel, void *parameters,
|
||||
NC_Dispatch *dispatch, NC* nc_file)
|
||||
{
|
||||
MPI_Comm comm = MPI_COMM_WORLD;
|
||||
MPI_Info info = MPI_INFO_NULL;
|
||||
int res;
|
||||
|
||||
assert(nc_file && path);
|
||||
|
||||
LOG((1, "%s: path %s cmode 0x%x comm %d info %d",
|
||||
__func__, path, cmode, comm, info));
|
||||
|
||||
#ifdef USE_PARALLEL4
|
||||
if (parameters)
|
||||
{
|
||||
comm = ((NC_MPI_INFO *)parameters)->comm;
|
||||
info = ((NC_MPI_INFO *)parameters)->info;
|
||||
}
|
||||
#endif /* USE_PARALLEL4 */
|
||||
LOG((1, "%s: path %s cmode 0x%x parameters %p",
|
||||
__func__, path, cmode, parameters));
|
||||
|
||||
/* If this is our first file, turn off HDF5 error messages. */
|
||||
if (!nc4_hdf5_initialized)
|
||||
@ -1144,7 +1182,7 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
|
||||
|
||||
nc_file->int_ncid = nc_file->ext_ncid;
|
||||
|
||||
res = nc4_create_file(path, cmode, comm, info, nc_file);
|
||||
res = nc4_create_file(path, cmode, initialsz, parameters, nc_file);
|
||||
|
||||
done:
|
||||
return res;
|
||||
@ -1275,7 +1313,7 @@ exit:
|
||||
|
||||
/**
|
||||
* @internal This function reads the hacked in coordinates attribute I
|
||||
* use for multi-dimensional coordinates.
|
||||
* use for multi-dimensional coordinates.
|
||||
*
|
||||
* @param grp Group info pointer.
|
||||
* @param var Var info pointer.
|
||||
@ -1354,7 +1392,7 @@ dimscale_visitor(hid_t did, unsigned dim, hid_t dsid,
|
||||
/**
|
||||
* @internal Given an HDF5 type, set a pointer to netcdf type_info struct,
|
||||
* either an existing one (for user-defined types) or a newly created
|
||||
* one.
|
||||
* one.
|
||||
*
|
||||
* @param h5 Pointer to HDF5 file info struct.
|
||||
* @param datasetid HDF5 dataset ID.
|
||||
@ -1802,13 +1840,13 @@ read_type(NC_GRP_INFO_T *grp, hid_t hdf_typeid, char *type_name)
|
||||
* @internal This function is called by read_dataset(), (which is called
|
||||
* by nc4_rec_read_metadata()) when a netCDF variable is found in the
|
||||
* file. This function reads in all the metadata about the var,
|
||||
* including the attributes.
|
||||
* including the attributes.
|
||||
*
|
||||
* @param grp Pointer to group info struct.
|
||||
* @param datasetid HDF5 dataset ID.
|
||||
* @param obj_name Name of the HDF5 object to read.
|
||||
* @param ndims Number of dimensions.
|
||||
* @param dim
|
||||
* @param dim
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
@ -2073,7 +2111,7 @@ exit:
|
||||
/**
|
||||
* @internal This function is called by nc4_rec_read_metadata to read
|
||||
* all the group level attributes (the NC_GLOBAL atts for this
|
||||
* group).
|
||||
* group).
|
||||
*
|
||||
* @param grp Pointer to group info struct.
|
||||
*
|
||||
@ -2147,7 +2185,7 @@ exit:
|
||||
/**
|
||||
* @internal This function is called when nc4_rec_read_metadata
|
||||
* encounters an HDF5 dataset when reading a file.
|
||||
*
|
||||
*
|
||||
* @param grp Pointer to group info struct.
|
||||
* @param datasetid HDF5 dataset ID.
|
||||
* @param obj_name Object name.
|
||||
@ -2466,7 +2504,7 @@ exit:
|
||||
/**
|
||||
* @internal Open a netcdf-4 file. Things have already been kicked off
|
||||
* in ncfunc.c in nc_open, but here the netCDF-4 part of opening a
|
||||
* file is handled.
|
||||
* file is handled.
|
||||
*
|
||||
* @param path The file name of the new file.
|
||||
* @param mode The open mode flag.
|
||||
@ -2480,27 +2518,47 @@ static int
|
||||
nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
|
||||
{
|
||||
hid_t fapl_id = H5P_DEFAULT;
|
||||
unsigned flags = (mode & NC_WRITE) ?
|
||||
H5F_ACC_RDWR : H5F_ACC_RDONLY;
|
||||
int retval;
|
||||
unsigned flags;
|
||||
NC_HDF5_FILE_INFO_T* nc4_info = NULL;
|
||||
int inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
|
||||
NC_MEM_INFO* meminfo = (NC_MEM_INFO*)parameters;
|
||||
|
||||
#ifdef USE_PARALLEL4
|
||||
NC_MPI_INFO* mpiinfo = (NC_MPI_INFO*)parameters;
|
||||
int comm_duped = 0; /* Whether the MPI Communicator was duplicated */
|
||||
int info_duped = 0; /* Whether the MPI Info object was duplicated */
|
||||
#endif /* !USE_PARALLEL4 */
|
||||
NC_MPI_INFO* mpiinfo = NULL;
|
||||
int comm_duped = 0; /* Whether the MPI Communicator was duplicated */
|
||||
int info_duped = 0; /* Whether the MPI Info object was duplicated */
|
||||
#endif
|
||||
|
||||
LOG((3, "%s: path %s mode %d", __func__, path, mode));
|
||||
assert(path && nc);
|
||||
|
||||
flags = (mode & NC_WRITE) ? H5F_ACC_RDWR : H5F_ACC_RDONLY;
|
||||
|
||||
/* Add necessary structs to hold netcdf-4 file data. */
|
||||
if ((retval = nc4_nc4f_list_add(nc, path, mode)))
|
||||
BAIL(retval);
|
||||
nc4_info = NC4_DATA(nc);
|
||||
assert(nc4_info && nc4_info->root_grp);
|
||||
|
||||
nc4_info->mem.inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
|
||||
nc4_info->mem.diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
|
||||
if(nc4_info->mem.inmemory) {
|
||||
NC_memio* memparams = NULL;
|
||||
if(parameters == NULL)
|
||||
BAIL(NC_EINMEMORY);
|
||||
memparams = (NC_memio*)parameters;
|
||||
nc4_info->mem.memio = *memparams; /* keep local copy */
|
||||
/* As a safeguard, if !locked and NC_WRITE is set,
|
||||
then we must take control of the incoming memory */
|
||||
nc4_info->mem.locked = (nc4_info->mem.memio.flags & NC_MEMIO_LOCKED) == NC_MEMIO_LOCKED;
|
||||
if(!nc4_info->mem.locked && ((mode & NC_WRITE) == NC_WRITE)) {
|
||||
memparams->memory = NULL;
|
||||
}
|
||||
#ifdef USE_PARALLEL4
|
||||
} else {
|
||||
mpiinfo = (NC_MPI_INFO*)parameters;
|
||||
#endif /* !USE_PARALLEL4 */
|
||||
}
|
||||
|
||||
/* Need this access plist to control how HDF5 handles open objects
|
||||
* on file close. (Setting H5F_CLOSE_SEMI will cause H5Fclose to
|
||||
* fail if there are any open objects in the file. */
|
||||
@ -2568,12 +2626,13 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
|
||||
#ifdef HDF5_HAS_COLL_METADATA_OPS
|
||||
H5Pset_all_coll_metadata_ops(fapl_id, 1 );
|
||||
#endif
|
||||
if(inmemory) {
|
||||
if((nc4_info->hdfid = H5LTopen_file_image(meminfo->memory,meminfo->size,
|
||||
H5LT_FILE_IMAGE_DONT_COPY|H5LT_FILE_IMAGE_DONT_RELEASE
|
||||
)) < 0)
|
||||
if(nc4_info->mem.inmemory) {
|
||||
/* validate */
|
||||
if(nc4_info->mem.memio.size == 0 || nc4_info->mem.memio.memory == NULL)
|
||||
BAIL(NC_INMEMORY);
|
||||
retval = NC4_open_image_file(nc4_info);
|
||||
if(retval)
|
||||
BAIL(NC_EHDFERR);
|
||||
nc4_info->no_write = NC_TRUE;
|
||||
} else if ((nc4_info->hdfid = H5Fopen(path, flags, fapl_id)) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
|
||||
@ -2614,7 +2673,7 @@ exit:
|
||||
#endif
|
||||
if (fapl_id != H5P_DEFAULT) H5Pclose(fapl_id);
|
||||
if (!nc4_info) return retval;
|
||||
close_netcdf4_file(nc4_info,1); /* treat like abort*/
|
||||
close_netcdf4_file(nc4_info,1,0); /* treat like abort*/
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -2695,7 +2754,7 @@ done:
|
||||
* only when a dataset is created. Whereas in netcdf, you first create
|
||||
* the variable and then (optionally) specify the fill value. To
|
||||
* accomplish this in HDF5 I have to delete the dataset, and recreate
|
||||
* it, with the fill value specified.
|
||||
* it, with the fill value specified.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param fillmode File mode.
|
||||
@ -2736,7 +2795,7 @@ NC4_set_fill(int ncid, int fillmode, int *old_modep)
|
||||
|
||||
/**
|
||||
* @internal Put the file back in redef mode. This is done
|
||||
* automatically for netcdf-4 files, if the user forgets.
|
||||
* automatically for netcdf-4 files, if the user forgets.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
*
|
||||
@ -2775,7 +2834,7 @@ NC4_redef(int ncid)
|
||||
|
||||
/**
|
||||
* @internal For netcdf-4 files, this just calls nc_enddef, ignoring
|
||||
* the extra parameters.
|
||||
* the extra parameters.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param h_minfree Ignored for netCDF-4 files.
|
||||
@ -2798,7 +2857,7 @@ NC4__enddef(int ncid, size_t h_minfree, size_t v_align,
|
||||
|
||||
/**
|
||||
* @internal Take the file out of define mode. This is called
|
||||
* automatically for netcdf-4 files, if the user forgets.
|
||||
* automatically for netcdf-4 files, if the user forgets.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
*
|
||||
@ -2872,7 +2931,7 @@ NC4_sync(int ncid)
|
||||
* created and is still in define mode, the dataset is deleted. If
|
||||
* define mode was entered by a call to nc_redef, the netCDF dataset
|
||||
* is restored to its state before definition mode was entered and the
|
||||
* dataset is closed.
|
||||
* dataset is closed.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
*
|
||||
@ -2905,7 +2964,7 @@ NC4_abort(int ncid)
|
||||
|
||||
/* Free any resources the netcdf-4 library has for this file's
|
||||
* metadata. */
|
||||
if ((retval = close_netcdf4_file(nc4_info, 1)))
|
||||
if ((retval = close_netcdf4_file(nc4_info, 1, 0)))
|
||||
return retval;
|
||||
|
||||
/* Delete the file, if we should. */
|
||||
@ -2917,15 +2976,60 @@ NC4_abort(int ncid)
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Close the netcdf file, writing any changes first.
|
||||
* @internal Close the netcdf file, writing any changes first.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param params any extra parameters in/out of close
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
NC4_close(int ncid)
|
||||
NC4_close(int ncid, void* params)
|
||||
{
|
||||
NC_GRP_INFO_T *grp;
|
||||
NC *nc;
|
||||
NC_HDF5_FILE_INFO_T *h5;
|
||||
int retval;
|
||||
int inmemory;
|
||||
|
||||
LOG((1, "%s: ncid 0x%x", __func__, ncid));
|
||||
|
||||
/* Find our metadata for this file. */
|
||||
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
||||
return retval;
|
||||
|
||||
assert(nc && h5 && grp);
|
||||
|
||||
/* This must be the root group. */
|
||||
if (grp->parent)
|
||||
return NC_EBADGRPID;
|
||||
|
||||
inmemory = ((h5->cmode & NC_INMEMORY) == NC_INMEMORY);
|
||||
|
||||
/* Call the nc4 close. */
|
||||
if ((retval = close_netcdf4_file(grp->nc4_info, 0, (inmemory?1:0))))
|
||||
return retval;
|
||||
if(inmemory && params != NULL) {
|
||||
NC_memio* memio = (NC_memio*)params;
|
||||
*memio = h5->mem.memio;
|
||||
}
|
||||
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Close an in-memory netcdf file, writing any changes first.
|
||||
*
|
||||
* @param ncid File and group ID.
|
||||
* @param sizep ptr into which the final size is stored
|
||||
* @param memp ptr into which the final memory is stored
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
int
|
||||
NC4_close_mem(int ncid, size_t* sizep, void** memp)
|
||||
{
|
||||
NC_GRP_INFO_T *grp;
|
||||
NC *nc;
|
||||
@ -2944,10 +3048,15 @@ NC4_close(int ncid)
|
||||
if (grp->parent)
|
||||
return NC_EBADGRPID;
|
||||
|
||||
/* Call the nc4 close. */
|
||||
if ((retval = close_netcdf4_file(grp->nc4_info, 0)))
|
||||
/* If the file is not an in-memory file, then treat like normal close */
|
||||
if((h5->cmode & NC_INMEMORY) == 0)
|
||||
return NC4_close(ncid,NULL);
|
||||
|
||||
/* Call the nc4 close and extract memory */
|
||||
if ((retval = close_netcdf4_file(grp->nc4_info, 0, 1)))
|
||||
return retval;
|
||||
|
||||
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
@ -3022,7 +3131,7 @@ NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal This function will do the enddef stuff for a netcdf-4 file.
|
||||
* @internal This function will do the enddef stuff for a netcdf-4 file.
|
||||
*
|
||||
* @param h5 Pointer to HDF5 file info struct.
|
||||
*
|
||||
@ -3047,4 +3156,3 @@ nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
|
||||
|
||||
return sync_netcdf4_file(h5);
|
||||
}
|
||||
|
@ -647,7 +647,7 @@ set_par_access(NC_HDF5_FILE_INFO_T *h5, NC_VAR_INFO_T *var, hid_t xfer_plistid)
|
||||
* @param nc Pointer to the file NC struct.
|
||||
* @param ncid File ID.
|
||||
* @param varid Variable ID.
|
||||
* @param startp Array of start indicies.
|
||||
* @param startp Array of start indices.
|
||||
* @param countp Array of counts.
|
||||
* @param mem_nc_type The type of the data in memory.
|
||||
* @param is_long True only if NC_LONG is the memory type.
|
||||
@ -979,7 +979,7 @@ exit:
|
||||
* @param nc Pointer to the file NC struct.
|
||||
* @param ncid File ID.
|
||||
* @param varid Variable ID.
|
||||
* @param startp Array of start indicies.
|
||||
* @param startp Array of start indices.
|
||||
* @param countp Array of counts.
|
||||
* @param mem_nc_type The type of the data in memory. (Convert to this
|
||||
* type from file type.)
|
||||
@ -2965,7 +2965,7 @@ nc4_convert_type(const void *src, void *dest,
|
||||
*cp1++ = *cp++;
|
||||
break;
|
||||
default:
|
||||
LOG((0, "%s: Uknown destination type.", __func__));
|
||||
LOG((0, "%s: Unknown destination type.", __func__));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3932,7 +3932,7 @@ nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
|
||||
However, here that is incorrect because it will find the dimid 0 always
|
||||
(if any dimensions were defined). Except that when dimscale dimids have
|
||||
been defined, one or more of the values in var->dimids will have a
|
||||
legitmate value.
|
||||
legitimate value.
|
||||
The solution I choose is to modify nc4_var_list_add to initialize dimids to
|
||||
illegal values (-1). This is another example of the problems with dimscales.
|
||||
*/
|
||||
@ -4082,7 +4082,7 @@ nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
|
||||
*
|
||||
* @param h5 Pointer to HDF5 file info struct.
|
||||
* @param xtype NetCDF type ID.
|
||||
* @param len Pointer that gets lenght in bytes.
|
||||
* @param len Pointer that gets length in bytes.
|
||||
*
|
||||
* @returns NC_NOERR No error.
|
||||
* @returns NC_EBADTYPE Type not found
|
||||
@ -4254,7 +4254,7 @@ reportobject(int uselog, hid_t id, unsigned int type)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fprintf(stderr,"Type = %s(%lld) name='%s'",typename,(long long)id,name);
|
||||
fprintf(stderr,"Type = %s(%lld) name='%s'",typename,printid,name);
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,8 @@ SET(liblib_LIBS dispatch netcdf3)
|
||||
|
||||
IF(USE_HDF5 OR USE_NETCDF4)
|
||||
SET(liblib_LIBS ${liblib_LIBS} netcdf4)
|
||||
SET(liblib_LIBS ${liblib_LIBS} netcdfhdf5)
|
||||
|
||||
ENDIF()
|
||||
|
||||
IF(USE_PNETCDF)
|
||||
|
@ -40,11 +40,17 @@ AM_CPPFLAGS += -I${top_srcdir}/libsrcp
|
||||
libnetcdf_la_LIBADD += ${top_builddir}/libsrcp/libnetcdfp.la
|
||||
endif # USE_PNETCDF
|
||||
|
||||
# + hdf5
|
||||
if USE_NETCDF4
|
||||
AM_CPPFLAGS += -I${top_srcdir}/libhdf5
|
||||
libnetcdf_la_LIBADD += ${top_builddir}/libhdf5/libnchdf5.la
|
||||
endif # USE_NETCDF4
|
||||
|
||||
# + hdf4
|
||||
if USE_HDF4
|
||||
AM_CPPFLAGS += -I${top_srcdir}/libhdf4
|
||||
libnetcdf_la_LIBADD += ${top_builddir}/libhdf4/libnchdf4.la
|
||||
endif # USE_PNETCDF
|
||||
endif # USE_HDF4
|
||||
|
||||
# + dap
|
||||
if ENABLE_DAP
|
||||
|
@ -56,6 +56,7 @@ IF(HAVE_M4)
|
||||
FILE(GLOB libsrc_MANPAGE ${CMAKE_SOURCE_DIR}/docs/netcdf.m4)
|
||||
FILE(COPY ${libsrc_MANPAGE} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
IF(NOT MSVC)
|
||||
ADD_CUSTOM_TARGET(manpage ALL
|
||||
|
||||
COMMAND ${NC_M4} ${ARGS_MANPAGE} '${CMAKE_CURRENT_BINARY_DIR}/netcdf.m4' > '${CMAKE_CURRENT_BINARY_DIR}/netcdf.3'
|
||||
@ -63,4 +64,6 @@ IF(HAVE_M4)
|
||||
)
|
||||
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/netcdf.3 DESTINATION "share/man/man3" COMPONENT documentation)
|
||||
ENDIF(NOT MSVC)
|
||||
|
||||
ENDIF()
|
||||
|
@ -834,7 +834,7 @@ void driver2()
|
||||
{
|
||||
for (j=0; j<8; ++j) /*------------------------ for each input bit, */
|
||||
{
|
||||
for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */
|
||||
for (m=1; m<8; ++m) /*------------ for several possible initvals, */
|
||||
{
|
||||
for (l=0; l<HASHSTATE; ++l)
|
||||
e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0);
|
||||
|
436
libsrc/memio.c
436
libsrc/memio.c
@ -2,36 +2,39 @@
|
||||
* Copyright 1996, University Corporation for Atmospheric Research
|
||||
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
#if defined (_WIN32) || defined (_WIN64)
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#include <io.h>
|
||||
#define lseek64 lseek
|
||||
#endif
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifdef _MSC_VER /* Microsoft Compilers */
|
||||
#include <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef _MSC_VER /* Microsoft Compilers */
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#include <io.h>
|
||||
#define access(path,mode) _access(path,mode)
|
||||
#endif
|
||||
|
||||
#include "ncdispatch.h"
|
||||
#include "nc3internal.h"
|
||||
#include "netcdf_mem.h"
|
||||
#include "ncwinpath.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
@ -73,15 +76,33 @@
|
||||
#undef X_ALIGN
|
||||
#endif
|
||||
|
||||
#undef REALLOCBUG
|
||||
#ifdef REALLOCBUG
|
||||
/* There is some kind of realloc bug that I cannot solve yet */
|
||||
#define reallocx(m,new,old) realloc(m,new)
|
||||
#else
|
||||
static void*
|
||||
reallocx(void* mem, size_t newsize, size_t oldsize)
|
||||
{
|
||||
void* m = malloc(newsize);
|
||||
memcpy(m,mem,oldsize);
|
||||
return m;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private data for memio */
|
||||
|
||||
typedef struct NCMEMIO {
|
||||
int locked; /* => we cannot realloc */
|
||||
int locked; /* => we cannot realloc or free*/
|
||||
int modified; /* => we realloc'd memory at least once */
|
||||
int persist; /* => save to a file; triggered by NC_WRITE */
|
||||
char* memory;
|
||||
off_t alloc;
|
||||
off_t size;
|
||||
off_t pos;
|
||||
size_t alloc;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
/* Convenience flags */
|
||||
int diskless;
|
||||
int inmemory; /* assert(inmemory iff !diskless */
|
||||
} NCMEMIO;
|
||||
|
||||
/* Forward */
|
||||
@ -92,25 +113,28 @@ static int memio_sync(ncio *const nciop);
|
||||
static int memio_filesize(ncio* nciop, off_t* filesizep);
|
||||
static int memio_pad_length(ncio* nciop, off_t length);
|
||||
static int memio_close(ncio* nciop, int);
|
||||
static int readfile(const char* path, NC_memio*);
|
||||
static int writefile(const char* path, NCMEMIO*);
|
||||
static int fileiswriteable(const char* path);
|
||||
|
||||
/* Mnemonic */
|
||||
#define DOOPEN 1
|
||||
|
||||
static long pagesize = 0;
|
||||
static size_t pagesize = 0;
|
||||
|
||||
/*! Create a new ncio struct to hold info about the file. */
|
||||
static int memio_new(const char* path, int ioflags, off_t initialsize, void* memory, ncio** nciopp, NCMEMIO** memiop)
|
||||
static int
|
||||
memio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEMIO** memiop)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
ncio* nciop = NULL;
|
||||
NCMEMIO* memio = NULL;
|
||||
off_t minsize = initialsize;
|
||||
int inmemory = (fIsSet(ioflags,NC_INMEMORY));
|
||||
size_t minsize = (size_t)initialsize;
|
||||
|
||||
/* use asserts because this is an internal function */
|
||||
assert(fIsSet(ioflags,NC_INMEMORY));
|
||||
assert(memiop != NULL && nciopp != NULL);
|
||||
assert(path != NULL || (memory != NULL && initialsize > 0));
|
||||
assert(!inmemory || (memory != NULL && initialsize > 0));
|
||||
assert(path != NULL);
|
||||
|
||||
if(pagesize == 0) {
|
||||
#if defined (_WIN32) || defined(_WIN64)
|
||||
@ -118,22 +142,20 @@ static int memio_new(const char* path, int ioflags, off_t initialsize, void* mem
|
||||
GetSystemInfo (&info);
|
||||
pagesize = info.dwPageSize;
|
||||
#elif defined HAVE_SYSCONF
|
||||
pagesize = sysconf(_SC_PAGE_SIZE);
|
||||
long pgval = -1;
|
||||
pgval = sysconf(_SC_PAGE_SIZE);
|
||||
if(pgval < 0) {
|
||||
status = NC_EIO;
|
||||
goto fail;
|
||||
}
|
||||
pagesize = (size_t)pgval;
|
||||
#elif defined HAVE_GETPAGESIZE
|
||||
pagesize = getpagesize();
|
||||
pagesize = (size_t)getpagesize();
|
||||
#else
|
||||
pagesize = 4096; /* good guess */
|
||||
pagesize = 4096; /* good guess */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We need to catch errors.
|
||||
sysconf, at least, can return a negative value
|
||||
when there is an error. */
|
||||
if(pagesize < 0) {
|
||||
status = NC_EIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* Always force the allocated size to be a multiple of pagesize */
|
||||
@ -161,24 +183,24 @@ static int memio_new(const char* path, int ioflags, off_t initialsize, void* mem
|
||||
|
||||
*((char**)&nciop->path) = strdup(path);
|
||||
if(nciop->path == NULL) {status = NC_ENOMEM; goto fail;}
|
||||
memio->alloc = initialsize;
|
||||
memio->pos = 0;
|
||||
memio->size = minsize;
|
||||
memio->memory = NULL;
|
||||
memio->persist = fIsSet(ioflags,NC_WRITE);
|
||||
|
||||
if(memiop && memio) *memiop = memio; else free(memio);
|
||||
if(nciopp && nciop) *nciopp = nciop;
|
||||
else {
|
||||
if(nciop->path != NULL) free((char*)nciop->path);
|
||||
free(nciop);
|
||||
}
|
||||
if(inmemory) {
|
||||
memio->memory = memory;
|
||||
} else {
|
||||
/* malloc memory */
|
||||
memio->memory = (char*)malloc((size_t)memio->alloc);
|
||||
if(memio->memory == NULL) {status = NC_ENOMEM; goto fail;}
|
||||
}
|
||||
memio->alloc = (size_t)initialsize;
|
||||
memio->pos = 0;
|
||||
memio->size = minsize;
|
||||
memio->memory = NULL; /* filled in by caller */
|
||||
|
||||
if(fIsSet(ioflags,NC_DISKLESS))
|
||||
memio->diskless = 1;
|
||||
if(fIsSet(ioflags,NC_INMEMORY) && !memio->diskless)
|
||||
memio->inmemory = 1;
|
||||
if(fIsSet(ioflags,NC_WRITE) && !fIsSet(ioflags,NC_NOCLOBBER) && memio->diskless)
|
||||
memio->persist = 1;
|
||||
|
||||
done:
|
||||
return status;
|
||||
@ -210,41 +232,31 @@ int
|
||||
memio_create(const char* path, int ioflags,
|
||||
size_t initialsz,
|
||||
off_t igeto, size_t igetsz, size_t* sizehintp,
|
||||
void* parameters,
|
||||
void* parameters /*ignored*/,
|
||||
ncio* *nciopp, void** const mempp)
|
||||
{
|
||||
ncio* nciop;
|
||||
int fd;
|
||||
int status;
|
||||
NCMEMIO* memio = NULL;
|
||||
int persist = (ioflags & NC_WRITE?1:0);
|
||||
int oflags;
|
||||
|
||||
if(path == NULL ||* path == 0)
|
||||
return NC_EINVAL;
|
||||
|
||||
status = memio_new(path, ioflags, (off_t)initialsz, NULL, &nciop, &memio);
|
||||
|
||||
status = memio_new(path, ioflags, initialsz, &nciop, &memio);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
|
||||
if(persist) {
|
||||
/* Open the file just tomake sure we can write it if needed */
|
||||
oflags = (persist ? O_RDWR : O_RDONLY);
|
||||
#ifdef O_BINARY
|
||||
fSet(oflags, O_BINARY);
|
||||
#endif
|
||||
oflags |= (O_CREAT|O_TRUNC);
|
||||
if(fIsSet(ioflags,NC_NOCLOBBER))
|
||||
oflags |= O_EXCL;
|
||||
#ifdef vms
|
||||
fd = open(path, oflags, 0, "ctx=stm");
|
||||
#else
|
||||
fd = open(path, oflags, OPENMODE);
|
||||
#endif
|
||||
if(fd < 0) {status = errno; goto unwind_open;}
|
||||
if(memio->persist) {
|
||||
/* Verify the file is writeable */
|
||||
if(!fileiswriteable(path))
|
||||
{status = EPERM; goto unwind_open;}
|
||||
}
|
||||
|
||||
(void)close(fd); /* will reopen at nc_close */
|
||||
} /*!persist*/
|
||||
/* Allocate the memory for this file */
|
||||
memio->memory = (char*)malloc((size_t)memio->alloc);
|
||||
if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;}
|
||||
memio->locked = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"memio_create: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc);
|
||||
@ -276,8 +288,7 @@ unwind_open:
|
||||
return status;
|
||||
}
|
||||
|
||||
/* This function opens the data file.
|
||||
|
||||
/* This function opens the data file or inmemory data
|
||||
path - path of data file.
|
||||
ioflags - flags passed into nc_open.
|
||||
igeto - looks like this function can do an initial page get, and
|
||||
@ -301,85 +312,75 @@ memio_open(const char* path,
|
||||
ncio* nciop = NULL;
|
||||
int fd = -1;
|
||||
int status = NC_NOERR;
|
||||
int persist = (fIsSet(ioflags,NC_WRITE)?1:0);
|
||||
int inmemory = (fIsSet(ioflags,NC_INMEMORY));
|
||||
int oflags = 0;
|
||||
NCMEMIO* memio = NULL;
|
||||
size_t sizehint = 0;
|
||||
off_t filesize = 0;
|
||||
off_t red = 0;
|
||||
char* pos = NULL;
|
||||
NC_MEM_INFO* meminfo = (NC_MEM_INFO*)parameters;
|
||||
NC_memio meminfo; /* use struct to avoid worrying about free'ing it */
|
||||
NCMEMIO* memio = NULL;
|
||||
size_t initialsize;
|
||||
/* Should be the case that diskless => inmemory but not converse */
|
||||
int diskless = (fIsSet(ioflags,NC_DISKLESS));
|
||||
int inmemory = (fIsSet(ioflags,NC_INMEMORY) && !diskless);
|
||||
int locked = 0;
|
||||
|
||||
if(path == NULL || strlen(path) == 0)
|
||||
return NC_EINVAL;
|
||||
|
||||
assert(sizehintp != NULL);
|
||||
|
||||
sizehint = *sizehintp;
|
||||
|
||||
if(inmemory) {
|
||||
filesize = (off_t)meminfo->size;
|
||||
} else {
|
||||
/* Open the file,and make sure we can write it if needed */
|
||||
oflags = (persist ? O_RDWR : O_RDONLY);
|
||||
#ifdef O_BINARY
|
||||
fSet(oflags, O_BINARY);
|
||||
#endif
|
||||
oflags |= O_EXCL;
|
||||
#ifdef vms
|
||||
fd = open(path, oflags, 0, "ctx=stm");
|
||||
#else
|
||||
fd = open(path, oflags, OPENMODE);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if(fd < 0) {
|
||||
fprintf(stderr,"open failed: file=%s err=",path);
|
||||
perror("");
|
||||
}
|
||||
#endif
|
||||
if(fd < 0) {status = errno; goto unwind_open;}
|
||||
|
||||
/* get current filesize = max(|file|,initialize)*/
|
||||
filesize = lseek(fd,0,SEEK_END);
|
||||
if(filesize < 0) {status = errno; goto unwind_open;}
|
||||
/* move pointer back to beginning of file */
|
||||
(void)lseek(fd,0,SEEK_SET);
|
||||
if(filesize < (off_t)sizehint)
|
||||
filesize = (off_t)sizehint;
|
||||
if(inmemory) { /* parameters provide the memory chunk */
|
||||
NC_memio* memparams = (NC_memio*)parameters;
|
||||
meminfo = *memparams;
|
||||
locked = fIsSet(meminfo.flags,NC_MEMIO_LOCKED);
|
||||
/* As a safeguard, if !locked and NC_WRITE is set,
|
||||
then we must take control of the incoming memory */
|
||||
if(!locked && fIsSet(ioflags,NC_WRITE)) {
|
||||
memparams->memory = NULL;
|
||||
}
|
||||
} else { /* read the file into a chunk of memory*/
|
||||
assert(diskless);
|
||||
status = readfile(path,&meminfo);
|
||||
if(status != NC_NOERR)
|
||||
{goto unwind_open;}
|
||||
}
|
||||
|
||||
if(inmemory)
|
||||
status = memio_new(path, ioflags, filesize, meminfo->memory, &nciop, &memio);
|
||||
else
|
||||
status = memio_new(path, ioflags, filesize, NULL, &nciop, &memio);
|
||||
if(status != NC_NOERR) {
|
||||
if(fd >= 0)
|
||||
close(fd);
|
||||
return status;
|
||||
/* Fix up initial size */
|
||||
initialsize = meminfo.size;
|
||||
|
||||
/* create the NCMEMIO structure */
|
||||
status = memio_new(path, ioflags, initialsize, &nciop, &memio);
|
||||
if(status != NC_NOERR)
|
||||
{goto unwind_open;}
|
||||
memio->locked = locked;
|
||||
|
||||
/* Initialize the memio memory */
|
||||
memio->memory = meminfo.memory;
|
||||
|
||||
/* memio_new may have modified the allocated size, in which case,
|
||||
reallocate the memory unless the memory is locked. */
|
||||
if(memio->alloc > meminfo.size) {
|
||||
if(memio->locked)
|
||||
memio->alloc = meminfo.size; /* force it back to what it was */
|
||||
else {
|
||||
void* oldmem = memio->memory;
|
||||
memio->memory = reallocx(oldmem,memio->alloc,meminfo.size);
|
||||
if(memio->memory == NULL)
|
||||
{status = NC_ENOMEM; goto unwind_open;}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"memio_open: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc);
|
||||
#endif
|
||||
|
||||
if(!inmemory) {
|
||||
/* Read the file into the memio memory */
|
||||
/* We need to do multiple reads because there is no
|
||||
guarantee that the amount read will be the full amount */
|
||||
red = memio->size;
|
||||
pos = memio->memory;
|
||||
while(red > 0) {
|
||||
ssize_t count = (ssize_t)read(fd, pos, (size_t)red);
|
||||
if(count < 0) {status = errno; goto unwind_open;}
|
||||
if(count == 0) {status = NC_ENOTNC; goto unwind_open;}
|
||||
red -= count;
|
||||
pos += count;
|
||||
}
|
||||
(void)close(fd);
|
||||
if(memio->persist) {
|
||||
/* Verify the file is writeable */
|
||||
if(!fileiswriteable(path))
|
||||
{status = EPERM; goto unwind_open;}
|
||||
}
|
||||
|
||||
/* Use half the filesize as the blocksize ; why? */
|
||||
sizehint = (size_t)filesize/2;
|
||||
sizehint = (size_t)(memio->alloc/2);
|
||||
|
||||
/* sizehint must be multiple of 8 */
|
||||
sizehint = (sizehint / 8) * 8;
|
||||
@ -433,26 +434,34 @@ static int
|
||||
memio_pad_length(ncio* nciop, off_t length)
|
||||
{
|
||||
NCMEMIO* memio;
|
||||
size_t len = (size_t)length;
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL;
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
|
||||
if(!fIsSet(nciop->ioflags, NC_WRITE))
|
||||
if(!memio->persist)
|
||||
return EPERM; /* attempt to write readonly file*/
|
||||
|
||||
if(memio->locked > 0)
|
||||
if(memio->locked)
|
||||
return NC_EDISKLESS;
|
||||
|
||||
if(length > memio->alloc) {
|
||||
if(len > memio->alloc) {
|
||||
/* Realloc the allocated memory to a multiple of the pagesize*/
|
||||
off_t newsize = length;
|
||||
size_t newsize = (size_t)len;
|
||||
void* newmem = NULL;
|
||||
/* Round to a multiple of pagesize */
|
||||
if((newsize % pagesize) != 0)
|
||||
newsize += (pagesize - (newsize % pagesize));
|
||||
|
||||
newmem = (char*)realloc(memio->memory,(size_t)newsize);
|
||||
newmem = (char*)reallocx(memio->memory,newsize,memio->alloc);
|
||||
if(newmem == NULL) return NC_ENOMEM;
|
||||
|
||||
/* If not copy is set, then fail if the newmem address is different
|
||||
from old address */
|
||||
if(newmem != memio->memory) {
|
||||
memio->modified++;
|
||||
if(memio->locked) {
|
||||
free(newmem);
|
||||
return NC_EINMEMORY;
|
||||
}
|
||||
}
|
||||
/* zero out the extra memory */
|
||||
memset((void*)((char*)newmem+memio->alloc),0,(size_t)(newsize - memio->alloc));
|
||||
|
||||
@ -461,10 +470,13 @@ fprintf(stderr,"realloc: %lu/%lu -> %lu/%lu\n",
|
||||
(unsigned long)memio->memory,(unsigned long)memio->alloc,
|
||||
(unsigned long)newmem,(unsigned long)newsize);
|
||||
#endif
|
||||
if(memio->memory != NULL && (!memio->locked || memio->modified))
|
||||
free(memio->memory);
|
||||
memio->memory = newmem;
|
||||
memio->alloc = newsize;
|
||||
memio->modified = 1;
|
||||
}
|
||||
memio->size = length;
|
||||
memio->size = len;
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
@ -482,46 +494,23 @@ memio_close(ncio* nciop, int doUnlink)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
NCMEMIO* memio ;
|
||||
int fd = -1;
|
||||
int inmemory = 0;
|
||||
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_NOERR;
|
||||
|
||||
inmemory = (fIsSet(nciop->ioflags,NC_INMEMORY));
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
assert(memio != NULL);
|
||||
|
||||
/* See if the user wants the contents persisted to a file */
|
||||
if(!inmemory && memio->persist) {
|
||||
/* Try to open the file for writing */
|
||||
int oflags = O_WRONLY|O_CREAT|O_TRUNC;
|
||||
#ifdef O_BINARY
|
||||
fSet(oflags, O_BINARY);
|
||||
#endif
|
||||
fd = open(nciop->path, oflags, OPENMODE);
|
||||
if(fd >= 0) {
|
||||
/* We need to do multiple writes because there is no
|
||||
guarantee that the amount written will be the full amount */
|
||||
off_t written = memio->size;
|
||||
char* pos = memio->memory;
|
||||
while(written > 0) {
|
||||
ssize_t count = (ssize_t)write(fd, pos, (size_t)written);
|
||||
if(count < 0)
|
||||
{status = errno; goto done;}
|
||||
if(count == 0)
|
||||
{status = NC_ENOTNC; goto done;}
|
||||
written -= count;
|
||||
pos += count;
|
||||
}
|
||||
} else
|
||||
status = errno;
|
||||
}
|
||||
if(memio->persist && memio->memory != NULL) {
|
||||
status = writefile(nciop->path,memio);
|
||||
}
|
||||
|
||||
done:
|
||||
if(!inmemory && memio->memory != NULL)
|
||||
/* We only free the memio memory if file is not locked or has been modified */
|
||||
if(memio->memory != NULL && (!memio->locked || memio->modified)) {
|
||||
free(memio->memory);
|
||||
memio->memory = NULL;
|
||||
}
|
||||
/* do cleanup */
|
||||
if(fd >= 0) (void)close(fd);
|
||||
if(memio != NULL) free(memio);
|
||||
if(nciop->path != NULL) free((char*)nciop->path);
|
||||
free(nciop);
|
||||
@ -529,9 +518,10 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
guarantee(ncio* nciop, off_t endpoint)
|
||||
guarantee(ncio* nciop, off_t endpoint0)
|
||||
{
|
||||
NCMEMIO* memio = (NCMEMIO*)nciop->pvt;
|
||||
size_t endpoint = (size_t)endpoint0;
|
||||
if(endpoint > memio->alloc) {
|
||||
/* extend the allocated memory and size */
|
||||
int status = memio_pad_length(nciop,endpoint);
|
||||
@ -633,3 +623,117 @@ memio_sync(ncio* const nciop)
|
||||
{
|
||||
return NC_NOERR; /* do nothing */
|
||||
}
|
||||
|
||||
/* "Hidden" Internal function to extract a copy of
|
||||
the size and/or contents of the memory
|
||||
*/
|
||||
int
|
||||
memio_extract(ncio* const nciop, size_t* sizep, void** memoryp)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
NCMEMIO* memio = NULL;
|
||||
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_NOERR;
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
assert(memio != NULL);
|
||||
if(sizep) *sizep = memio->size;
|
||||
|
||||
if(memoryp && memio->memory != NULL) {
|
||||
*memoryp = memio->memory;
|
||||
memio->memory = NULL; /* make sure it does not get free'd */
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
fileiswriteable(const char* path)
|
||||
{
|
||||
int ok;
|
||||
ok = access(path,O_RDWR);
|
||||
if(ok < 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read contents of a disk file into a memory chunk */
|
||||
static int
|
||||
readfile(const char* path, NC_memio* memio)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
FILE* f = NULL;
|
||||
size_t filesize = 0;
|
||||
size_t count = 0;
|
||||
char* memory = NULL;
|
||||
char* p = NULL;
|
||||
|
||||
/* Open the file for reading */
|
||||
#ifdef _MSC_VER
|
||||
f = NCfopen(path,"rb");
|
||||
#else
|
||||
f = NCfopen(path,"r");
|
||||
#endif
|
||||
if(f == NULL)
|
||||
{status = errno; goto done;}
|
||||
/* get current filesize */
|
||||
if(fseek(f,0,SEEK_END) < 0)
|
||||
{status = errno; goto done;}
|
||||
filesize = (size_t)ftell(f);
|
||||
/* allocate memory */
|
||||
memory = malloc((size_t)filesize);
|
||||
if(memory == NULL)
|
||||
{status = NC_ENOMEM; goto done;}
|
||||
/* move pointer back to beginning of file */
|
||||
rewind(f);
|
||||
count = filesize;
|
||||
p = memory;
|
||||
while(count > 0) {
|
||||
size_t actual;
|
||||
actual = fread(p,1,count,f);
|
||||
if(actual == 0 || ferror(f))
|
||||
{status = NC_EIO; goto done;}
|
||||
count -= actual;
|
||||
p += actual;
|
||||
}
|
||||
if(memio) {
|
||||
memio->size = (size_t)filesize;
|
||||
memio->memory = memory;
|
||||
}
|
||||
done:
|
||||
if(status != NC_NOERR && memory != NULL)
|
||||
free(memory);
|
||||
if(f != NULL) fclose(f);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* write contents of a memory chunk back into a disk file */
|
||||
static int
|
||||
writefile(const char* path, NCMEMIO* memio)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
FILE* f = NULL;
|
||||
size_t count = 0;
|
||||
char* p = NULL;
|
||||
|
||||
/* Open the file for writing*/
|
||||
#ifdef _MSC_VER
|
||||
f = NCfopen(path,"rwb");
|
||||
#else
|
||||
f = NCfopen(path,"rw");
|
||||
#endif
|
||||
if(f == NULL)
|
||||
{status = errno; goto done;}
|
||||
rewind(f);
|
||||
count = memio->size;
|
||||
p = memio->memory;
|
||||
while(count > 0) {
|
||||
size_t actual;
|
||||
actual = fwrite(p,1,count,f);
|
||||
if(actual == 0 || ferror(f))
|
||||
{status = NC_EIO; goto done;}
|
||||
count -= actual;
|
||||
p += actual;
|
||||
}
|
||||
done:
|
||||
if(f != NULL) fclose(f);
|
||||
return status;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#endif
|
||||
|
||||
#include "nc3internal.h"
|
||||
#include "netcdf_mem.h"
|
||||
#include "rnd.h"
|
||||
#include "ncx.h"
|
||||
|
||||
@ -35,6 +36,10 @@
|
||||
/* For cdf5 */
|
||||
#define NC_NUMRECS_EXTENT5 8
|
||||
|
||||
/* Internal function; breaks ncio abstraction */
|
||||
extern int memio_extract(ncio* const nciop, size_t* sizep, void** memoryp);
|
||||
|
||||
|
||||
static void
|
||||
free_NC3INFO(NC3_INFO *nc3)
|
||||
{
|
||||
@ -1317,7 +1322,7 @@ NC3_abort(int ncid)
|
||||
}
|
||||
|
||||
int
|
||||
NC3_close(int ncid)
|
||||
NC3_close(int ncid, void* params)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
NC *nc;
|
||||
@ -1365,6 +1370,12 @@ NC3_close(int ncid)
|
||||
}
|
||||
}
|
||||
|
||||
if(params != NULL && (nc->mode & NC_INMEMORY) != 0) {
|
||||
NC_memio* memio = (NC_memio*)params;
|
||||
/* Extract the final memory size &/or contents */
|
||||
status = memio_extract(nc3->nciop,&memio->size,&memio->memory);
|
||||
}
|
||||
|
||||
(void) ncio_close(nc3->nciop, 0);
|
||||
nc3->nciop = NULL;
|
||||
|
||||
@ -1771,19 +1782,14 @@ int
|
||||
nc_delete_mp(const char * path, int basepe)
|
||||
{
|
||||
NC *nc;
|
||||
NC3_INFO* nc3;
|
||||
int status;
|
||||
int ncid;
|
||||
size_t chunk = 512;
|
||||
|
||||
status = nc_open(path,NC_NOWRITE,&ncid);
|
||||
if(status) return status;
|
||||
|
||||
status = NC_check_id(ncid,&nc);
|
||||
if(status) return status;
|
||||
nc3 = NC3_DATA(nc);
|
||||
|
||||
nc3->chunk = chunk;
|
||||
|
||||
#if defined(LOCKNUMREC) /* && _CRAYMPP */
|
||||
if (status = NC_init_pe(nc3, basepe)) {
|
||||
|
@ -46,9 +46,9 @@ ncio_create(const char *path, int ioflags, size_t initialsz,
|
||||
ncio** iopp, void** const mempp)
|
||||
{
|
||||
#ifdef USE_DISKLESS
|
||||
if(fIsSet(ioflags,NC_DISKLESS)) {
|
||||
if(fIsSet(ioflags,NC_INMEMORY)) {
|
||||
# ifdef USE_MMAP
|
||||
if(fIsSet(ioflags,NC_MMAP))
|
||||
if(fIsSet(ioflags,NC_MMAP) && fIsSet(ioflags, NC_DISKLESS))
|
||||
return mmapio_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,parameters,iopp,mempp);
|
||||
else
|
||||
# endif /*USE_MMAP*/
|
||||
@ -72,12 +72,12 @@ ncio_open(const char *path, int ioflags,
|
||||
ncio** iopp, void** const mempp)
|
||||
{
|
||||
/* Diskless open has the following constraints:
|
||||
1. file must be classic version 1 or 2
|
||||
1. file must be classic version 1 or 2 or 5
|
||||
*/
|
||||
#ifdef USE_DISKLESS
|
||||
if(fIsSet(ioflags,NC_DISKLESS)) {
|
||||
if(fIsSet(ioflags,NC_INMEMORY)) {
|
||||
# ifdef USE_MMAP
|
||||
if(fIsSet(ioflags,NC_MMAP))
|
||||
if(fIsSet(ioflags,NC_MMAP) && fIsSet(ioflags, NC_DISKLESS))
|
||||
return mmapio_open(path,ioflags,igeto,igetsz,sizehintp,parameters,iopp,mempp);
|
||||
else
|
||||
# endif /*USE_MMAP*/
|
||||
|
@ -296,6 +296,9 @@ static const char nada[X_ALIGN] = {0, 0, 0, 0};
|
||||
(((a) & 0x00FF000000000000ULL) >> 40) | \
|
||||
(((a) & 0xFF00000000000000ULL) >> 56) )
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
inline static void
|
||||
swapn2b(void *dst, const void *src, IntType nn)
|
||||
|
@ -510,7 +510,7 @@ ncio_px_rel(ncio *const nciop, off_t offset, int rflags)
|
||||
* The blkextent can't be more than twice the pxp->blksz. That's
|
||||
because the pxp->blksize is the sizehint, and in ncio_px_init2 the
|
||||
buffer (pointed to by pxp->bf-base) is allocated with 2 *
|
||||
*sizehintp. This is checked (unneccesarily) more than once in
|
||||
*sizehintp. This is checked (unnecessarily) more than once in
|
||||
asserts.
|
||||
|
||||
* If this is called on a newly opened file, pxp->bf_offset will be
|
||||
@ -1722,7 +1722,7 @@ unwind_new:
|
||||
nciopp - pointer to pointer that will get address of newly created
|
||||
and inited ncio struct.
|
||||
|
||||
igetvpp - handle to pass back pointer to data from inital page
|
||||
igetvpp - handle to pass back pointer to data from initial page
|
||||
read, if this were ever used, which it isn't.
|
||||
*/
|
||||
int
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Process these files with m4.
|
||||
|
||||
SET(libsrc4_SOURCES nc4dispatch.c nc4attr.c nc4dim.c nc4file.c nc4grp.c nc4type.c nc4var.c ncfunc.c nc4internal.c nc4hdf.c nc4info.c ncindex.c)
|
||||
SET(libsrc4_SOURCES nc4dispatch.c nc4attr.c nc4dim.c nc4grp.c nc4type.c nc4var.c ncfunc.c nc4internal.c ncindex.c nc4mem.c nc4memcb.c )
|
||||
|
||||
IF(LOGGING)
|
||||
SET(libsrc4_SOURCES ${libsrc4_SOURCES} error4.c)
|
||||
@ -38,6 +38,3 @@ ENDIF(BUILD_DAP)
|
||||
IF (BUILD_PARALLEL)
|
||||
SET(ARGS_MANPAGE ${ARGS_MANPAGE} -DPARALLEL_IO=TRUE)
|
||||
ENDIF(BUILD_PARALLEL)
|
||||
|
||||
|
||||
|
||||
|
@ -10,9 +10,9 @@ libnetcdf4_la_CPPFLAGS = ${AM_CPPFLAGS}
|
||||
|
||||
# This is our output. The netCDF-4 convenience library.
|
||||
noinst_LTLIBRARIES = libnetcdf4.la
|
||||
libnetcdf4_la_SOURCES = nc4dispatch.c nc4attr.c nc4dim.c nc4file.c \
|
||||
nc4grp.c nc4hdf.c nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c \
|
||||
nc4info.c nc4printer.c ncindex.c
|
||||
libnetcdf4_la_SOURCES = nc4dispatch.c nc4attr.c nc4dim.c nc4grp.c \
|
||||
nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c nc4printer.c \
|
||||
ncindex.c nc4mem.c nc4memcb.c
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
||||
|
@ -432,7 +432,7 @@ nc4_find_g_var_nc(NC *nc, int ncid, int varid,
|
||||
* @param grp Pointer to group info struct.
|
||||
* @param dimid Dimension ID to find.
|
||||
* @param dim Pointer that gets pointer to dim info if found.
|
||||
* @param dim_grp Pointer that gets pointer to group info of group that contians dimension.
|
||||
* @param dim_grp Pointer that gets pointer to group info of group that contains dimension.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADDIM Dimension not found.
|
||||
@ -987,7 +987,7 @@ exit:
|
||||
|
||||
/**
|
||||
* @internal Add to the end of a group list. Can't use 0 as a
|
||||
* new_nc_grpid - it's reserverd for the root group.
|
||||
* new_nc_grpid - it's reserved for the root group.
|
||||
*
|
||||
* @param parent The parent group.
|
||||
* @param name Name of the group.
|
||||
@ -1828,11 +1828,11 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
|
||||
*
|
||||
* Sometimes, during renames, or late creation of variables, an
|
||||
* existing, dimscale-only dataset must be removed. This means
|
||||
* detatching all variables that use the dataset, then closing and
|
||||
* detaching all variables that use the dataset, then closing and
|
||||
* unlinking it.
|
||||
*
|
||||
* @param grp The grp of the dimscale-only dataset to be deleted, or a
|
||||
* higher group in the heirarchy (ex. root group).
|
||||
* higher group in the hierarchy (ex. root group).
|
||||
* @param dimid id of the dimension
|
||||
* @param dim Pointer to the dim with the dimscale-only dataset to be
|
||||
* deleted.
|
||||
@ -2031,7 +2031,7 @@ nc_set_log_level(int new_level)
|
||||
nc4_hdf5_initialize();
|
||||
|
||||
/* If the user wants to completely turn off logging, turn off HDF5
|
||||
logging too. Now I truely can't think of what to do if this
|
||||
logging too. Now I truly can't think of what to do if this
|
||||
fails, so just ignore the return code. */
|
||||
if (new_level == NC_TURN_OFF_LOGGING)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user