Merge branch 'master' into cleanncgen.dmh

This commit is contained in:
Ward Fisher 2018-05-16 14:31:11 -06:00 committed by GitHub
commit c9d1589c39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
145 changed files with 3270 additions and 1196 deletions

View File

@ -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

View File

@ -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.
##

View File

@ -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 \

View File

@ -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
View 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
View File

@ -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"

View File

@ -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
View 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
View 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:

View File

@ -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

View File

@ -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}")

View File

@ -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.

View File

@ -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.

View File

@ -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:

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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.

View File

@ -1316,7 +1316,7 @@ $ nc2text -f &#39;%0.1f&#39; 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>

View File

@ -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.)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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}")

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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. */

View 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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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. */

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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 */

View File

@ -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) {

View File

@ -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';

View File

@ -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);

View File

@ -341,7 +341,7 @@ NCD4_abort(int ncid)
}
/**************************************************/
/* Auxilliary routines */
/* Auxiliary routines */
/**************************************************/
static void

View File

@ -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);
}
/**************************************************/

View File

@ -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.
*/

View File

@ -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

View File

@ -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;

View File

@ -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.
*/

View File

@ -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*/

View File

@ -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);*/

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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, &params, &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;

View File

@ -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.

View File

@ -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(;;) {

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.

View 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.
*

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
View 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
View 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

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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);

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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*/

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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